summaryrefslogtreecommitdiff
path: root/framework/source
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source')
-rw-r--r--framework/source/accelerators/acceleratorcache.cxx247
-rw-r--r--framework/source/accelerators/acceleratorconfiguration.cxx1697
-rw-r--r--framework/source/accelerators/acceleratorexecute.cxx371
-rw-r--r--framework/source/accelerators/acceleratorexecute.hxx246
-rw-r--r--framework/source/accelerators/documentacceleratorconfiguration.cxx212
-rw-r--r--framework/source/accelerators/globalacceleratorconfiguration.cxx132
-rw-r--r--framework/source/accelerators/keymapping.cxx235
-rw-r--r--framework/source/accelerators/moduleacceleratorconfiguration.cxx166
-rw-r--r--framework/source/accelerators/presethandler.cxx924
-rw-r--r--framework/source/accelerators/storageholder.cxx624
-rw-r--r--framework/source/application/framework.cxx257
-rw-r--r--framework/source/application/login.cxx296
-rw-r--r--framework/source/classes/droptargetlistener.cxx256
-rw-r--r--framework/source/classes/framecontainer.cxx401
-rw-r--r--framework/source/classes/fwktabwindow.cxx412
-rw-r--r--framework/source/classes/fwlresid.cxx64
-rw-r--r--framework/source/classes/menumanager.cxx1055
-rw-r--r--framework/source/classes/resource.src360
-rw-r--r--framework/source/classes/taskcreator.cxx174
-rw-r--r--framework/source/constant/containerquery.cxx43
-rw-r--r--framework/source/constant/contenthandler.cxx43
-rw-r--r--framework/source/constant/frameloader.cxx43
-rw-r--r--framework/source/dispatch/closedispatcher.cxx655
-rw-r--r--framework/source/dispatch/dispatchinformationprovider.cxx193
-rw-r--r--framework/source/dispatch/dispatchprovider.cxx798
-rw-r--r--framework/source/dispatch/helpagentdispatcher.cxx446
-rw-r--r--framework/source/dispatch/interceptionhelper.cxx343
-rw-r--r--framework/source/dispatch/loaddispatcher.cxx201
-rw-r--r--framework/source/dispatch/mailtodispatcher.cxx333
-rw-r--r--framework/source/dispatch/menudispatcher.cxx480
-rw-r--r--framework/source/dispatch/oxt_handler.cxx272
-rw-r--r--framework/source/dispatch/popupmenudispatcher.cxx422
-rw-r--r--framework/source/dispatch/servicehandler.cxx354
-rw-r--r--framework/source/dispatch/startmoduledispatcher.cxx244
-rw-r--r--framework/source/dispatch/systemexec.cxx237
-rw-r--r--framework/source/dispatch/windowcommanddispatch.cxx211
-rw-r--r--framework/source/fwe/classes/actiontriggercontainer.cxx205
-rw-r--r--framework/source/fwe/classes/actiontriggerpropertyset.cxx482
-rw-r--r--framework/source/fwe/classes/actiontriggerseparatorpropertyset.cxx351
-rw-r--r--framework/source/fwe/classes/addonmenu.cxx458
-rw-r--r--framework/source/fwe/classes/addonsoptions.cxx1823
-rw-r--r--framework/source/fwe/classes/bmkmenu.cxx250
-rw-r--r--framework/source/fwe/classes/framelistanalyzer.cxx305
-rw-r--r--framework/source/fwe/classes/fwkresid.cxx64
-rw-r--r--framework/source/fwe/classes/imagewrapper.cxx122
-rw-r--r--framework/source/fwe/classes/menuextensionsupplier.cxx67
-rw-r--r--framework/source/fwe/classes/rootactiontriggercontainer.cxx381
-rw-r--r--framework/source/fwe/classes/sfxhelperfunctions.cxx182
-rw-r--r--framework/source/fwe/dispatch/interaction.cxx366
-rw-r--r--framework/source/fwe/helper/acceleratorinfo.cxx74
-rw-r--r--framework/source/fwe/helper/actiontriggerhelper.cxx405
-rw-r--r--framework/source/fwe/helper/configimporter.cxx96
-rw-r--r--framework/source/fwe/helper/documentundoguard.cxx271
-rw-r--r--framework/source/fwe/helper/imageproducer.cxx62
-rw-r--r--framework/source/fwe/helper/propertysetcontainer.cxx198
-rw-r--r--framework/source/fwe/helper/titlehelper.cxx730
-rw-r--r--framework/source/fwe/helper/undomanagerhelper.cxx1165
-rw-r--r--framework/source/fwe/interaction/preventduplicateinteraction.cxx297
-rw-r--r--framework/source/fwe/xml/eventsconfiguration.cxx157
-rw-r--r--framework/source/fwe/xml/eventsdocumenthandler.cxx553
-rw-r--r--framework/source/fwe/xml/imagesconfiguration.cxx227
-rw-r--r--framework/source/fwe/xml/imagesdocumenthandler.cxx851
-rw-r--r--framework/source/fwe/xml/menuconfiguration.cxx184
-rw-r--r--framework/source/fwe/xml/menudocumenthandler.cxx1005
-rw-r--r--framework/source/fwe/xml/saxnamespacefilter.cxx200
-rw-r--r--framework/source/fwe/xml/statusbarconfiguration.cxx166
-rw-r--r--framework/source/fwe/xml/statusbardocumenthandler.cxx698
-rw-r--r--framework/source/fwe/xml/toolboxconfiguration.cxx152
-rw-r--r--framework/source/fwe/xml/toolboxdocumenthandler.cxx880
-rw-r--r--framework/source/fwe/xml/toolboxlayoutdocumenthandler.cxx58
-rw-r--r--framework/source/fwe/xml/xmlnamespaces.cxx193
-rw-r--r--framework/source/fwi/classes/converter.cxx319
-rw-r--r--framework/source/fwi/classes/propertysethelper.cxx448
-rw-r--r--framework/source/fwi/classes/protocolhandlercache.cxx364
-rw-r--r--framework/source/fwi/helper/mischelper.cxx242
-rw-r--r--framework/source/fwi/helper/networkdomain.cxx298
-rw-r--r--framework/source/fwi/helper/shareablemutex.cxx84
-rw-r--r--framework/source/fwi/jobs/configaccess.cxx245
-rw-r--r--framework/source/fwi/jobs/jobconst.cxx77
-rw-r--r--framework/source/fwi/threadhelp/lockhelper.cxx553
-rw-r--r--framework/source/fwi/threadhelp/transactionmanager.cxx377
-rw-r--r--framework/source/fwi/uielement/constitemcontainer.cxx481
-rw-r--r--framework/source/fwi/uielement/itemcontainer.cxx268
-rw-r--r--framework/source/fwi/uielement/rootitemcontainer.cxx464
-rw-r--r--framework/source/helper/dockingareadefaultacceptor.cxx185
-rw-r--r--framework/source/helper/ocomponentaccess.cxx263
-rw-r--r--framework/source/helper/ocomponentenumeration.cxx238
-rw-r--r--framework/source/helper/oframes.cxx525
-rw-r--r--framework/source/helper/persistentwindowstate.cxx347
-rw-r--r--framework/source/helper/statusindicator.cxx155
-rw-r--r--framework/source/helper/statusindicatorfactory.cxx647
-rw-r--r--framework/source/helper/tagwindowasmodified.cxx253
-rw-r--r--framework/source/helper/titlebarupdate.cxx423
-rw-r--r--framework/source/helper/uiconfigelementwrapperbase.cxx569
-rw-r--r--framework/source/helper/uielementwrapperbase.cxx285
-rw-r--r--framework/source/helper/vclstatusindicator.cxx234
-rw-r--r--framework/source/helper/wakeupthread.cxx86
-rw-r--r--framework/source/inc/accelerators/acceleratorcache.hxx188
-rw-r--r--framework/source/inc/accelerators/acceleratorconfiguration.hxx479
-rw-r--r--framework/source/inc/accelerators/documentacceleratorconfiguration.hxx127
-rw-r--r--framework/source/inc/accelerators/globalacceleratorconfiguration.hxx111
-rw-r--r--framework/source/inc/accelerators/istoragelistener.hxx67
-rw-r--r--framework/source/inc/accelerators/keymapping.hxx165
-rw-r--r--framework/source/inc/accelerators/moduleacceleratorconfiguration.hxx118
-rw-r--r--framework/source/inc/accelerators/presethandler.hxx534
-rw-r--r--framework/source/inc/accelerators/storageholder.hxx260
-rw-r--r--framework/source/inc/constant/containerquery.hxx50
-rw-r--r--framework/source/inc/constant/contenthandler.hxx50
-rw-r--r--framework/source/inc/constant/frameloader.hxx50
-rw-r--r--framework/source/inc/dispatch/loaddispatcher.hxx164
-rw-r--r--framework/source/inc/dispatch/uieventloghelper.hxx85
-rw-r--r--framework/source/inc/dispatch/windowcommanddispatch.hxx171
-rw-r--r--framework/source/inc/loadenv/actionlockguard.hxx212
-rw-r--r--framework/source/inc/loadenv/loadenv.hxx703
-rw-r--r--framework/source/inc/loadenv/loadenvexception.hxx200
-rw-r--r--framework/source/inc/loadenv/targethelper.hxx127
-rw-r--r--framework/source/inc/pattern/configuration.hxx175
-rw-r--r--framework/source/inc/pattern/frame.hxx133
-rw-r--r--framework/source/inc/pattern/storages.hxx105
-rw-r--r--framework/source/inc/pattern/window.hxx155
-rw-r--r--framework/source/interaction/quietinteraction.cxx207
-rw-r--r--framework/source/jobs/helponstartup.cxx426
-rw-r--r--framework/source/jobs/job.cxx944
-rw-r--r--framework/source/jobs/jobdata.cxx751
-rw-r--r--framework/source/jobs/jobdispatch.cxx497
-rw-r--r--framework/source/jobs/jobexecutor.cxx388
-rw-r--r--framework/source/jobs/jobresult.cxx264
-rw-r--r--framework/source/jobs/joburl.cxx660
-rw-r--r--framework/source/jobs/shelljob.cxx217
-rw-r--r--framework/source/layoutmanager/helpers.cxx414
-rw-r--r--framework/source/layoutmanager/helpers.hxx95
-rw-r--r--framework/source/layoutmanager/layoutmanager.cxx3254
-rw-r--r--framework/source/layoutmanager/panel.cxx87
-rw-r--r--framework/source/layoutmanager/panel.hxx91
-rw-r--r--framework/source/layoutmanager/panelmanager.cxx183
-rw-r--r--framework/source/layoutmanager/panelmanager.hxx109
-rw-r--r--framework/source/layoutmanager/toolbarlayoutmanager.cxx4303
-rw-r--r--framework/source/layoutmanager/toolbarlayoutmanager.hxx344
-rw-r--r--framework/source/layoutmanager/uielement.cxx159
-rw-r--r--framework/source/loadenv/loadenv.cxx1809
-rw-r--r--framework/source/loadenv/targethelper.cxx110
-rw-r--r--framework/source/lomenubar/AwtKeyToDbusmenuString.cxx145
-rw-r--r--framework/source/lomenubar/AwtKeyToDbusmenuString.hxx33
-rw-r--r--framework/source/lomenubar/DesktopJob.cxx161
-rw-r--r--framework/source/lomenubar/DesktopJob.hxx90
-rw-r--r--framework/source/lomenubar/FrameHelper.cxx862
-rw-r--r--framework/source/lomenubar/FrameHelper.hxx154
-rw-r--r--framework/source/lomenubar/FrameJob.cxx397
-rw-r--r--framework/source/lomenubar/FrameJob.hxx101
-rw-r--r--framework/source/lomenubar/HACKING99
-rw-r--r--framework/source/lomenubar/Jobs.xcu34
-rw-r--r--framework/source/lomenubar/MenuItemInfo.cxx103
-rw-r--r--framework/source/lomenubar/MenuItemInfo.hxx54
-rw-r--r--framework/source/lomenubar/MenuItemStatusListener.cxx82
-rw-r--r--framework/source/lomenubar/MenuItemStatusListener.hxx35
-rw-r--r--framework/source/lomenubar/README15
-rw-r--r--framework/source/lomenubar/exports.cxx94
-rw-r--r--framework/source/recording/dispatchrecorder.cxx496
-rw-r--r--framework/source/recording/dispatchrecordersupplier.cxx224
-rw-r--r--framework/source/register/register3rdcomponents.cxx69
-rw-r--r--framework/source/register/registerlogindialog.cxx65
-rw-r--r--framework/source/register/registerservices.cxx137
-rw-r--r--framework/source/register/registertemp.cxx105
-rw-r--r--framework/source/services/autorecovery.cxx3642
-rw-r--r--framework/source/services/backingcomp.cxx868
-rw-r--r--framework/source/services/backingwindow.cxx1121
-rw-r--r--framework/source/services/backingwindow.hxx186
-rw-r--r--framework/source/services/desktop.cxx2036
-rw-r--r--framework/source/services/dispatchhelper.cxx229
-rw-r--r--framework/source/services/frame.cxx3305
-rw-r--r--framework/source/services/fwk_services.src135
-rw-r--r--framework/source/services/license.cxx603
-rw-r--r--framework/source/services/mediatypedetectionhelper.cxx112
-rw-r--r--framework/source/services/modelwinservice.cxx279
-rw-r--r--framework/source/services/modulemanager.cxx428
-rw-r--r--framework/source/services/pathsettings.cxx1183
-rw-r--r--framework/source/services/sessionlistener.cxx368
-rw-r--r--framework/source/services/substitutepathvars.cxx1265
-rw-r--r--framework/source/services/tabwindowservice.cxx488
-rw-r--r--framework/source/services/taskcreatorsrv.cxx403
-rw-r--r--framework/source/services/uriabbreviation.cxx92
-rw-r--r--framework/source/services/urltransformer.cxx374
-rw-r--r--framework/source/tabwin/tabwindow.cxx976
-rw-r--r--framework/source/tabwin/tabwinfactory.cxx178
-rw-r--r--framework/source/uiconfiguration/globalsettings.cxx358
-rw-r--r--framework/source/uiconfiguration/graphicnameaccess.cxx115
-rw-r--r--framework/source/uiconfiguration/imagemanager.cxx257
-rw-r--r--framework/source/uiconfiguration/imagemanagerimpl.cxx1460
-rw-r--r--framework/source/uiconfiguration/imagemanagerimpl.hxx225
-rw-r--r--framework/source/uiconfiguration/moduleimagemanager.cxx229
-rw-r--r--framework/source/uiconfiguration/moduleuicfgsupplier.cxx245
-rw-r--r--framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx1619
-rw-r--r--framework/source/uiconfiguration/uicategorydescription.cxx478
-rw-r--r--framework/source/uiconfiguration/uiconfigurationmanager.cxx1354
-rw-r--r--framework/source/uiconfiguration/uiconfigurationmanagerimpl.cxx1704
-rw-r--r--framework/source/uiconfiguration/uiconfigurationmanagerimpl.hxx221
-rw-r--r--framework/source/uiconfiguration/windowstateconfiguration.cxx1504
-rw-r--r--framework/source/uielement/addonstoolbarmanager.cxx540
-rw-r--r--framework/source/uielement/addonstoolbarwrapper.cxx194
-rw-r--r--framework/source/uielement/buttontoolbarcontroller.cxx335
-rw-r--r--framework/source/uielement/comboboxtoolbarcontroller.cxx445
-rw-r--r--framework/source/uielement/complextoolbarcontroller.cxx386
-rw-r--r--framework/source/uielement/controlmenucontroller.cxx436
-rw-r--r--framework/source/uielement/dropdownboxtoolbarcontroller.cxx349
-rw-r--r--framework/source/uielement/edittoolbarcontroller.cxx264
-rw-r--r--framework/source/uielement/fontmenucontroller.cxx259
-rw-r--r--framework/source/uielement/fontsizemenucontroller.cxx357
-rw-r--r--framework/source/uielement/footermenucontroller.cxx95
-rw-r--r--framework/source/uielement/generictoolbarcontroller.cxx389
-rw-r--r--framework/source/uielement/headermenucontroller.cxx273
-rw-r--r--framework/source/uielement/imagebuttontoolbarcontroller.cxx232
-rw-r--r--framework/source/uielement/langselectionmenucontroller.cxx371
-rw-r--r--framework/source/uielement/langselectionstatusbarcontroller.cxx429
-rw-r--r--framework/source/uielement/logoimagestatusbarcontroller.cxx178
-rw-r--r--framework/source/uielement/logotextstatusbarcontroller.cxx181
-rw-r--r--framework/source/uielement/macrosmenucontroller.cxx228
-rw-r--r--framework/source/uielement/menubarmanager.cxx2118
-rw-r--r--framework/source/uielement/menubarmerger.cxx451
-rw-r--r--framework/source/uielement/menubarwrapper.cxx379
-rw-r--r--framework/source/uielement/newmenucontroller.cxx579
-rw-r--r--framework/source/uielement/objectmenucontroller.cxx164
-rw-r--r--framework/source/uielement/panelwindow.cxx77
-rw-r--r--framework/source/uielement/panelwrapper.cxx226
-rw-r--r--framework/source/uielement/popupmenucontroller.cxx249
-rw-r--r--framework/source/uielement/progressbarwrapper.cxx366
-rw-r--r--framework/source/uielement/recentfilesmenucontroller.cxx521
-rw-r--r--framework/source/uielement/simpletextstatusbarcontroller.cxx197
-rw-r--r--framework/source/uielement/spinfieldtoolbarcontroller.cxx573
-rw-r--r--framework/source/uielement/statusbar.cxx116
-rw-r--r--framework/source/uielement/statusbarmanager.cxx713
-rw-r--r--framework/source/uielement/statusbarwrapper.cxx205
-rw-r--r--framework/source/uielement/statusindicatorinterfacewrapper.cxx132
-rw-r--r--framework/source/uielement/togglebuttontoolbarcontroller.cxx320
-rw-r--r--framework/source/uielement/toolbar.cxx80
-rw-r--r--framework/source/uielement/toolbarmanager.cxx2325
-rw-r--r--framework/source/uielement/toolbarmerger.cxx719
-rw-r--r--framework/source/uielement/toolbarsmenucontroller.cxx916
-rw-r--r--framework/source/uielement/toolbarwrapper.cxx351
-rw-r--r--framework/source/uielement/uicommanddescription.cxx808
-rw-r--r--framework/source/uifactory/addonstoolboxfactory.cxx220
-rw-r--r--framework/source/uifactory/factoryconfiguration.cxx347
-rw-r--r--framework/source/uifactory/menubarfactory.cxx210
-rw-r--r--framework/source/uifactory/popupmenucontrollerfactory.cxx94
-rw-r--r--framework/source/uifactory/statusbarcontrollerfactory.cxx92
-rw-r--r--framework/source/uifactory/statusbarfactory.cxx108
-rw-r--r--framework/source/uifactory/toolbarcontrollerfactory.cxx263
-rw-r--r--framework/source/uifactory/toolboxfactory.cxx104
-rw-r--r--framework/source/uifactory/uielementfactorymanager.cxx554
-rw-r--r--framework/source/uifactory/windowcontentfactorymanager.cxx242
-rwxr-xr-xframework/source/unotypes/fwk.xml457
-rwxr-xr-xframework/source/unotypes/fwl.xml95
-rwxr-xr-xframework/source/unotypes/lgd.xml32
-rw-r--r--framework/source/xml/acceleratorconfigurationreader.cxx339
-rw-r--r--framework/source/xml/acceleratorconfigurationwriter.cxx159
254 files changed, 108733 insertions, 0 deletions
diff --git a/framework/source/accelerators/acceleratorcache.cxx b/framework/source/accelerators/acceleratorcache.cxx
new file mode 100644
index 000000000000..4214e6e15092
--- /dev/null
+++ b/framework/source/accelerators/acceleratorcache.cxx
@@ -0,0 +1,247 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <accelerators/acceleratorcache.hxx>
+
+//_______________________________________________
+// own includes
+
+#include <xml/acceleratorconfigurationreader.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+//_______________________________________________
+// interface includes
+
+#include <com/sun/star/container/ElementExistException.hpp>
+
+#include <com/sun/star/container/NoSuchElementException.hpp>
+
+//_______________________________________________
+// other includes
+#include <vcl/svapp.hxx>
+
+namespace framework
+{
+
+//-----------------------------------------------
+AcceleratorCache::AcceleratorCache()
+ : ThreadHelpBase(&Application::GetSolarMutex())
+{
+}
+
+//-----------------------------------------------
+AcceleratorCache::AcceleratorCache(const AcceleratorCache& rCopy)
+ : ThreadHelpBase(&Application::GetSolarMutex())
+{
+ m_lCommand2Keys = rCopy.m_lCommand2Keys;
+ m_lKey2Commands = rCopy.m_lKey2Commands;
+}
+
+//-----------------------------------------------
+AcceleratorCache::~AcceleratorCache()
+{
+ // Dont save anything automaticly here.
+ // The user has to do that explicitly!
+}
+
+//-----------------------------------------------
+void AcceleratorCache::takeOver(const AcceleratorCache& rCopy)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ m_lCommand2Keys = rCopy.m_lCommand2Keys;
+ m_lKey2Commands = rCopy.m_lKey2Commands;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+AcceleratorCache& AcceleratorCache::operator=(const AcceleratorCache& rCopy)
+{
+ takeOver(rCopy);
+ return *this;
+}
+
+//-----------------------------------------------
+sal_Bool AcceleratorCache::hasKey(const css::awt::KeyEvent& aKey) const
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ return (m_lKey2Commands.find(aKey) != m_lKey2Commands.end());
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+sal_Bool AcceleratorCache::hasCommand(const ::rtl::OUString& sCommand) const
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ return (m_lCommand2Keys.find(sCommand) != m_lCommand2Keys.end());
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+AcceleratorCache::TKeyList AcceleratorCache::getAllKeys() const
+{
+ TKeyList lKeys;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ lKeys.reserve(m_lKey2Commands.size());
+
+ TKey2Commands::const_iterator pIt;
+ TKey2Commands::const_iterator pEnd = m_lKey2Commands.end();
+ for ( pIt = m_lKey2Commands.begin();
+ pIt != pEnd ;
+ ++pIt )
+ {
+ lKeys.push_back(pIt->first);
+ }
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return lKeys;
+}
+
+//-----------------------------------------------
+void AcceleratorCache::setKeyCommandPair(const css::awt::KeyEvent& aKey ,
+ const ::rtl::OUString& sCommand)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // register command for the specified key
+ m_lKey2Commands[aKey] = sCommand;
+
+ // update optimized structure to bind multiple keys to one command
+ TKeyList& rKeyList = m_lCommand2Keys[sCommand];
+ rKeyList.push_back(aKey);
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+AcceleratorCache::TKeyList AcceleratorCache::getKeysByCommand(const ::rtl::OUString& sCommand) const
+{
+ TKeyList lKeys;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ TCommand2Keys::const_iterator pCommand = m_lCommand2Keys.find(sCommand);
+ if (pCommand == m_lCommand2Keys.end())
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(), css::uno::Reference< css::uno::XInterface >());
+ lKeys = pCommand->second;
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return lKeys;
+}
+
+//-----------------------------------------------
+::rtl::OUString AcceleratorCache::getCommandByKey(const css::awt::KeyEvent& aKey) const
+{
+ ::rtl::OUString sCommand;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ TKey2Commands::const_iterator pKey = m_lKey2Commands.find(aKey);
+ if (pKey == m_lKey2Commands.end())
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(), css::uno::Reference< css::uno::XInterface >());
+ sCommand = pKey->second;
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return sCommand;
+}
+
+//-----------------------------------------------
+void AcceleratorCache::removeKey(const css::awt::KeyEvent& aKey)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // check if key exists
+ TKey2Commands::const_iterator pKey = m_lKey2Commands.find(aKey);
+ if (pKey == m_lKey2Commands.end())
+ return;
+
+ // get its registered command
+ // Because we must know its place inside the optimized
+ // structure, which bind keys to commands, too!
+ ::rtl::OUString sCommand = pKey->second;
+ pKey = m_lKey2Commands.end(); // nobody should use an undefined value .-)
+
+ // remove key from primary list
+ m_lKey2Commands.erase(aKey);
+
+ // remove key from optimized command list
+ m_lCommand2Keys.erase(sCommand);
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void AcceleratorCache::removeCommand(const ::rtl::OUString& sCommand)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ const TKeyList& lKeys = getKeysByCommand(sCommand);
+ AcceleratorCache::TKeyList::const_iterator pKey ;
+ for ( pKey = lKeys.begin();
+ pKey != lKeys.end() ;
+ ++pKey )
+ {
+ const css::awt::KeyEvent& rKey = *pKey;
+ removeKey(rKey);
+ }
+ m_lCommand2Keys.erase(sCommand);
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/accelerators/acceleratorconfiguration.cxx b/framework/source/accelerators/acceleratorconfiguration.cxx
new file mode 100644
index 000000000000..d2f958be8838
--- /dev/null
+++ b/framework/source/accelerators/acceleratorconfiguration.cxx
@@ -0,0 +1,1697 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <accelerators/acceleratorconfiguration.hxx>
+
+//_______________________________________________
+// own includes
+#include <pattern/configuration.hxx>
+#include <accelerators/presethandler.hxx>
+
+#include <xml/saxnamespacefilter.hxx>
+#include <xml/acceleratorconfigurationreader.hxx>
+#include <xml/acceleratorconfigurationwriter.hxx>
+
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+#include <acceleratorconst.h>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+//_______________________________________________
+// other includes
+#include <vcl/svapp.hxx>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+#include <comphelper/configurationhelper.hxx>
+#include <unotools/configpathes.hxx>
+#include <rtl/logfile.hxx>
+#include <svtools/acceleratorexecute.hxx>
+#include <stdio.h>
+
+//_______________________________________________
+// const
+
+namespace framework
+{
+ const ::rtl::OUString CFG_ENTRY_PRIMARY(RTL_CONSTASCII_USTRINGPARAM("PrimaryKeys"));
+ const ::rtl::OUString CFG_ENTRY_SECONDARY(RTL_CONSTASCII_USTRINGPARAM("SecondaryKeys"));
+ const ::rtl::OUString CFG_ENTRY_GLOBAL(RTL_CONSTASCII_USTRINGPARAM("Global"));
+ const ::rtl::OUString CFG_ENTRY_MODULES(RTL_CONSTASCII_USTRINGPARAM("Modules"));
+ const ::rtl::OUString CFG_PROP_COMMAND(RTL_CONSTASCII_USTRINGPARAM("Command"));
+
+
+#ifdef fpc
+ #error "Who exports this define? I use it as namespace alias ..."
+#else
+ namespace fpc = ::framework::pattern::configuration;
+#endif
+
+ ::rtl::OUString lcl_getKeyString(salhelper::SingletonRef<framework::KeyMapping>& _rKeyMapping, const css::awt::KeyEvent& aKeyEvent)
+ {
+ const sal_Int32 nBeginIndex = 4; // "KEY_" is the prefix of a identifier...
+ ::rtl::OUStringBuffer sKeyBuffer((_rKeyMapping->mapCodeToIdentifier(aKeyEvent.KeyCode)).copy(nBeginIndex));
+
+ if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT )
+ sKeyBuffer.appendAscii("_SHIFT");
+ if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 )
+ sKeyBuffer.appendAscii("_MOD1");
+ if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 )
+ sKeyBuffer.appendAscii("_MOD2");
+ if ( (aKeyEvent.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 )
+ sKeyBuffer.appendAscii("_MOD3");
+
+ return sKeyBuffer.makeStringAndClear();
+ }
+
+//-----------------------------------------------
+// XInterface, XTypeProvider
+DEFINE_XINTERFACE_6(XMLBasedAcceleratorConfiguration ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::ui::XAcceleratorConfiguration ),
+ DIRECT_INTERFACE(css::form::XReset ),
+ DIRECT_INTERFACE(css::ui::XUIConfigurationPersistence),
+ DIRECT_INTERFACE(css::ui::XUIConfigurationStorage ),
+ DIRECT_INTERFACE(css::ui::XUIConfiguration ))
+
+DEFINE_XTYPEPROVIDER_6(XMLBasedAcceleratorConfiguration ,
+ css::lang::XTypeProvider ,
+ css::ui::XAcceleratorConfiguration ,
+ css::form::XReset ,
+ css::ui::XUIConfigurationPersistence,
+ css::ui::XUIConfigurationStorage ,
+ css::ui::XUIConfiguration )
+
+//-----------------------------------------------
+XMLBasedAcceleratorConfiguration::XMLBasedAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , m_xSMGR (xSMGR )
+ , m_aPresetHandler(xSMGR )
+ , m_pWriteCache (0 )
+{
+}
+
+//-----------------------------------------------
+XMLBasedAcceleratorConfiguration::~XMLBasedAcceleratorConfiguration()
+{
+ LOG_ASSERT(!m_pWriteCache, "XMLBasedAcceleratorConfiguration::~XMLBasedAcceleratorConfiguration()\nChanges not flushed. Ignore it ...")
+}
+
+//-----------------------------------------------
+css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XMLBasedAcceleratorConfiguration::getAllKeyEvents()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ AcceleratorCache& rCache = impl_getCFG();
+ AcceleratorCache::TKeyList lKeys = rCache.getAllKeys();
+ return lKeys.getAsConstList();
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+::rtl::OUString SAL_CALL XMLBasedAcceleratorConfiguration::getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent)
+ throw(css::container::NoSuchElementException,
+ css::uno::RuntimeException )
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ AcceleratorCache& rCache = impl_getCFG();
+ if (!rCache.hasKey(aKeyEvent))
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(),
+ static_cast< ::cppu::OWeakObject* >(this));
+ return rCache.getCommandByKey(aKeyEvent);
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
+ const ::rtl::OUString& sCommand )
+ throw(css::lang::IllegalArgumentException,
+ css::uno::RuntimeException )
+{
+ if (
+ (aKeyEvent.KeyCode == 0) &&
+ (aKeyEvent.KeyChar == 0) &&
+ (aKeyEvent.KeyFunc == 0) &&
+ (aKeyEvent.Modifiers == 0)
+ )
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Such key event seams not to be supported by any operating system.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 0);
+
+ if (!sCommand.getLength())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty command strings are not allowed here.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AcceleratorCache& rCache = impl_getCFG(sal_True); // sal_True => force getting of a writeable cache!
+ rCache.setKeyCommandPair(aKeyEvent, sCommand);
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::removeKeyEvent(const css::awt::KeyEvent& aKeyEvent)
+throw(css::container::NoSuchElementException,
+ css::uno::RuntimeException )
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AcceleratorCache& rCache = impl_getCFG(sal_True); // true => force using of a writeable cache
+ if (!rCache.hasKey(aKeyEvent))
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(),
+ static_cast< ::cppu::OWeakObject* >(this));
+ rCache.removeKey(aKeyEvent);
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XMLBasedAcceleratorConfiguration::getKeyEventsByCommand(const ::rtl::OUString& sCommand)
+ throw(css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::uno::RuntimeException )
+{
+ if (!sCommand.getLength())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty command strings are not allowed here.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ AcceleratorCache& rCache = impl_getCFG();
+ if (!rCache.hasCommand(sCommand))
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ AcceleratorCache::TKeyList lKeys = rCache.getKeysByCommand(sCommand);
+ return lKeys.getAsConstList();
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Sequence< css::uno::Any > SAL_CALL XMLBasedAcceleratorConfiguration::getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList)
+ throw(css::lang::IllegalArgumentException ,
+ css::uno::RuntimeException )
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ sal_Int32 i = 0;
+ sal_Int32 c = lCommandList.getLength();
+ css::uno::Sequence< css::uno::Any > lPreferredOnes (c); // dont pack list!
+ AcceleratorCache& rCache = impl_getCFG();
+
+ for (i=0; i<c; ++i)
+ {
+ const ::rtl::OUString& rCommand = lCommandList[i];
+ if (!rCommand.getLength())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty command strings are not allowed here.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ (sal_Int16)i);
+
+ if (!rCache.hasCommand(rCommand))
+ continue;
+
+ AcceleratorCache::TKeyList lKeys = rCache.getKeysByCommand(rCommand);
+ if ( lKeys.empty() )
+ continue;
+
+ css::uno::Any& rAny = lPreferredOnes[i];
+ rAny <<= *(lKeys.begin());
+ }
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return lPreferredOnes;
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand)
+ throw(css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::uno::RuntimeException )
+{
+ if (!sCommand.getLength())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty command strings are not allowed here.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 0);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AcceleratorCache& rCache = impl_getCFG(sal_True); // sal_True => force getting of a writeable cache!
+ if (!rCache.hasCommand(sCommand))
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Command does not exists inside this container.")),
+ static_cast< ::cppu::OWeakObject* >(this));
+ rCache.removeCommand(sCommand);
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::reload()
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ css::uno::Reference< css::io::XStream > xStreamNoLang;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::io::XStream > xStream = m_aPresetHandler.openTarget(PresetHandler::TARGET_CURRENT(), sal_True); // sal_True => open or create!
+ try
+ {
+ xStreamNoLang = m_aPresetHandler.openPreset(PresetHandler::PRESET_DEFAULT(), sal_True);
+ }
+ catch(const css::io::IOException&) {} // does not have to exist
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::io::XInputStream > xIn;
+ if (xStream.is())
+ xIn = xStream->getInputStream();
+ if (!xIn.is())
+ throw css::io::IOException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Could not open accelerator configuration for reading.")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ // impl_ts_load() does not clear the cache
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_aReadCache = AcceleratorCache();
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ impl_ts_load(xIn);
+
+ // Load also the general language independent default accelerators
+ // (ignoring the already defined accelerators)
+ if (xStreamNoLang.is())
+ {
+ xIn = xStreamNoLang->getInputStream();
+ if (xIn.is())
+ impl_ts_load(xIn);
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::store()
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::io::XStream > xStream = m_aPresetHandler.openTarget(PresetHandler::TARGET_CURRENT(), sal_True); // sal_True => open or create!
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::io::XOutputStream > xOut;
+ if (xStream.is())
+ xOut = xStream->getOutputStream();
+
+ if (!xOut.is())
+ throw css::io::IOException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Could not open accelerator configuration for saving.")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ impl_ts_save(xOut);
+
+ xOut.clear();
+ xStream.clear();
+
+ m_aPresetHandler.commitUserChanges();
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ css::uno::Reference< css::io::XStream > xStream = StorageHolder::openSubStreamWithFallback(
+ xStorage,
+ PresetHandler::TARGET_CURRENT(),
+ css::embed::ElementModes::READWRITE,
+ sal_False); // False => no fallback from read/write to readonly!
+ css::uno::Reference< css::io::XOutputStream > xOut;
+ if (xStream.is())
+ xOut = xStream->getOutputStream();
+
+ if (!xOut.is())
+ throw css::io::IOException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Could not open accelerator configuration for saving.")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ impl_ts_save(xOut);
+
+ // TODO inform listener about success, so it can flush the root and sub storage of this stream!
+}
+
+//-----------------------------------------------
+::sal_Bool SAL_CALL XMLBasedAcceleratorConfiguration::isModified()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ return (m_pWriteCache != 0);
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+::sal_Bool SAL_CALL XMLBasedAcceleratorConfiguration::isReadOnly()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::io::XStream > xStream = m_aPresetHandler.openTarget(PresetHandler::TARGET_CURRENT(), sal_True); // sal_True => open or create!
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::io::XOutputStream > xOut;
+ if (xStream.is())
+ xOut = xStream->getOutputStream();
+ return !(xOut.is());
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& /*xStorage*/)
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XMLBasedAcceleratorConfiguration::setStorage()", "TODO implement this HACK .-)")
+}
+
+//-----------------------------------------------
+::sal_Bool SAL_CALL XMLBasedAcceleratorConfiguration::hasStorage()
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XMLBasedAcceleratorConfiguration::hasStorage()", "TODO implement this HACK .-)")
+ return sal_False;
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/)
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XMLBasedAcceleratorConfiguration::addConfigurationListener()", "TODO implement me")
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/)
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XMLBasedAcceleratorConfiguration::removeConfigurationListener()", "TODO implement me")
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::reset()
+throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_aPresetHandler.copyPresetToTarget(PresetHandler::PRESET_DEFAULT(), PresetHandler::TARGET_CURRENT());
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ reload();
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::addResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/)
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XMLBasedAcceleratorConfiguration::addResetListener()", "TODO implement me")
+}
+
+//-----------------------------------------------
+void SAL_CALL XMLBasedAcceleratorConfiguration::removeResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/)
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XMLBasedAcceleratorConfiguration::removeResetListener()", "TODO implement me")
+}
+
+//-----------------------------------------------
+// IStorageListener
+void XMLBasedAcceleratorConfiguration::changesOccurred(const ::rtl::OUString& /*sPath*/)
+{
+ reload();
+}
+
+//-----------------------------------------------
+void XMLBasedAcceleratorConfiguration::impl_ts_load(const css::uno::Reference< css::io::XInputStream >& xStream)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ if (m_pWriteCache)
+ {
+ // be aware of reentrance problems - use temp variable for calling delete ... :-)
+ AcceleratorCache* pTemp = m_pWriteCache;
+ m_pWriteCache = 0;
+ delete pTemp;
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::io::XSeekable > xSeek(xStream, css::uno::UNO_QUERY);
+ if (xSeek.is())
+ xSeek->seek(0);
+
+ // add accelerators to the cache (the cache is not cleared)
+ // SAFE -> ----------------------------------
+ aWriteLock.lock();
+
+ // create the parser queue
+ // Note: Use special filter object between parser and reader
+ // to get filtered xml with right namespaces ...
+ // Use further a temp cache for reading!
+ AcceleratorConfigurationReader* pReader = new AcceleratorConfigurationReader(m_aReadCache);
+ css::uno::Reference< css::xml::sax::XDocumentHandler > xReader (static_cast< ::cppu::OWeakObject* >(pReader), css::uno::UNO_QUERY_THROW);
+ SaxNamespaceFilter* pFilter = new SaxNamespaceFilter(xReader);
+ css::uno::Reference< css::xml::sax::XDocumentHandler > xFilter (static_cast< ::cppu::OWeakObject* >(pFilter), css::uno::UNO_QUERY_THROW);
+
+ // connect parser, filter and stream
+ css::uno::Reference< css::xml::sax::XParser > xParser(xSMGR->createInstance(SERVICENAME_SAXPARSER), css::uno::UNO_QUERY_THROW);
+ xParser->setDocumentHandler(xFilter);
+
+ css::xml::sax::InputSource aSource;
+ aSource.aInputStream = xStream;
+
+ // TODO think about error handling
+ xParser->parseStream(aSource);
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void XMLBasedAcceleratorConfiguration::impl_ts_save(const css::uno::Reference< css::io::XOutputStream >& xStream)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ AcceleratorCache aCache;
+ sal_Bool bChanged = (m_pWriteCache != 0);
+ if (bChanged)
+ aCache.takeOver(*m_pWriteCache);
+ else
+ aCache.takeOver(m_aReadCache);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::io::XTruncate > xClearable(xStream, css::uno::UNO_QUERY_THROW);
+ xClearable->truncate();
+
+ // TODO can be removed if seek(0) is done by truncate() automaticly!
+ css::uno::Reference< css::io::XSeekable > xSeek(xStream, css::uno::UNO_QUERY);
+ if (xSeek.is())
+ xSeek->seek(0);
+
+ // combine writer/cache/stream etcpp.
+ css::uno::Reference< css::xml::sax::XDocumentHandler > xWriter (xSMGR->createInstance(SERVICENAME_SAXWRITER), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::io::XActiveDataSource> xDataSource(xWriter , css::uno::UNO_QUERY_THROW);
+ xDataSource->setOutputStream(xStream);
+
+ // write into the stream
+ AcceleratorConfigurationWriter aWriter(aCache, xWriter);
+ aWriter.flush();
+
+ // take over all changes into the original container
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // take over all changes into the readonly cache ...
+ // and forget the copy-on-write copied cache
+ if (bChanged)
+ {
+ m_aReadCache.takeOver(*m_pWriteCache);
+ // live with reentrance .-)
+ AcceleratorCache* pTemp = m_pWriteCache;
+ m_pWriteCache = 0;
+ delete pTemp;
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+AcceleratorCache& XMLBasedAcceleratorConfiguration::impl_getCFG(sal_Bool bWriteAccessRequested)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ //create copy of our readonly-cache, if write access is forced ... but
+ //not still possible!
+ if (
+ (bWriteAccessRequested) &&
+ (!m_pWriteCache )
+ )
+ {
+ m_pWriteCache = new AcceleratorCache(m_aReadCache);
+ }
+
+ // in case, we have a writeable cache, we use it for reading too!
+ // Otherwhise the API user cant find its own changes ...
+ if (m_pWriteCache)
+ return *m_pWriteCache;
+ else
+ return m_aReadCache;
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+::comphelper::Locale XMLBasedAcceleratorConfiguration::impl_ts_getLocale() const
+{
+ static ::rtl::OUString LOCALE_PACKAGE(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Setup"));
+ static ::rtl::OUString LOCALE_PATH(RTL_CONSTASCII_USTRINGPARAM("L10N"));
+ static ::rtl::OUString LOCALE_KEY(RTL_CONSTASCII_USTRINGPARAM("ooLocale"));
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::uno::XInterface > xCFG = fpc::ConfigurationHelper::openConfig(xSMGR, LOCALE_PACKAGE, LOCALE_PATH, fpc::ConfigurationHelper::E_READONLY);
+ css::uno::Reference< css::beans::XPropertySet > xProp (xCFG, css::uno::UNO_QUERY_THROW);
+ ::rtl::OUString sISOLocale;
+ xProp->getPropertyValue(LOCALE_KEY) >>= sISOLocale;
+
+ if (!sISOLocale.getLength())
+ return ::comphelper::Locale::EN_US();
+ return ::comphelper::Locale(sISOLocale);
+}
+
+/*******************************************************************************
+*
+* XCU based accelerator configuration
+*
+*******************************************************************************/
+
+//-----------------------------------------------
+// XInterface, XTypeProvider
+DEFINE_XINTERFACE_7(XCUBasedAcceleratorConfiguration ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::ui::XAcceleratorConfiguration ),
+ DIRECT_INTERFACE(css::util::XChangesListener ),
+ DIRECT_INTERFACE(css::form::XReset ),
+ DIRECT_INTERFACE(css::ui::XUIConfigurationPersistence),
+ DIRECT_INTERFACE(css::ui::XUIConfigurationStorage ),
+ DIRECT_INTERFACE(css::ui::XUIConfiguration ))
+
+ DEFINE_XTYPEPROVIDER_7(XCUBasedAcceleratorConfiguration ,
+ css::lang::XTypeProvider ,
+ css::ui::XAcceleratorConfiguration ,
+ css::util::XChangesListener ,
+ css::form::XReset ,
+ css::ui::XUIConfigurationPersistence,
+ css::ui::XUIConfigurationStorage ,
+ css::ui::XUIConfiguration )
+
+//-----------------------------------------------
+XCUBasedAcceleratorConfiguration::XCUBasedAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , m_xSMGR (xSMGR )
+ , m_pPrimaryWriteCache(0 )
+ , m_pSecondaryWriteCache(0 )
+{
+ const ::rtl::OUString CFG_ENTRY_ACCELERATORS(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Accelerators"));
+ m_xCfg = css::uno::Reference< css::container::XNameAccess > (
+ ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_ACCELERATORS, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ),
+ css::uno::UNO_QUERY );
+}
+
+//-----------------------------------------------
+XCUBasedAcceleratorConfiguration::~XCUBasedAcceleratorConfiguration()
+{
+}
+
+//-----------------------------------------------
+css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XCUBasedAcceleratorConfiguration::getAllKeyEvents()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ AcceleratorCache::TKeyList lKeys = impl_getCFG(sal_True).getAllKeys(); //get keys from PrimaryKeys set
+
+ AcceleratorCache::TKeyList lSecondaryKeys = impl_getCFG(sal_False).getAllKeys(); //get keys from SecondaryKeys set
+ lKeys.reserve(lKeys.size()+lSecondaryKeys.size());
+ AcceleratorCache::TKeyList::const_iterator pIt;
+ AcceleratorCache::TKeyList::const_iterator pEnd = lSecondaryKeys.end();
+ for ( pIt = lSecondaryKeys.begin(); pIt != pEnd; ++pIt )
+ lKeys.push_back(*pIt);
+
+ return lKeys.getAsConstList();
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+::rtl::OUString SAL_CALL XCUBasedAcceleratorConfiguration::getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent)
+ throw(css::container::NoSuchElementException,
+ css::uno::RuntimeException )
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True );
+ AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False);
+
+ if (!rPrimaryCache.hasKey(aKeyEvent) && !rSecondaryCache.hasKey(aKeyEvent))
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ if (rPrimaryCache.hasKey(aKeyEvent))
+ return rPrimaryCache.getCommandByKey(aKeyEvent);
+ else
+ return rSecondaryCache.getCommandByKey(aKeyEvent);
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
+ const ::rtl::OUString& sCommand )
+ throw(css::lang::IllegalArgumentException,
+ css::uno::RuntimeException )
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::setKeyEvent" );
+
+ if (
+ (aKeyEvent.KeyCode == 0) &&
+ (aKeyEvent.KeyChar == 0) &&
+ (aKeyEvent.KeyFunc == 0) &&
+ (aKeyEvent.Modifiers == 0)
+ )
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Such key event seams not to be supported by any operating system.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 0);
+
+ if (!sCommand.getLength())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty command strings are not allowed here.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True ); // sal_True => force getting of a writeable cache!
+ AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True); // sal_True => force getting of a writeable cache!
+
+ if ( rPrimaryCache.hasKey(aKeyEvent) )
+ {
+ ::rtl::OUString sOriginalCommand = rPrimaryCache.getCommandByKey(aKeyEvent);
+ if ( sCommand != sOriginalCommand )
+ {
+ if (rSecondaryCache.hasCommand(sOriginalCommand))
+ {
+ AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sOriginalCommand);
+ rSecondaryCache.removeKey(lSecondaryKeys[0]);
+ rPrimaryCache.setKeyCommandPair(lSecondaryKeys[0], sOriginalCommand);
+ }
+
+ if (rPrimaryCache.hasCommand(sCommand))
+ {
+ AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand);
+ rPrimaryCache.removeKey(lPrimaryKeys[0]);
+ rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand);
+ }
+
+ rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand);
+ }
+ }
+
+ else if ( rSecondaryCache.hasKey(aKeyEvent) )
+ {
+ ::rtl::OUString sOriginalCommand = rSecondaryCache.getCommandByKey(aKeyEvent);
+ if (sCommand != sOriginalCommand)
+ {
+ if (rPrimaryCache.hasCommand(sCommand))
+ {
+ AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand);
+ rPrimaryCache.removeKey(lPrimaryKeys[0]);
+ rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand);
+ }
+
+ rSecondaryCache.removeKey(aKeyEvent);
+ rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand);
+ }
+ }
+
+ else
+ {
+ if (rPrimaryCache.hasCommand(sCommand))
+ {
+ AcceleratorCache::TKeyList lPrimaryKeys = rPrimaryCache.getKeysByCommand(sCommand);
+ rPrimaryCache.removeKey(lPrimaryKeys[0]);
+ rSecondaryCache.setKeyCommandPair(lPrimaryKeys[0], sCommand);
+ }
+
+ rPrimaryCache.setKeyCommandPair(aKeyEvent, sCommand);
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::removeKeyEvent(const css::awt::KeyEvent& aKeyEvent)
+ throw(css::container::NoSuchElementException,
+ css::uno::RuntimeException )
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True );
+ AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True);
+
+ if (!rPrimaryCache.hasKey(aKeyEvent) && !rSecondaryCache.hasKey(aKeyEvent))
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ if (rPrimaryCache.hasKey(aKeyEvent))
+ {
+ ::rtl::OUString sDelCommand = rPrimaryCache.getCommandByKey(aKeyEvent);
+ if (sDelCommand.getLength() > 0)
+ {
+ ::rtl::OUString sOriginalCommand = rPrimaryCache.getCommandByKey(aKeyEvent);
+ if (rSecondaryCache.hasCommand(sOriginalCommand))
+ {
+ AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sOriginalCommand);
+ rSecondaryCache.removeKey(lSecondaryKeys[0]);
+ rPrimaryCache.setKeyCommandPair(lSecondaryKeys[0], sOriginalCommand);
+ }
+
+ rPrimaryCache.removeKey(aKeyEvent);
+ }
+
+ }
+ else
+ {
+ ::rtl::OUString sDelCommand = rSecondaryCache.getCommandByKey(aKeyEvent);
+ if (sDelCommand.getLength() > 0)
+ rSecondaryCache.removeKey(aKeyEvent);
+ }
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Sequence< css::awt::KeyEvent > SAL_CALL XCUBasedAcceleratorConfiguration::getKeyEventsByCommand(const ::rtl::OUString& sCommand)
+ throw(css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::uno::RuntimeException )
+{
+ if (!sCommand.getLength())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty command strings are not allowed here.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True );
+ AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False);
+
+ if (!rPrimaryCache.hasCommand(sCommand) && !rSecondaryCache.hasCommand(sCommand))
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ AcceleratorCache::TKeyList lKeys = rPrimaryCache.getKeysByCommand(sCommand);
+
+ AcceleratorCache::TKeyList lSecondaryKeys = rSecondaryCache.getKeysByCommand(sCommand);
+ AcceleratorCache::TKeyList::const_iterator pIt;
+ for (pIt = lSecondaryKeys.begin(); pIt != lSecondaryKeys.end(); ++pIt)
+ lKeys.push_back(*pIt);
+
+ return lKeys.getAsConstList();
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+AcceleratorCache::TKeyList::const_iterator lcl_getPreferredKey(const AcceleratorCache::TKeyList& lKeys)
+{
+ AcceleratorCache::TKeyList::const_iterator pIt;
+ for ( pIt = lKeys.begin ();
+ pIt != lKeys.end ();
+ ++pIt )
+ {
+ const css::awt::KeyEvent& rAWTKey = *pIt;
+ const KeyCode aVCLKey = ::svt::AcceleratorExecute::st_AWTKey2VCLKey(rAWTKey);
+ const String sName = aVCLKey.GetName();
+
+ if (sName.Len () > 0)
+ return pIt;
+ }
+
+ return lKeys.end ();
+}
+
+//-----------------------------------------------
+css::uno::Sequence< css::uno::Any > SAL_CALL XCUBasedAcceleratorConfiguration::getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList)
+ throw(css::lang::IllegalArgumentException ,
+ css::uno::RuntimeException )
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ sal_Int32 i = 0;
+ sal_Int32 c = lCommandList.getLength();
+ css::uno::Sequence< css::uno::Any > lPreferredOnes (c); // dont pack list!
+ AcceleratorCache& rCache = impl_getCFG(sal_True);
+
+ for (i=0; i<c; ++i)
+ {
+ const ::rtl::OUString& rCommand = lCommandList[i];
+ if (!rCommand.getLength())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty command strings are not allowed here.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ (sal_Int16)i);
+
+ if (!rCache.hasCommand(rCommand))
+ continue;
+
+ AcceleratorCache::TKeyList lKeys = rCache.getKeysByCommand(rCommand);
+ if ( lKeys.empty() )
+ continue;
+
+ AcceleratorCache::TKeyList::const_iterator pPreferredKey = lcl_getPreferredKey(lKeys);
+ if (pPreferredKey != lKeys.end ())
+ {
+ css::uno::Any& rAny = lPreferredOnes[i];
+ rAny <<= *(pPreferredKey);
+ }
+ }
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return lPreferredOnes;
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand)
+ throw(css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::uno::RuntimeException )
+{
+ if (!sCommand.getLength())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty command strings are not allowed here.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 0);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AcceleratorCache& rPrimaryCache = impl_getCFG(sal_True, sal_True );
+ AcceleratorCache& rSecondaryCache = impl_getCFG(sal_False, sal_True);
+
+ if (!rPrimaryCache.hasCommand(sCommand) && !rSecondaryCache.hasCommand(sCommand))
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Command does not exists inside this container.")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ if (rPrimaryCache.hasCommand(sCommand))
+ rPrimaryCache.removeCommand(sCommand);
+ if (rSecondaryCache.hasCommand(sCommand))
+ rSecondaryCache.removeCommand(sCommand);
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::reload()
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::reload()" );
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ sal_Bool bPreferred;
+ css::uno::Reference< css::container::XNameAccess > xAccess;
+
+ bPreferred = sal_True;
+ m_aPrimaryReadCache = AcceleratorCache();
+ if (m_pPrimaryWriteCache)
+ {
+ // be aware of reentrance problems - use temp variable for calling delete ... :-)
+ AcceleratorCache* pTemp = m_pPrimaryWriteCache;
+ m_pPrimaryWriteCache = 0;
+ delete pTemp;
+ }
+ m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess;
+ impl_ts_load(bPreferred, xAccess); // load the preferred keys
+
+ bPreferred = sal_False;
+ m_aSecondaryReadCache = AcceleratorCache();
+ if (m_pSecondaryWriteCache)
+ {
+ // be aware of reentrance problems - use temp variable for calling delete ... :-)
+ AcceleratorCache* pTemp = m_pSecondaryWriteCache;
+ m_pSecondaryWriteCache = 0;
+ delete pTemp;
+ }
+ m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess;
+ impl_ts_load(bPreferred, xAccess); // load the secondary keys
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::store()
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::store()" );
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ sal_Bool bPreferred;
+ css::uno::Reference< css::container::XNameAccess > xAccess;
+
+ bPreferred = sal_True;
+ // on-demand creation of the primary write cache
+ impl_getCFG(bPreferred, sal_True);
+ m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess;
+ impl_ts_save(bPreferred, xAccess);
+
+ bPreferred = sal_False;
+ // on-demand creation of the secondary write cache
+ impl_getCFG(bPreferred, sal_True);
+ m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess;
+ impl_ts_save(bPreferred, xAccess);
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ // use m_aCache + old AcceleratorXMLWriter to store data directly on storage given as parameter ...
+ if (!xStorage.is())
+ return;
+
+ long nOpenModes = css::embed::ElementModes::READWRITE;
+ css::uno::Reference< css::embed::XStorage > xAcceleratorTypeStorage = xStorage->openStorageElement(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("accelerator")), nOpenModes);
+ if (!xAcceleratorTypeStorage.is())
+ return;
+
+ css::uno::Reference< css::io::XStream > xStream = xAcceleratorTypeStorage->openStreamElement(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("current")), nOpenModes);
+ css::uno::Reference< css::io::XOutputStream > xOut;
+ if (xStream.is())
+ xOut = xStream->getOutputStream();
+ if (!xOut.is())
+ throw css::io::IOException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Could not open accelerator configuration for saving.")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ // the original m_aCache has been split into primay cache and secondary cache...
+ // we should merge them before storing to storage
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AcceleratorCache aCache;
+ if (m_pPrimaryWriteCache != 0)
+ aCache.takeOver(*m_pPrimaryWriteCache);
+ else
+ aCache.takeOver(m_aPrimaryReadCache);
+
+ AcceleratorCache::TKeyList lKeys;
+ AcceleratorCache::TKeyList::const_iterator pIt;
+ if (m_pSecondaryWriteCache!=0)
+ {
+ lKeys = m_pSecondaryWriteCache->getAllKeys();
+ for ( pIt=lKeys.begin(); pIt!=lKeys.end(); ++pIt )
+ aCache.setKeyCommandPair(*pIt, m_pSecondaryWriteCache->getCommandByKey(*pIt));
+ }
+ else
+ {
+ lKeys = m_aSecondaryReadCache.getAllKeys();
+ for ( pIt=lKeys.begin(); pIt!=lKeys.end(); ++pIt )
+ aCache.setKeyCommandPair(*pIt, m_aSecondaryReadCache.getCommandByKey(*pIt));
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::io::XTruncate > xClearable(xOut, css::uno::UNO_QUERY_THROW);
+ xClearable->truncate();
+ css::uno::Reference< css::io::XSeekable > xSeek(xOut, css::uno::UNO_QUERY);
+ if (xSeek.is())
+ xSeek->seek(0);
+
+ css::uno::Reference< css::xml::sax::XDocumentHandler > xWriter (m_xSMGR->createInstance(SERVICENAME_SAXWRITER), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::io::XActiveDataSource> xDataSource(xWriter , css::uno::UNO_QUERY_THROW);
+ xDataSource->setOutputStream(xOut);
+
+ // write into the stream
+ AcceleratorConfigurationWriter aWriter(aCache, xWriter);
+ aWriter.flush();
+}
+
+//-----------------------------------------------
+::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::isModified()
+ throw(css::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+//-----------------------------------------------
+::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::isReadOnly()
+ throw(css::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& /*xStorage*/)
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XCUBasedAcceleratorConfiguration::setStorage()", "TODO implement this HACK .-)")
+}
+
+//-----------------------------------------------
+::sal_Bool SAL_CALL XCUBasedAcceleratorConfiguration::hasStorage()
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XCUBasedAcceleratorConfiguration::hasStorage()", "TODO implement this HACK .-)")
+ return sal_False;
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/)
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XCUBasedAcceleratorConfiguration::addConfigurationListener()", "TODO implement me")
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& /*xListener*/)
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XCUBasedAcceleratorConfiguration::removeConfigurationListener()", "TODO implement me")
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::reset()
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Reference< css::container::XNamed > xNamed(m_xCfg, css::uno::UNO_QUERY);
+ ::rtl::OUString sConfig = xNamed->getName();
+ if ( sConfig.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Global")) )
+ {
+ m_xCfg = css::uno::Reference< css::container::XNameAccess > (
+ ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_GLOBAL, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ),
+ css::uno::UNO_QUERY );
+ XCUBasedAcceleratorConfiguration::reload();
+ }
+ else if ( sConfig.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Modules")) )
+ {
+ m_xCfg = css::uno::Reference< css::container::XNameAccess > (
+ ::comphelper::ConfigurationHelper::openConfig( m_xSMGR, CFG_ENTRY_MODULES, ::comphelper::ConfigurationHelper::E_ALL_LOCALES ),
+ css::uno::UNO_QUERY );
+ XCUBasedAcceleratorConfiguration::reload();
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::addResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/)
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XCUBasedAcceleratorConfiguration::addResetListener()", "TODO implement me")
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::removeResetListener(const css::uno::Reference< css::form::XResetListener >& /*xListener*/)
+ throw(css::uno::RuntimeException)
+{
+ LOG_WARNING("XCUBasedAcceleratorConfiguration::removeResetListener()", "TODO implement me")
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::changesOccurred(const css::util::ChangesEvent& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "XCUBasedAcceleratorConfiguration::changesOccurred()" );
+
+ css::uno::Reference< css::container::XHierarchicalNameAccess > xHAccess;
+ aEvent.Base >>= xHAccess;
+ if (! xHAccess.is ())
+ return;
+
+ css::util::ChangesEvent aReceivedEvents( aEvent );
+ const sal_Int32 c = aReceivedEvents.Changes.getLength();
+ sal_Int32 i = 0;
+ for (i=0; i<c; ++i)
+ {
+ const css::util::ElementChange& aChange = aReceivedEvents.Changes[i];
+
+ // Only path of form "PrimaryKeys/Modules/Module['<module_name>']/Key['<command_url>']/Command[<locale>]" will
+ // be interesting for use. Sometimes short path values are given also by the broadcaster ... but they must be ignored :-)
+ // So we try to split the path into 3 parts (module isnt important here, because we already know it ... because
+ // these instance is bound to a specific module configuration ... or it''s the global configuration where no module is given at all.
+
+ ::rtl::OUString sOrgPath ;
+ ::rtl::OUString sPath ;
+ ::rtl::OUString sKey;
+
+ aChange.Accessor >>= sOrgPath;
+ sPath = sOrgPath;
+ ::rtl::OUString sPrimarySecondary = ::utl::extractFirstFromConfigurationPath(sPath, &sPath);
+ ::rtl::OUString sGlobalModules = ::utl::extractFirstFromConfigurationPath(sPath, &sPath);
+
+ if ( sGlobalModules.equals(CFG_ENTRY_GLOBAL) )
+ {
+ ::rtl::OUString sModule;
+ sKey = ::utl::extractFirstFromConfigurationPath(sPath, &sPath);
+ if (( sKey.getLength() > 0 ) && ( sPath.getLength() > 0 ))
+ reloadChanged(sPrimarySecondary, sGlobalModules, sModule, sKey);
+ }
+ else if ( sGlobalModules.equals(CFG_ENTRY_MODULES) )
+ {
+ ::rtl::OUString sModule = ::utl::extractFirstFromConfigurationPath(sPath, &sPath);
+ sKey = ::utl::extractFirstFromConfigurationPath(sPath, &sPath);
+
+ if (( sKey.getLength() > 0 ) && ( sPath.getLength() > 0 ))
+ {
+ reloadChanged(sPrimarySecondary, sGlobalModules, sModule, sKey);
+ }
+ }
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL XCUBasedAcceleratorConfiguration::disposing(const css::lang::EventObject& /*aSource*/)
+ throw(css::uno::RuntimeException)
+{
+}
+
+//-----------------------------------------------
+void XCUBasedAcceleratorConfiguration::impl_ts_load( sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg )
+{
+ AcceleratorCache aReadCache = AcceleratorCache();
+ css::uno::Reference< css::container::XNameAccess > xAccess;
+ if (m_sGlobalOrModules.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Global")))
+ xCfg->getByName(CFG_ENTRY_GLOBAL) >>= xAccess;
+ else if (m_sGlobalOrModules.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Modules")))
+ {
+ css::uno::Reference< css::container::XNameAccess > xModules;
+ xCfg->getByName(CFG_ENTRY_MODULES) >>= xModules;
+ xModules->getByName(m_sModuleCFG) >>= xAccess;
+ }
+
+ const ::rtl::OUString sIsoLang = impl_ts_getLocale().toISO();
+ const ::rtl::OUString sDefaultLocale(RTL_CONSTASCII_USTRINGPARAM("en-US"));
+
+ css::uno::Reference< css::container::XNameAccess > xKey;
+ css::uno::Reference< css::container::XNameAccess > xCommand;
+ if (xAccess.is())
+ {
+ css::uno::Sequence< ::rtl::OUString > lKeys = xAccess->getElementNames();
+ sal_Int32 nKeys = lKeys.getLength();
+ for ( sal_Int32 i=0; i<nKeys; ++i )
+ {
+ ::rtl::OUString sKey = lKeys[i];
+ xAccess->getByName(sKey) >>= xKey;
+ xKey->getByName(CFG_PROP_COMMAND) >>= xCommand;
+
+ css::uno::Sequence< ::rtl::OUString > lLocales = xCommand->getElementNames();
+ sal_Int32 nLocales = lLocales.getLength();
+ ::std::vector< ::rtl::OUString > aLocales;
+ for ( sal_Int32 j=0; j<nLocales; ++j )
+ aLocales.push_back(lLocales[j]);
+
+ ::std::vector< ::rtl::OUString >::const_iterator pFound;
+ for ( pFound = aLocales.begin(); pFound != aLocales.end(); ++pFound )
+ {
+ if ( *pFound == sIsoLang )
+ break;
+ }
+
+ if ( pFound == aLocales.end() )
+ {
+ for ( pFound = aLocales.begin(); pFound != aLocales.end(); ++pFound )
+ {
+ if ( *pFound == sDefaultLocale )
+ break;
+ }
+
+ if ( pFound == aLocales.end() )
+ continue;
+ }
+
+ ::rtl::OUString sLocale = *pFound;
+ ::rtl::OUString sCommand;
+ xCommand->getByName(sLocale) >>= sCommand;
+ if (sCommand.getLength()<1)
+ continue;
+
+ css::awt::KeyEvent aKeyEvent;
+
+ sal_Int32 nIndex = 0;
+ ::rtl::OUString sKeyCommand = sKey.getToken(0, '_', nIndex);
+ ::rtl::OUString sPrefix(RTL_CONSTASCII_USTRINGPARAM("KEY_"));
+ aKeyEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(sPrefix + sKeyCommand);
+
+ css::uno::Sequence< ::rtl::OUString > sToken(4);
+ const sal_Int32 nToken = 4;
+ sal_Bool bValid = sal_True;
+ sal_Int32 k;
+ for (k=0; k<nToken; ++k)
+ {
+ if (nIndex < 0)
+ break;
+
+ sToken[k] = sKey.getToken(0, '_', nIndex);
+ ::rtl::OUString sTest = sToken[k];
+ if (sToken[k].getLength() < 1)
+ {
+ bValid = sal_False;
+ break;
+ }
+
+ if (sToken[k].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SHIFT")))
+ aKeyEvent.Modifiers |= css::awt::KeyModifier::SHIFT;
+ else if (sToken[k].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MOD1")))
+ aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD1;
+ else if (sToken[k].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MOD2")))
+ aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD2;
+ else if (sToken[k].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MOD3")))
+ aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD3;
+ else
+ {
+ bValid = sal_False;
+ break;
+ }
+ }
+
+ if ( !aReadCache.hasKey(aKeyEvent) && bValid && k<nToken)
+ aReadCache.setKeyCommandPair(aKeyEvent, sCommand);
+ }
+ }
+
+ if (bPreferred)
+ m_aPrimaryReadCache.takeOver(aReadCache);
+ else
+ m_aSecondaryReadCache.takeOver(aReadCache);
+}
+
+//-----------------------------------------------
+void XCUBasedAcceleratorConfiguration::impl_ts_save(sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& /*xCfg*/)
+{
+ if (bPreferred)
+ {
+ AcceleratorCache::TKeyList::const_iterator pIt;
+ AcceleratorCache::TKeyList lPrimaryReadKeys = m_aPrimaryReadCache.getAllKeys();
+ AcceleratorCache::TKeyList lPrimaryWriteKeys = m_pPrimaryWriteCache->getAllKeys();
+
+ for ( pIt = lPrimaryReadKeys.begin(); pIt != lPrimaryReadKeys.end(); ++pIt )
+ {
+ if (!m_pPrimaryWriteCache->hasKey(*pIt))
+ removeKeyFromConfiguration(*pIt, sal_True);
+ }
+
+ for ( pIt = lPrimaryWriteKeys.begin(); pIt != lPrimaryWriteKeys.end(); ++pIt )
+ {
+ ::rtl::OUString sCommand = m_pPrimaryWriteCache->getCommandByKey(*pIt);
+ if (!m_aPrimaryReadCache.hasKey(*pIt))
+ {
+ insertKeyToConfiguration(*pIt, sCommand, sal_True);
+ }
+ else
+ {
+ ::rtl::OUString sReadCommand = m_aPrimaryReadCache.getCommandByKey(*pIt);
+ if (sReadCommand != sCommand)
+ insertKeyToConfiguration(*pIt, sCommand, sal_True);
+ }
+ }
+
+ // take over all changes into the original container
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_pPrimaryWriteCache)
+ {
+ m_aPrimaryReadCache.takeOver(*m_pPrimaryWriteCache);
+ AcceleratorCache* pTemp = m_pPrimaryWriteCache;
+ m_pPrimaryWriteCache = 0;
+ delete pTemp;
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+ }
+
+ else
+ {
+ AcceleratorCache::TKeyList::const_iterator pIt;
+ AcceleratorCache::TKeyList lSecondaryReadKeys = m_aSecondaryReadCache.getAllKeys();
+ AcceleratorCache::TKeyList lSecondaryWriteKeys = m_pSecondaryWriteCache->getAllKeys();
+
+ for ( pIt = lSecondaryReadKeys.begin(); pIt != lSecondaryReadKeys.end(); ++pIt)
+ {
+ if (!m_pSecondaryWriteCache->hasKey(*pIt))
+ removeKeyFromConfiguration(*pIt, sal_False);
+ }
+
+
+ for ( pIt = lSecondaryWriteKeys.begin(); pIt != lSecondaryWriteKeys.end(); ++pIt )
+ {
+ ::rtl::OUString sCommand = m_pSecondaryWriteCache->getCommandByKey(*pIt);
+ if (!m_aSecondaryReadCache.hasKey(*pIt))
+ {
+ insertKeyToConfiguration(*pIt, sCommand, sal_False);
+ }
+ else
+ {
+ ::rtl::OUString sReadCommand = m_aSecondaryReadCache.getCommandByKey(*pIt);
+ if (sReadCommand != sCommand)
+ insertKeyToConfiguration(*pIt, sCommand, sal_False);
+ }
+ }
+
+ // take over all changes into the original container
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_pSecondaryWriteCache)
+ {
+ m_aSecondaryReadCache.takeOver(*m_pSecondaryWriteCache);
+ AcceleratorCache* pTemp = m_pSecondaryWriteCache;
+ m_pSecondaryWriteCache = 0;
+ delete pTemp;
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+ }
+
+ ::comphelper::ConfigurationHelper::flush(m_xCfg);
+}
+
+//-----------------------------------------------
+void XCUBasedAcceleratorConfiguration::insertKeyToConfiguration( const css::awt::KeyEvent& aKeyEvent, const ::rtl::OUString& sCommand, const sal_Bool bPreferred )
+{
+ css::uno::Reference< css::container::XNameAccess > xAccess;
+ css::uno::Reference< css::container::XNameContainer > xContainer;
+ css::uno::Reference< css::lang::XSingleServiceFactory > xFac;
+ css::uno::Reference< css::uno::XInterface > xInst;
+
+ if ( bPreferred )
+ m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess;
+ else
+ m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess;
+
+ if ( m_sGlobalOrModules.equals(CFG_ENTRY_GLOBAL) )
+ xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer;
+ else if ( m_sGlobalOrModules.equals(CFG_ENTRY_MODULES) )
+ {
+ css::uno::Reference< css::container::XNameContainer > xModules;
+ xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules;
+ if ( !xModules->hasByName(m_sModuleCFG) )
+ {
+ xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xModules, css::uno::UNO_QUERY);
+ xInst = xFac->createInstance();
+ xModules->insertByName(m_sModuleCFG, css::uno::makeAny(xInst));
+ }
+ xModules->getByName(m_sModuleCFG) >>= xContainer;
+ }
+
+ const ::rtl::OUString sKey = lcl_getKeyString(m_rKeyMapping,aKeyEvent);
+ css::uno::Reference< css::container::XNameAccess > xKey;
+ css::uno::Reference< css::container::XNameContainer > xCommand;
+ if ( !xContainer->hasByName(sKey) )
+ {
+ xFac = css::uno::Reference< css::lang::XSingleServiceFactory >(xContainer, css::uno::UNO_QUERY);
+ xInst = xFac->createInstance();
+ xContainer->insertByName(sKey, css::uno::makeAny(xInst));
+ }
+ xContainer->getByName(sKey) >>= xKey;
+
+ xKey->getByName(CFG_PROP_COMMAND) >>= xCommand;
+ ::rtl::OUString sLocale = impl_ts_getLocale().toISO();
+ if ( !xCommand->hasByName(sLocale) )
+ xCommand->insertByName(sLocale, css::uno::makeAny(sCommand));
+ else
+ xCommand->replaceByName(sLocale, css::uno::makeAny(sCommand));
+}
+
+//-----------------------------------------------
+void XCUBasedAcceleratorConfiguration::removeKeyFromConfiguration( const css::awt::KeyEvent& aKeyEvent, const sal_Bool bPreferred )
+{
+ css::uno::Reference< css::container::XNameAccess > xAccess;
+ css::uno::Reference< css::container::XNameContainer > xContainer;
+
+ if ( bPreferred )
+ m_xCfg->getByName(CFG_ENTRY_PRIMARY) >>= xAccess;
+ else
+ m_xCfg->getByName(CFG_ENTRY_SECONDARY) >>= xAccess;
+
+ if ( m_sGlobalOrModules.equals(CFG_ENTRY_GLOBAL) )
+ xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer;
+ else if ( m_sGlobalOrModules.equals(CFG_ENTRY_MODULES) )
+ {
+ css::uno::Reference< css::container::XNameAccess > xModules;
+ xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules;
+ if ( !xModules->hasByName(m_sModuleCFG) )
+ return;
+ xModules->getByName(m_sModuleCFG) >>= xContainer;
+ }
+
+ const ::rtl::OUString sKey = lcl_getKeyString(m_rKeyMapping,aKeyEvent);
+ xContainer->removeByName(sKey);
+}
+
+//-----------------------------------------------
+void XCUBasedAcceleratorConfiguration::reloadChanged( const ::rtl::OUString& sPrimarySecondary, const ::rtl::OUString& sGlobalModules, const ::rtl::OUString& sModule, const ::rtl::OUString& sKey )
+{
+ css::uno::Reference< css::container::XNameAccess > xAccess;
+ css::uno::Reference< css::container::XNameContainer > xContainer;
+
+ m_xCfg->getByName(sPrimarySecondary) >>= xAccess;
+ if ( sGlobalModules.equals(CFG_ENTRY_GLOBAL) )
+ xAccess->getByName(CFG_ENTRY_GLOBAL) >>= xContainer;
+ else
+ {
+ css::uno::Reference< css::container::XNameAccess > xModules;
+ xAccess->getByName(CFG_ENTRY_MODULES) >>= xModules;
+ if ( !xModules->hasByName(sModule) )
+ return;
+ xModules->getByName(sModule) >>= xContainer;
+ }
+
+ css::awt::KeyEvent aKeyEvent;
+ ::rtl::OUString sKeyIdentifier;
+
+ sal_Int32 nIndex = 0;
+ sKeyIdentifier = sKey.getToken(0, '_', nIndex);
+ aKeyEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("KEY_"))+sKeyIdentifier);
+
+ css::uno::Sequence< ::rtl::OUString > sToken(3);
+ const sal_Int32 nToken = 3;
+ for (sal_Int32 i=0; i<nToken; ++i)
+ {
+ if ( nIndex < 0 )
+ break;
+
+ sToken[i] = sKey.getToken(0, '_', nIndex);
+ if (sToken[i].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SHIFT")))
+ aKeyEvent.Modifiers |= css::awt::KeyModifier::SHIFT;
+ else if (sToken[i].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MOD1")))
+ aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD1;
+ else if (sToken[i].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MOD2")))
+ aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD2;
+ else if (sToken[i].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MOD3")))
+ aKeyEvent.Modifiers |= css::awt::KeyModifier::MOD3;
+ }
+
+ css::uno::Reference< css::container::XNameAccess > xKey;
+ css::uno::Reference< css::container::XNameAccess > xCommand;
+ ::rtl::OUString sCommand;
+
+ if (xContainer->hasByName(sKey))
+ {
+ ::rtl::OUString sLocale = impl_ts_getLocale().toISO();
+ xContainer->getByName(sKey) >>= xKey;
+ xKey->getByName(CFG_PROP_COMMAND) >>= xCommand;
+ xCommand->getByName(sLocale) >>= sCommand;
+ }
+
+ if (sPrimarySecondary.equals(CFG_ENTRY_PRIMARY))
+ {
+ if (sCommand.getLength() ==0)
+ m_aPrimaryReadCache.removeKey(aKeyEvent);
+ else
+ m_aPrimaryReadCache.setKeyCommandPair(aKeyEvent, sCommand);
+ }
+ else if (sPrimarySecondary.equals(CFG_ENTRY_SECONDARY))
+ {
+ if (sCommand.getLength() ==0)
+ m_aSecondaryReadCache.removeKey(aKeyEvent);
+ else
+ m_aSecondaryReadCache.setKeyCommandPair(aKeyEvent, sCommand);
+ }
+}
+
+//-----------------------------------------------
+AcceleratorCache& XCUBasedAcceleratorConfiguration::impl_getCFG(sal_Bool bPreferred, sal_Bool bWriteAccessRequested)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (bPreferred)
+ {
+ //create copy of our readonly-cache, if write access is forced ... but
+ //not still possible!
+ if (
+ (bWriteAccessRequested) &&
+ (!m_pPrimaryWriteCache )
+ )
+ {
+ m_pPrimaryWriteCache = new AcceleratorCache(m_aPrimaryReadCache);
+ }
+
+ // in case, we have a writeable cache, we use it for reading too!
+ // Otherwhise the API user cant find its own changes ...
+ if (m_pPrimaryWriteCache)
+ return *m_pPrimaryWriteCache;
+ else
+ return m_aPrimaryReadCache;
+ }
+
+ else
+ {
+ //create copy of our readonly-cache, if write access is forced ... but
+ //not still possible!
+ if (
+ (bWriteAccessRequested) &&
+ (!m_pSecondaryWriteCache )
+ )
+ {
+ m_pSecondaryWriteCache = new AcceleratorCache(m_aSecondaryReadCache);
+ }
+
+ // in case, we have a writeable cache, we use it for reading too!
+ // Otherwhise the API user cant find its own changes ...
+ if (m_pSecondaryWriteCache)
+ return *m_pSecondaryWriteCache;
+ else
+ return m_aSecondaryReadCache;
+ }
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+::comphelper::Locale XCUBasedAcceleratorConfiguration::impl_ts_getLocale() const
+{
+ static ::rtl::OUString LOCALE_PACKAGE(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Setup"));
+ static ::rtl::OUString LOCALE_PATH(RTL_CONSTASCII_USTRINGPARAM("L10N"));
+ static ::rtl::OUString LOCALE_KEY(RTL_CONSTASCII_USTRINGPARAM("ooLocale"));
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::uno::XInterface > xCFG = fpc::ConfigurationHelper::openConfig(xSMGR, LOCALE_PACKAGE, LOCALE_PATH, fpc::ConfigurationHelper::E_READONLY);
+ css::uno::Reference< css::beans::XPropertySet > xProp (xCFG, css::uno::UNO_QUERY_THROW);
+ ::rtl::OUString sISOLocale;
+ xProp->getPropertyValue(LOCALE_KEY) >>= sISOLocale;
+
+ if (!sISOLocale.getLength())
+ return ::comphelper::Locale::EN_US();
+ return ::comphelper::Locale(sISOLocale);
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/accelerators/acceleratorexecute.cxx b/framework/source/accelerators/acceleratorexecute.cxx
new file mode 100644
index 000000000000..1b5b37f439c8
--- /dev/null
+++ b/framework/source/accelerators/acceleratorexecute.cxx
@@ -0,0 +1,371 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include "acceleratorexecute.hxx"
+
+//===============================================
+// includes
+
+#include <com/sun/star/frame/XModuleManager.hpp>
+
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+
+#include <com/sun/star/awt/KeyModifier.hpp>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+//===============================================
+// namespace
+
+namespace svt
+{
+
+namespace css = ::com::sun::star;
+
+//===============================================
+// definitions
+
+//-----------------------------------------------
+AcceleratorExecute::AcceleratorExecute()
+ : TMutexInit ( )
+ , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback))
+{
+}
+
+//-----------------------------------------------
+AcceleratorExecute::AcceleratorExecute(const AcceleratorExecute& rCopy)
+ : TMutexInit ( )
+ , m_aAsyncCallback(LINK(this, AcceleratorExecute, impl_ts_asyncCallback))
+{
+ // copy construction sint supported in real ...
+ // but we need this ctor to init our async callback ...
+}
+
+//-----------------------------------------------
+AcceleratorExecute::~AcceleratorExecute()
+{
+ // does nothing real
+}
+
+//-----------------------------------------------
+AcceleratorExecute* AcceleratorExecute::createAcceleratorHelper()
+{
+ AcceleratorExecute* pNew = new AcceleratorExecute();
+ return pNew;
+}
+
+//-----------------------------------------------
+void AcceleratorExecute::init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR,
+ const css::uno::Reference< css::frame::XFrame >& xEnv )
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ // take over the uno service manager
+ m_xSMGR = xSMGR;
+
+ // specify our internal dispatch provider
+ // frame or desktop?! => document or global config.
+ sal_Bool bDesktopIsUsed = sal_False;
+ m_xDispatcher = css::uno::Reference< css::frame::XDispatchProvider >(xEnv, css::uno::UNO_QUERY);
+ if (!m_xDispatcher.is())
+ {
+ aLock.clear();
+ // <- SAFE ------------------------------
+
+ css::uno::Reference< css::frame::XDispatchProvider > xDispatcher(
+ xSMGR->createInstance(SERVICENAME_DESKTOP),
+ css::uno::UNO_QUERY_THROW);
+
+ // SAFE -> ------------------------------
+ aLock.reset();
+
+ m_xDispatcher = xDispatcher;
+ bDesktopIsUsed = sal_True;
+ }
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ // open all needed configuration objects
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg;
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg;
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg ;
+
+ // global cfg
+ xGlobalCfg = AcceleratorExecute::impl_st_openGlobalConfig(xSMGR);
+ if (!bDesktopIsUsed)
+ {
+ // module cfg
+ xModuleCfg = AcceleratorExecute::impl_st_openModuleConfig(xSMGR, xEnv);
+
+ // doc cfg
+ css::uno::Reference< css::frame::XController > xController;
+ css::uno::Reference< css::frame::XModel > xModel;
+ xController = xEnv->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+ if (xModel.is())
+ xDocCfg = AcceleratorExecute::impl_st_openDocConfig(xModel);
+ }
+
+ // SAFE -> ------------------------------
+ aLock.reset();
+
+ m_xGlobalCfg = xGlobalCfg;
+ m_xModuleCfg = xModuleCfg;
+ m_xDocCfg = xDocCfg ;
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void AcceleratorExecute::execute(const KeyCode& aVCLKey)
+{
+ css::awt::KeyEvent aAWTKey = AcceleratorExecute::st_VCLKey2AWTKey(aVCLKey);
+ execute(aAWTKey);
+}
+
+//-----------------------------------------------
+void AcceleratorExecute::execute(const css::awt::KeyEvent& aAWTKey)
+{
+ ::rtl::OUString sCommand = impl_ts_findCommand(aAWTKey);
+
+ // No Command found? Do nothing! User isnt interested on any error handling .-)
+ if (!sCommand.getLength())
+ return;
+
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ m_lCommandQueue.push_back(sCommand);
+ m_aAsyncCallback.Post(0);
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::awt::KeyEvent AcceleratorExecute::st_VCLKey2AWTKey(const KeyCode& aVCLKey)
+{
+ css::awt::KeyEvent aAWTKey;
+ aAWTKey.Modifiers = 0;
+ aAWTKey.KeyCode = (sal_Int16)aVCLKey.GetCode();
+
+ if (aVCLKey.IsShift())
+ aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT;
+ if (aVCLKey.IsMod1())
+ aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1;
+ if (aVCLKey.IsMod2())
+ aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2;
+ if (aVCLKey.IsMod3())
+ aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3;
+
+ return aAWTKey;
+}
+
+/*
+ViewFrame->GetObjectShell
+ObjectShell->GetStyleSheetPool
+*/
+
+//-----------------------------------------------
+KeyCode AcceleratorExecute::st_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey)
+{
+ sal_Bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT );
+ sal_Bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 );
+ sal_Bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 );
+ sal_Bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 );
+ sal_uInt16 nKey = (sal_uInt16)aAWTKey.KeyCode;
+
+ return KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
+}
+
+//-----------------------------------------------
+::rtl::OUString AcceleratorExecute::impl_ts_findCommand(const css::awt::KeyEvent& aKey)
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xGlobalCfg = m_xGlobalCfg;
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xModuleCfg = m_xModuleCfg;
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xDocCfg = m_xDocCfg ;
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ ::rtl::OUString sCommand;
+ try
+ {
+ if (xDocCfg.is())
+ sCommand = xDocCfg->getCommandByKeyEvent(aKey);
+ }
+ catch(const css::container::NoSuchElementException&)
+ {
+ try
+ {
+ if (xModuleCfg.is())
+ sCommand = xModuleCfg->getCommandByKeyEvent(aKey);
+ }
+ catch(const css::container::NoSuchElementException&)
+ {
+ try
+ {
+ if (xGlobalCfg.is())
+ sCommand = xGlobalCfg->getCommandByKeyEvent(aKey);
+ }
+ catch(const css::container::NoSuchElementException&)
+ {}
+ }
+ }
+
+ return sCommand;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openGlobalConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+{
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg(
+ xSMGR->createInstance(SERVICENAME_GLOBALACCELERATORCONFIGURATION),
+ css::uno::UNO_QUERY_THROW);
+ return xAccCfg;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openModuleConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ css::uno::Reference< css::frame::XModuleManager > xModuleDetection(
+ xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
+ css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString sModule;
+ try
+ {
+ sModule = xModuleDetection->identify(xFrame);
+ }
+ catch(const css::uno::RuntimeException& exRuntime)
+ { throw exRuntime; }
+ catch(const css::uno::Exception&)
+ { return css::uno::Reference< css::ui::XAcceleratorConfiguration >(); }
+
+ css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xUISupplier(
+ xSMGR->createInstance(SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER),
+ css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(sModule);
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW);
+ return xAccCfg;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::impl_st_openDocConfig(const css::uno::Reference< css::frame::XModel >& xModel)
+{
+ css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUISupplier(xModel, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager();
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW);
+ return xAccCfg;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::util::XURLTransformer > AcceleratorExecute::impl_ts_getURLParser()
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ if (m_xURLParser.is())
+ return m_xURLParser;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::util::XURLTransformer > xParser(
+ xSMGR->createInstance(SERVICENAME_URLTRANSFORMER),
+ css::uno::UNO_QUERY_THROW);
+
+ // SAFE -> ----------------------------------
+ aLock.reset();
+ m_xURLParser = xParser;
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ return xParser;
+}
+
+//-----------------------------------------------
+IMPL_LINK(AcceleratorExecute, impl_ts_asyncCallback, void*, pVoid)
+{
+ // SAFE -> ----------------------------------
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ TCommandQueue::iterator pIt = m_lCommandQueue.begin();
+ if (pIt == m_lCommandQueue.end())
+ return 0;
+ ::rtl::OUString sCommand = *pIt;
+ m_lCommandQueue.erase(pIt);
+
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider = m_xDispatcher;
+
+ aLock.clear();
+ // <- SAFE ----------------------------------
+
+ // convert command in URL structure
+ css::uno::Reference< css::util::XURLTransformer > xParser = impl_ts_getURLParser();
+ css::util::URL aURL;
+ aURL.Complete = sCommand;
+ xParser->parseStrict(aURL);
+
+ // ask for dispatch object
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, ::rtl::OUString(), 0);
+ css::uno::Sequence< css::beans::PropertyValue> aArgs;
+ if (xDispatch.is())
+ {
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ {
+ Sequence<css::beans::PropertyValue> source;
+ ::comphelper::UiEventsLogger::appendDispatchOrigin(OUString(RTL_CONSTASCII_USTRINGPARAM("AcceleratorExecute")));
+ ::comphelper::UiEventsLogger::logDispatch(aURL, source);
+ }
+ xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue >());
+ }
+ return 0;
+}
+
+} // namespace svt
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/accelerators/acceleratorexecute.hxx b/framework/source/accelerators/acceleratorexecute.hxx
new file mode 100644
index 000000000000..a733e55a550c
--- /dev/null
+++ b/framework/source/accelerators/acceleratorexecute.hxx
@@ -0,0 +1,246 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_SVTOOLS_ACCELERATOREXECUTE_HXX
+#define INCLUDED_SVTOOLS_ACCELERATOREXECUTE_HXX
+
+//===============================================
+// includes
+
+#include <vector>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include <com/sun/star/frame/XFrame.hpp>
+
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <vcl/keycod.hxx>
+#include <vcl/evntpost.hxx>
+#include <osl/mutex.h>
+
+//===============================================
+// namespace
+
+namespace svt
+{
+
+#ifdef css
+ #error "Who define css? I need it as namespace alias."
+#else
+ #define css ::com::sun::star
+#endif
+
+//===============================================
+// definitions
+
+struct TMutexInit
+{
+ ::osl::Mutex m_aLock;
+};
+
+//===============================================
+/**
+ @descr implements a helper, which can be used to
+ convert vcl key codes into awt key codes ...
+ and reverse.
+
+ Further such key code can be triggered.
+ Doing so different accelerator
+ configurations are merged together; a suitable
+ command registered for the given key code is searched
+ and will be dispatched.
+
+ @attention
+
+ Because exceution of an accelerator command can be dangerous
+ (in case it force an office shutdown for key "ALT+F4"!)
+ all internal dispatches are done asynchronous.
+ Menas that the trigger call doesnt wait till the dispatch
+ is finished. You can call very often. All requests will be
+ queued internal and dispatched ASAP.
+
+ Of course this queue will be stopped if the environment
+ will be destructed ...
+ */
+class AcceleratorExecute : private TMutexInit
+{
+ //-------------------------------------------
+ // const, types
+ private:
+
+ /** TODO document me */
+ typedef ::std::vector< ::rtl::OUString > TCommandQueue;
+
+ //-------------------------------------------
+ // member
+ private:
+
+ /** TODO document me */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ /** TODO document me */
+ css::uno::Reference< css::util::XURLTransformer > m_xURLParser;
+
+ /** TODO document me */
+ css::uno::Reference< css::frame::XDispatchProvider > m_xDispatcher;
+
+ /** TODO document me */
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > m_xGlobalCfg;
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > m_xModuleCfg;
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > m_xDocCfg;
+
+ /** TODO document me */
+ TCommandQueue m_lCommandQueue;
+
+ /** TODO document me */
+ ::vcl::EventPoster m_aAsyncCallback;
+
+ //-------------------------------------------
+ // interface
+ public:
+
+ //---------------------------------------
+ /** @short factory method to create new accelerator
+ helper instance.
+
+ @descr Such helper instance must be initialized at first.
+ So it can know its environment (global/module or
+ document specific).
+
+ Afterwards it can be used to execute incoming
+ accelerator requests.
+
+ The "end of life" of such helper can be reached as follow:
+
+ - delete the object
+ => If it stands currently in its execute method, they will
+ be finished. All further queued requests will be removed
+ and further not executed!
+
+ Other modes are possible and will be implemented ASAP :-)
+ */
+ static AcceleratorExecute* createAcceleratorHelper();
+
+ //---------------------------------------
+ /** @short fight against inlining ... */
+ virtual ~AcceleratorExecute();
+
+ //---------------------------------------
+ /** @short init this instance.
+
+ @descr It must be called as first method after creation.
+ And further it can be called more then once ...
+ but at least its should be used one times only.
+ Otherwhise nobody can say, which asynchronous
+ executions will be used inside the old and which one
+ will be used inside the new environment.
+
+ @param xSMGR
+ reference to an uno service manager.
+
+ @param xEnv
+ if it points to a valid frame it will be used
+ to execute the dispatch there. Further the frame
+ is used to locate the right module configuration
+ and use it merged together with the document and
+ the global configuration.
+
+ If this parameter is set to NULL, the global configuration
+ is used only. Further the global Desktop instance is
+ used for dispatch.
+ */
+ virtual void init(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR,
+ const css::uno::Reference< css::frame::XFrame >& xEnv );
+
+ //---------------------------------------
+ /** @short trigger this accelerator.
+
+ @descr The internal configuartions are used to find
+ as suitable command for this key code.
+ This command will be queued and executed later
+ asynchronous.
+
+ @param aKey
+ specify the accelerator for execute.
+ */
+ virtual void execute(const KeyCode& aKey);
+ virtual void execute(const css::awt::KeyEvent& aKey);
+
+ //---------------------------------------
+ /** TODO document me */
+ static css::awt::KeyEvent st_VCLKey2AWTKey(const KeyCode& aKey);
+ static KeyCode st_AWTKey2VCLKey(const css::awt::KeyEvent& aKey);
+
+ //-------------------------------------------
+ // internal
+ private:
+
+ //---------------------------------------
+ /** @short allow creation of instances of this class
+ by using our factory only!
+ */
+ AcceleratorExecute();
+ AcceleratorExecute(const AcceleratorExecute& rCopy);
+ void operator=(const AcceleratorExecute& rCopy) {};
+
+ //---------------------------------------
+ /** TODO document me */
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > impl_st_openGlobalConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > impl_st_openModuleConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xFrame);
+
+ css::uno::Reference< css::ui::XAcceleratorConfiguration > impl_st_openDocConfig(const css::uno::Reference< css::frame::XModel >& xModel);
+
+ //---------------------------------------
+ /** TODO document me */
+ ::rtl::OUString impl_ts_findCommand(const css::awt::KeyEvent& aKey);
+
+ //---------------------------------------
+ /** TODO document me */
+ css::uno::Reference< css::util::XURLTransformer > impl_ts_getURLParser();
+
+ //---------------------------------------
+ /** TODO document me */
+ DECL_LINK(impl_ts_asyncCallback, void*);
+};
+
+#undef css
+#undef css
+
+} // namespace svt
+
+#endif // INCLUDED_SVTOOLS_ACCELERATOREXECUTE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/accelerators/documentacceleratorconfiguration.cxx b/framework/source/accelerators/documentacceleratorconfiguration.cxx
new file mode 100644
index 000000000000..ba09a7a15e20
--- /dev/null
+++ b/framework/source/accelerators/documentacceleratorconfiguration.cxx
@@ -0,0 +1,212 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <accelerators/documentacceleratorconfiguration.hxx>
+
+#include <xml/acceleratorconfigurationreader.hxx>
+
+#include <xml/acceleratorconfigurationwriter.hxx>
+
+#include <xml/saxnamespacefilter.hxx>
+
+//_______________________________________________
+// own includes
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+#include <acceleratorconst.h>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+
+#include <com/sun/star/io/XActiveDataSource.hpp>
+
+#include <com/sun/star/io/XSeekable.hpp>
+
+#include <com/sun/star/io/XTruncate.hpp>
+
+#include <com/sun/star/embed/ElementModes.hpp>
+
+#include <com/sun/star/xml/sax/InputSource.hpp>
+
+#include <com/sun/star/xml/sax/XParser.hpp>
+
+//_______________________________________________
+// other includes
+
+#include <comphelper/sequenceashashmap.hxx>
+
+//_______________________________________________
+// const
+
+namespace framework
+{
+
+//-----------------------------------------------
+// XInterface, XTypeProvider, XServiceInfo
+DEFINE_XINTERFACE_2(DocumentAcceleratorConfiguration ,
+ XMLBasedAcceleratorConfiguration ,
+ DIRECT_INTERFACE(css::lang::XServiceInfo) ,
+ DIRECT_INTERFACE(css::lang::XInitialization))
+// DIRECT_INTERFACE(css::ui::XUIConfigurationStorage))
+
+DEFINE_XTYPEPROVIDER_2_WITH_BASECLASS(DocumentAcceleratorConfiguration ,
+ XMLBasedAcceleratorConfiguration ,
+ css::lang::XServiceInfo ,
+ css::lang::XInitialization)
+// css::ui::XUIConfigurationStorage)
+
+DEFINE_XSERVICEINFO_MULTISERVICE(DocumentAcceleratorConfiguration ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_DOCUMENTACCELERATORCONFIGURATION ,
+ IMPLEMENTATIONNAME_DOCUMENTACCELERATORCONFIGURATION)
+
+DEFINE_INIT_SERVICE(DocumentAcceleratorConfiguration,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+ )
+
+//-----------------------------------------------
+DocumentAcceleratorConfiguration::DocumentAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
+ : XMLBasedAcceleratorConfiguration(xSMGR)
+{
+}
+
+//-----------------------------------------------
+DocumentAcceleratorConfiguration::~DocumentAcceleratorConfiguration()
+{
+ m_aPresetHandler.removeStorageListener(this);
+}
+
+//-----------------------------------------------
+void SAL_CALL DocumentAcceleratorConfiguration::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ ::comphelper::SequenceAsHashMap lArgs(lArguments);
+ m_xDocumentRoot = lArgs.getUnpackedValueOrDefault(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentRoot")),
+ css::uno::Reference< css::embed::XStorage >());
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ impl_ts_fillCache();
+}
+
+//-----------------------------------------------
+void SAL_CALL DocumentAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
+ throw(css::uno::RuntimeException)
+{
+ // Attention! xStorage must be accepted too, if it's NULL !
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ sal_Bool bForgetOldStorages = m_xDocumentRoot.is();
+ m_xDocumentRoot = xStorage;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (bForgetOldStorages)
+ impl_ts_clearCache();
+
+ if (xStorage.is())
+ impl_ts_fillCache();
+}
+
+//-----------------------------------------------
+sal_Bool SAL_CALL DocumentAcceleratorConfiguration::hasStorage()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ return m_xDocumentRoot.is();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void DocumentAcceleratorConfiguration::impl_ts_fillCache()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xDocumentRoot = m_xDocumentRoot;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // Sometimes we must live without a document root.
+ // E.g. if the document is readonly ...
+ if (!xDocumentRoot.is())
+ return;
+
+ // get current office locale ... but dont cache it.
+ // Otherwise we must be listener on the configuration layer
+ // which seems to superflous for this small implementation .-)
+ ::comphelper::Locale aLocale = impl_ts_getLocale();
+
+ // May be the current document does not contain any
+ // accelerator config? Handle it gracefully :-)
+ try
+ {
+ // Note: The used preset class is threadsafe by itself ... and live if we live!
+ // We do not need any mutex here.
+
+ // open the folder, where the configuration exists
+ m_aPresetHandler.connectToResource(
+ PresetHandler::E_DOCUMENT,
+ PresetHandler::RESOURCETYPE_ACCELERATOR(),
+ ::rtl::OUString(),
+ xDocumentRoot,
+ aLocale);
+
+ DocumentAcceleratorConfiguration::reload();
+ m_aPresetHandler.addStorageListener(this);
+ }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+//-----------------------------------------------
+void DocumentAcceleratorConfiguration::impl_ts_clearCache()
+{
+ m_aPresetHandler.forgetCachedStorages();
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/accelerators/globalacceleratorconfiguration.cxx b/framework/source/accelerators/globalacceleratorconfiguration.cxx
new file mode 100644
index 000000000000..173d19cd7d7e
--- /dev/null
+++ b/framework/source/accelerators/globalacceleratorconfiguration.cxx
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <accelerators/globalacceleratorconfiguration.hxx>
+
+//_______________________________________________
+// own includes
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include "helper/mischelper.hxx"
+
+#include <acceleratorconst.h>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+
+//_______________________________________________
+// other includes
+#include <vcl/svapp.hxx>
+#include <comphelper/locale.hxx>
+#include <comphelper/configurationhelper.hxx>
+
+//_______________________________________________
+// const
+
+namespace framework
+{
+
+//-----------------------------------------------
+// XInterface, XTypeProvider, XServiceInfo
+DEFINE_XINTERFACE_2(GlobalAcceleratorConfiguration ,
+ XCUBasedAcceleratorConfiguration ,
+ DIRECT_INTERFACE(css::lang::XServiceInfo),
+ DIRECT_INTERFACE(css::lang::XInitialization))
+DEFINE_XTYPEPROVIDER_2_WITH_BASECLASS(GlobalAcceleratorConfiguration,
+ XCUBasedAcceleratorConfiguration ,
+ css::lang::XServiceInfo ,
+ css::lang::XInitialization)
+
+DEFINE_XSERVICEINFO_MULTISERVICE(GlobalAcceleratorConfiguration ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_GLOBALACCELERATORCONFIGURATION ,
+ IMPLEMENTATIONNAME_GLOBALACCELERATORCONFIGURATION)
+
+DEFINE_INIT_SERVICE(GlobalAcceleratorConfiguration,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ impl_ts_fillCache();
+ }
+ )
+
+//-----------------------------------------------
+GlobalAcceleratorConfiguration::GlobalAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
+ : XCUBasedAcceleratorConfiguration(xSMGR)
+{
+}
+
+//-----------------------------------------------
+GlobalAcceleratorConfiguration::~GlobalAcceleratorConfiguration()
+{
+}
+
+void SAL_CALL GlobalAcceleratorConfiguration::initialize(const css::uno::Sequence< css::uno::Any >& /*lArguments*/)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+}
+
+//-----------------------------------------------
+void GlobalAcceleratorConfiguration::impl_ts_fillCache()
+{
+ // get current office locale ... but dont cache it.
+ // Otherwise we must be listener on the configuration layer
+ // which seems to superflous for this small implementation .-)
+ ::comphelper::Locale aLocale = ::comphelper::Locale(m_sLocale);
+
+ // May be there exists no accelerator config? Handle it gracefully :-)
+ try
+ {
+ m_sGlobalOrModules = CFG_ENTRY_GLOBAL;
+ XCUBasedAcceleratorConfiguration::reload();
+
+ css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(m_xCfg, css::uno::UNO_QUERY_THROW);
+ m_xCfgListener = new WeakChangesListener(this);
+ xBroadcaster->addChangesListener(m_xCfgListener);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/accelerators/keymapping.cxx b/framework/source/accelerators/keymapping.cxx
new file mode 100644
index 000000000000..e10b062d9af3
--- /dev/null
+++ b/framework/source/accelerators/keymapping.cxx
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <accelerators/keymapping.hxx>
+
+//_______________________________________________
+// own includes
+
+#include <macros/generic.hxx>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/awt/Key.hpp>
+
+//_______________________________________________
+// other includes
+
+//_______________________________________________
+// namespace
+
+namespace framework
+{
+
+//_______________________________________________
+// helper
+
+KeyMapping::KeyIdentifierInfo KeyMapping::KeyIdentifierMap[] =
+{
+ {css::awt::Key::NUM0 , "KEY_0" },
+ {css::awt::Key::NUM1 , "KEY_1" },
+ {css::awt::Key::NUM2 , "KEY_2" },
+ {css::awt::Key::NUM3 , "KEY_3" },
+ {css::awt::Key::NUM4 , "KEY_4" },
+ {css::awt::Key::NUM5 , "KEY_5" },
+ {css::awt::Key::NUM6 , "KEY_6" },
+ {css::awt::Key::NUM7 , "KEY_7" },
+ {css::awt::Key::NUM8 , "KEY_8" },
+ {css::awt::Key::NUM9 , "KEY_9" },
+ {css::awt::Key::A , "KEY_A" },
+ {css::awt::Key::B , "KEY_B" },
+ {css::awt::Key::C , "KEY_C" },
+ {css::awt::Key::D , "KEY_D" },
+ {css::awt::Key::E , "KEY_E" },
+ {css::awt::Key::F , "KEY_F" },
+ {css::awt::Key::G , "KEY_G" },
+ {css::awt::Key::H , "KEY_H" },
+ {css::awt::Key::I , "KEY_I" },
+ {css::awt::Key::J , "KEY_J" },
+ {css::awt::Key::K , "KEY_K" },
+ {css::awt::Key::L , "KEY_L" },
+ {css::awt::Key::M , "KEY_M" },
+ {css::awt::Key::N , "KEY_N" },
+ {css::awt::Key::O , "KEY_O" },
+ {css::awt::Key::P , "KEY_P" },
+ {css::awt::Key::Q , "KEY_Q" },
+ {css::awt::Key::R , "KEY_R" },
+ {css::awt::Key::S , "KEY_S" },
+ {css::awt::Key::T , "KEY_T" },
+ {css::awt::Key::U , "KEY_U" },
+ {css::awt::Key::V , "KEY_V" },
+ {css::awt::Key::W , "KEY_W" },
+ {css::awt::Key::X , "KEY_X" },
+ {css::awt::Key::Y , "KEY_Y" },
+ {css::awt::Key::Z , "KEY_Z" },
+ {css::awt::Key::F1 , "KEY_F1" },
+ {css::awt::Key::F2 , "KEY_F2" },
+ {css::awt::Key::F3 , "KEY_F3" },
+ {css::awt::Key::F4 , "KEY_F4" },
+ {css::awt::Key::F5 , "KEY_F5" },
+ {css::awt::Key::F6 , "KEY_F6" },
+ {css::awt::Key::F7 , "KEY_F7" },
+ {css::awt::Key::F8 , "KEY_F8" },
+ {css::awt::Key::F9 , "KEY_F9" },
+ {css::awt::Key::F10 , "KEY_F10" },
+ {css::awt::Key::F11 , "KEY_F11" },
+ {css::awt::Key::F12 , "KEY_F12" },
+ {css::awt::Key::F13 , "KEY_F13" },
+ {css::awt::Key::F14 , "KEY_F14" },
+ {css::awt::Key::F15 , "KEY_F15" },
+ {css::awt::Key::F16 , "KEY_F16" },
+ {css::awt::Key::F17 , "KEY_F17" },
+ {css::awt::Key::F18 , "KEY_F18" },
+ {css::awt::Key::F19 , "KEY_F19" },
+ {css::awt::Key::F20 , "KEY_F20" },
+ {css::awt::Key::F21 , "KEY_F21" },
+ {css::awt::Key::F22 , "KEY_F22" },
+ {css::awt::Key::F23 , "KEY_F23" },
+ {css::awt::Key::F24 , "KEY_F24" },
+ {css::awt::Key::F25 , "KEY_F25" },
+ {css::awt::Key::F26 , "KEY_F26" },
+ {css::awt::Key::DOWN , "KEY_DOWN" },
+ {css::awt::Key::UP , "KEY_UP" },
+ {css::awt::Key::LEFT , "KEY_LEFT" },
+ {css::awt::Key::RIGHT , "KEY_RIGHT" },
+ {css::awt::Key::HOME , "KEY_HOME" },
+ {css::awt::Key::END , "KEY_END" },
+ {css::awt::Key::PAGEUP , "KEY_PAGEUP" },
+ {css::awt::Key::PAGEDOWN , "KEY_PAGEDOWN" },
+ {css::awt::Key::RETURN , "KEY_RETURN" },
+ {css::awt::Key::ESCAPE , "KEY_ESCAPE" },
+ {css::awt::Key::TAB , "KEY_TAB" },
+ {css::awt::Key::BACKSPACE , "KEY_BACKSPACE" },
+ {css::awt::Key::SPACE , "KEY_SPACE" },
+ {css::awt::Key::INSERT , "KEY_INSERT" },
+ {css::awt::Key::DELETE , "KEY_DELETE" },
+ {css::awt::Key::ADD , "KEY_ADD" },
+ {css::awt::Key::SUBTRACT , "KEY_SUBTRACT" },
+ {css::awt::Key::MULTIPLY , "KEY_MULTIPLY" },
+ {css::awt::Key::DIVIDE , "KEY_DIVIDE" },
+ {css::awt::Key::POINT , "KEY_POINT" },
+ {css::awt::Key::COMMA , "KEY_COMMA" },
+ {css::awt::Key::LESS , "KEY_LESS" },
+ {css::awt::Key::GREATER , "KEY_GREATER" },
+ {css::awt::Key::EQUAL , "KEY_EQUAL" },
+ {css::awt::Key::OPEN , "KEY_OPEN" },
+ {css::awt::Key::CUT , "KEY_CUT" },
+ {css::awt::Key::COPY , "KEY_COPY" },
+ {css::awt::Key::PASTE , "KEY_PASTE" },
+ {css::awt::Key::UNDO , "KEY_UNDO" },
+ {css::awt::Key::REPEAT , "KEY_REPEAT" },
+ {css::awt::Key::FIND , "KEY_FIND" },
+ {css::awt::Key::PROPERTIES , "KEY_PROPERTIES" },
+ {css::awt::Key::FRONT , "KEY_FRONT" },
+ {css::awt::Key::CONTEXTMENU , "KEY_CONTEXTMENU"},
+ {css::awt::Key::HELP , "KEY_HELP" },
+ {css::awt::Key::MENU , "KEY_MENU" },
+ {css::awt::Key::HANGUL_HANJA , "KEY_HANGUL_HANJA"},
+ {css::awt::Key::DECIMAL , "KEY_DECIMAL" },
+ {css::awt::Key::TILDE , "KEY_TILDE" },
+ {css::awt::Key::QUOTELEFT , "KEY_QUOTELEFT" },
+ {css::awt::Key::BRACKETLEFT , "KEY_BRACKETLEFT" },
+ {css::awt::Key::BRACKETRIGHT , "KEY_BRACKETRIGHT" },
+ {css::awt::Key::SEMICOLON , "KEY_SEMICOLON" },
+ {0 , "" } // mark the end of this array!
+};
+
+//-----------------------------------------------
+KeyMapping::KeyMapping()
+{
+ sal_Int32 i = 0;
+ while(KeyIdentifierMap[i].Code != 0)
+ {
+ ::rtl::OUString sIdentifier = ::rtl::OUString::createFromAscii(KeyIdentifierMap[i].Identifier);
+ sal_Int16 nCode = KeyIdentifierMap[i].Code;
+
+ m_lIdentifierHash[sIdentifier] = nCode ;
+ m_lCodeHash [nCode] = sIdentifier;
+
+ ++i;
+ }
+}
+
+//-----------------------------------------------
+KeyMapping::~KeyMapping()
+{
+}
+
+//-----------------------------------------------
+sal_uInt16 KeyMapping::mapIdentifierToCode(const ::rtl::OUString& sIdentifier)
+ throw(css::lang::IllegalArgumentException)
+{
+ Identifier2CodeHash::const_iterator pIt = m_lIdentifierHash.find(sIdentifier);
+ if (pIt != m_lIdentifierHash.end())
+ return pIt->second;
+
+ // Its not well known identifier - but may be a pure key code formated as string ...
+ // Check and convert it!
+ sal_uInt16 nCode = 0;
+ if (!KeyMapping::impl_st_interpretIdentifierAsPureKeyCode(sIdentifier, nCode))
+ throw css::lang::IllegalArgumentException(
+ DECLARE_ASCII("Cant map given identifier to a valid key code value."),
+ css::uno::Reference< css::uno::XInterface >(),
+ 0);
+
+ return (sal_uInt16)nCode;
+}
+
+//-----------------------------------------------
+::rtl::OUString KeyMapping::mapCodeToIdentifier(sal_uInt16 nCode)
+{
+ Code2IdentifierHash::const_iterator pIt = m_lCodeHash.find(nCode);
+ if (pIt != m_lCodeHash.end())
+ return pIt->second;
+
+ // If we have no well known identifier - use the pure code value!
+ return ::rtl::OUString::valueOf((sal_Int32)nCode);
+}
+
+//-----------------------------------------------
+sal_Bool KeyMapping::impl_st_interpretIdentifierAsPureKeyCode(const ::rtl::OUString& sIdentifier,
+ sal_uInt16& rCode )
+{
+ sal_Int32 nCode = sIdentifier.toInt32();
+ if (nCode > 0)
+ {
+ rCode = (sal_uInt16)nCode;
+ return sal_True;
+ }
+
+ // 0 is normaly an error of the called method toInt32() ...
+ // But we must be aware, that the identifier is "0"!
+ rCode = 0;
+ return sIdentifier.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("0"));
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/accelerators/moduleacceleratorconfiguration.cxx b/framework/source/accelerators/moduleacceleratorconfiguration.cxx
new file mode 100644
index 000000000000..dca4a04c01ad
--- /dev/null
+++ b/framework/source/accelerators/moduleacceleratorconfiguration.cxx
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <accelerators/moduleacceleratorconfiguration.hxx>
+
+//_______________________________________________
+// own includes
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include "helper/mischelper.hxx"
+
+#include <acceleratorconst.h>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+
+//_______________________________________________
+// other includes
+
+#include <comphelper/sequenceashashmap.hxx>
+#include <vcl/svapp.hxx>
+
+#include <comphelper/configurationhelper.hxx>
+
+#include <com/sun/star/util/XChangesNotifier.hpp>
+
+#include <rtl/logfile.hxx>
+
+#include <rtl/logfile.h>
+
+//_______________________________________________
+// const
+
+namespace framework
+{
+
+//-----------------------------------------------
+// XInterface, XTypeProvider, XServiceInfo
+DEFINE_XINTERFACE_2(ModuleAcceleratorConfiguration ,
+ XCUBasedAcceleratorConfiguration ,
+ DIRECT_INTERFACE(css::lang::XServiceInfo) ,
+ DIRECT_INTERFACE(css::lang::XInitialization))
+
+DEFINE_XTYPEPROVIDER_2_WITH_BASECLASS(ModuleAcceleratorConfiguration,
+ XCUBasedAcceleratorConfiguration ,
+ css::lang::XServiceInfo ,
+ css::lang::XInitialization )
+
+DEFINE_XSERVICEINFO_MULTISERVICE(ModuleAcceleratorConfiguration ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_MODULEACCELERATORCONFIGURATION ,
+ IMPLEMENTATIONNAME_MODULEACCELERATORCONFIGURATION)
+
+DEFINE_INIT_SERVICE(ModuleAcceleratorConfiguration,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+ )
+
+//-----------------------------------------------
+ModuleAcceleratorConfiguration::ModuleAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR)
+ : XCUBasedAcceleratorConfiguration(xSMGR)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleAcceleratorConfiguration::ModuleAcceleratorConfiguration" );
+}
+
+//-----------------------------------------------
+ModuleAcceleratorConfiguration::~ModuleAcceleratorConfiguration()
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL ModuleAcceleratorConfiguration::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleAcceleratorConfiguration::initialize" );
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ ::comphelper::SequenceAsHashMap lArgs(lArguments);
+ m_sModule = lArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleIdentifier")), ::rtl::OUString());
+ m_sLocale = lArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Locale")) , ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("x-default")));
+
+ if (!m_sModule.getLength())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("The module dependend accelerator configuration service was initialized with an empty module identifier!")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ impl_ts_fillCache();
+}
+
+//-----------------------------------------------
+void ModuleAcceleratorConfiguration::impl_ts_fillCache()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleAcceleratorConfiguration::impl_ts_fillCache" );
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ ::rtl::OUString sModule = m_sModule;
+ m_sModuleCFG = m_sModule;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // get current office locale ... but dont cache it.
+ // Otherwise we must be listener on the configuration layer
+ // which seems to superflous for this small implementation .-)
+ ::comphelper::Locale aLocale = ::comphelper::Locale(m_sLocale);
+
+ // May be the current app module does not have any
+ // accelerator config? Handle it gracefully :-)
+ try
+ {
+ m_sGlobalOrModules = CFG_ENTRY_MODULES;
+ XCUBasedAcceleratorConfiguration::reload();
+
+ css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(m_xCfg, css::uno::UNO_QUERY_THROW);
+ m_xCfgListener = new WeakChangesListener(this);
+ xBroadcaster->addChangesListener(m_xCfgListener);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/accelerators/presethandler.cxx b/framework/source/accelerators/presethandler.cxx
new file mode 100644
index 000000000000..bcd4788790d0
--- /dev/null
+++ b/framework/source/accelerators/presethandler.cxx
@@ -0,0 +1,924 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <accelerators/presethandler.hxx>
+
+//_______________________________________________
+// own includes
+#include <classes/fwkresid.hxx>
+
+#include "classes/resource.hrc"
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+
+#include <com/sun/star/configuration/CorruptedUIConfigurationException.hpp>
+
+#include <com/sun/star/container/NoSuchElementException.hpp>
+
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/embed/ElementModes.hpp>
+
+#include <com/sun/star/embed/XTransactedObject.hpp>
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+//_______________________________________________
+// other includes
+#include <vcl/svapp.hxx>
+
+#include <rtl/ustrbuf.hxx>
+
+//_______________________________________________
+// const
+
+#define SUBSTORAGE_GLOBAL DECLARE_ASCII("global" )
+#define SUBSTORAGE_MODULES DECLARE_ASCII("modules")
+
+#define BASEPATH_SHARE_LAYER DECLARE_ASCII("UIConfig" )
+#define BASEPATH_USER_LAYER DECLARE_ASCII("UserConfig")
+
+#define RELPATH_SHARE_LAYER DECLARE_ASCII("soffice.cfg")
+#define RELPATH_USER_LAYER DECLARE_ASCII("soffice.cfg")
+// #define RELPATH_SHARE_LAYER DECLARE_ASCII("soffice.cfg/uiconfig.zip")
+// #define RELPATH_USER_LAYER DECLARE_ASCII("soffice.cfg/uiconfig.zip")
+
+#define FILE_EXTENSION DECLARE_ASCII(".xml")
+
+#define PATH_SEPERATOR DECLARE_ASCII("/")
+
+static const ::sal_Int32 ID_CORRUPT_UICONFIG_SHARE = 1;
+static const ::sal_Int32 ID_CORRUPT_UICONFIG_USER = 2;
+static const ::sal_Int32 ID_CORRUPT_UICONFIG_GENERAL = 3;
+
+//_______________________________________________
+// namespace
+
+namespace framework
+{
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::PRESET_DEFAULT()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("default");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::TARGET_CURRENT()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("current");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::RESOURCETYPE_MENUBAR()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("menubar");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::RESOURCETYPE_TOOLBAR()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("toolbar");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::RESOURCETYPE_ACCELERATOR()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("accelerator");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::RESOURCETYPE_STATUSBAR()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("statusbar");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+PresetHandler::PresetHandler(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase (&Application::GetSolarMutex() )
+ , m_xSMGR (xSMGR )
+ , m_aSharedStorages ( )
+ , m_lDocumentStorages(xSMGR )
+ , m_aLocale (::comphelper::Locale::X_NOTRANSLATE())
+{
+}
+
+//-----------------------------------------------
+PresetHandler::PresetHandler(const PresetHandler& rCopy)
+ : ThreadHelpBase (&Application::GetSolarMutex() )
+{
+ m_xSMGR = rCopy.m_xSMGR;
+ m_eConfigType = rCopy.m_eConfigType;
+ m_sResourceType = rCopy.m_sResourceType;
+ m_sModule = rCopy.m_sModule;
+ m_aSharedStorages = rCopy.m_aSharedStorages;
+ m_xWorkingStorageShare = rCopy.m_xWorkingStorageShare;
+ m_xWorkingStorageNoLang = rCopy.m_xWorkingStorageNoLang;
+ m_xWorkingStorageUser = rCopy.m_xWorkingStorageUser;
+ m_lPresets = rCopy.m_lPresets;
+ m_lTargets = rCopy.m_lTargets;
+ m_aLocale = rCopy.m_aLocale;
+ m_lDocumentStorages = rCopy.m_lDocumentStorages;
+ m_sRelPathShare = rCopy.m_sRelPathShare;
+ m_sRelPathNoLang = rCopy.m_sRelPathNoLang;
+ m_sRelPathUser = rCopy.m_sRelPathUser;
+}
+
+//-----------------------------------------------
+PresetHandler::~PresetHandler()
+{
+ m_xWorkingStorageShare.clear();
+ m_xWorkingStorageNoLang.clear();
+ m_xWorkingStorageUser.clear();
+
+ /* #i46497#
+ Dont call forgetCachedStorages() here for shared storages.
+ Because we opened different sub storages by using openPath().
+ And every already open path was reused and referenced (means it's
+ ref count was increased!)
+ So now we have to release our ref counts to these shared storages
+ only ... and not to free all used storages.
+ Otherwise we will disconnect all other open configuration access
+ objects which base on these storages.
+ */
+ m_aSharedStorages->m_lStoragesShare.closePath(m_sRelPathShare);
+ m_aSharedStorages->m_lStoragesUser.closePath (m_sRelPathUser );
+
+ /* On the other side closePath() is not needed for our special handled
+ document storage. Because it's not shared with others ... so we can
+ free it.
+ */
+ m_lDocumentStorages.forgetCachedStorages();
+}
+
+//-----------------------------------------------
+void PresetHandler::forgetCachedStorages()
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_eConfigType == E_DOCUMENT)
+ {
+ m_xWorkingStorageShare.clear();
+ m_xWorkingStorageNoLang.clear();
+ m_xWorkingStorageUser.clear();
+ }
+
+ m_lDocumentStorages.forgetCachedStorages();
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+::rtl::OUString lcl_getLocalizedMessage(::sal_Int32 nID)
+{
+ ::rtl::OUString sMessage(RTL_CONSTASCII_USTRINGPARAM("Unknown error."));
+
+ switch(nID)
+ {
+ case ID_CORRUPT_UICONFIG_SHARE :
+ sMessage = ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_SHARE )));
+ break;
+
+ case ID_CORRUPT_UICONFIG_USER :
+ sMessage = ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_USER )));
+ break;
+
+ case ID_CORRUPT_UICONFIG_GENERAL :
+ sMessage = ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_GENERAL )));
+ break;
+ }
+
+ return sMessage;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getOrCreateRootStorageShare()
+{
+ css::uno::Reference< css::embed::XStorage > xRoot = m_aSharedStorages->m_lStoragesShare.getRootStorage();
+ if (xRoot.is())
+ return xRoot;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::beans::XPropertySet > xPathSettings(
+ xSMGR->createInstance(SERVICENAME_PATHSETTINGS),
+ css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString sShareLayer;
+ xPathSettings->getPropertyValue(BASEPATH_SHARE_LAYER) >>= sShareLayer;
+
+ // "UIConfig" is a "multi path" ... use first part only here!
+ sal_Int32 nPos = sShareLayer.indexOf(';');
+ if (nPos > 0)
+ sShareLayer = sShareLayer.copy(0, nPos);
+
+ // Note: May be an user uses URLs without a final slash! Check it ...
+ nPos = sShareLayer.lastIndexOf('/');
+ if (nPos != sShareLayer.getLength()-1)
+ sShareLayer += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+
+ sShareLayer += RELPATH_SHARE_LAYER; // folder
+ /*
+ // TODO remove me!
+ // Attention: This is temp. workaround ... We create a temp. storage file
+ // based of a sytem directory. This must be used so, till the storage implementation
+ // can work on directories too.
+ */
+ css::uno::Sequence< css::uno::Any > lArgs(2);
+ lArgs[0] <<= sShareLayer;
+ lArgs[1] <<= css::embed::ElementModes::READ | css::embed::ElementModes::NOCREATE;
+
+ css::uno::Reference< css::lang::XSingleServiceFactory > xStorageFactory(xSMGR->createInstance(SERVICENAME_FILESYSTEMSTORAGEFACTORY) , css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::embed::XStorage > xStorage;
+
+ try
+ {
+ xStorage = css::uno::Reference< css::embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::configuration::CorruptedUIConfigurationException(
+ lcl_getLocalizedMessage(ID_CORRUPT_UICONFIG_SHARE),
+ css::uno::Reference< css::uno::XInterface >(),
+ ex.Message);
+ }
+
+ m_aSharedStorages->m_lStoragesShare.setRootStorage(xStorage);
+
+ return xStorage;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getOrCreateRootStorageUser()
+{
+ css::uno::Reference< css::embed::XStorage > xRoot = m_aSharedStorages->m_lStoragesUser.getRootStorage();
+ if (xRoot.is())
+ return xRoot;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::beans::XPropertySet > xPathSettings(
+ xSMGR->createInstance(SERVICENAME_PATHSETTINGS),
+ css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString sUserLayer;
+ xPathSettings->getPropertyValue(BASEPATH_USER_LAYER) >>= sUserLayer ;
+
+ // Note: May be an user uses URLs without a final slash! Check it ...
+ sal_Int32 nPos = sUserLayer.lastIndexOf('/');
+ if (nPos != sUserLayer.getLength()-1)
+ sUserLayer += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+
+ sUserLayer += RELPATH_USER_LAYER; // storage file
+
+ css::uno::Sequence< css::uno::Any > lArgs(2);
+ lArgs[0] <<= sUserLayer;
+ lArgs[1] <<= css::embed::ElementModes::READWRITE;
+
+ css::uno::Reference< css::lang::XSingleServiceFactory > xStorageFactory(xSMGR->createInstance(SERVICENAME_FILESYSTEMSTORAGEFACTORY) , css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::embed::XStorage > xStorage;
+
+ try
+ {
+ xStorage = css::uno::Reference< css::embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::configuration::CorruptedUIConfigurationException(
+ lcl_getLocalizedMessage(ID_CORRUPT_UICONFIG_USER),
+ css::uno::Reference< css::uno::XInterface >(),
+ ex.Message);
+ }
+
+ m_aSharedStorages->m_lStoragesUser.setRootStorage(xStorage);
+
+ return xStorage;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getWorkingStorageShare()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ return m_xWorkingStorageShare;
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getWorkingStorageUser()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ return m_xWorkingStorageUser;
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getParentStorageShare(const css::uno::Reference< css::embed::XStorage >& /*xChild*/)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xWorking = m_xWorkingStorageShare;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return m_aSharedStorages->m_lStoragesShare.getParentStorage(xWorking);
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getParentStorageUser(const css::uno::Reference< css::embed::XStorage >& /*xChild*/)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xWorking = m_xWorkingStorageUser;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return m_aSharedStorages->m_lStoragesUser.getParentStorage(xWorking);
+}
+
+//-----------------------------------------------
+void PresetHandler::connectToResource( PresetHandler::EConfigType eConfigType ,
+ const ::rtl::OUString& sResource ,
+ const ::rtl::OUString& sModule ,
+ const css::uno::Reference< css::embed::XStorage >& xDocumentRoot,
+ const ::comphelper::Locale& aLocale )
+{
+ // TODO free all current open storages!
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ m_eConfigType = eConfigType ;
+ m_sResourceType = sResource ;
+ m_sModule = sModule ;
+ m_aLocale = aLocale ;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::embed::XStorage > xShare;
+ css::uno::Reference< css::embed::XStorage > xNoLang;
+ css::uno::Reference< css::embed::XStorage > xUser;
+
+ // special case for documents
+ // use outside root storage, if we run in E_DOCUMENT mode!
+ if (eConfigType == E_DOCUMENT)
+ {
+ if (!xDocumentRoot.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("There is valid root storage, where the UI configuration can work on.")),
+ css::uno::Reference< css::uno::XInterface >());
+ m_lDocumentStorages.setRootStorage(xDocumentRoot);
+ xShare = xDocumentRoot;
+ xUser = xDocumentRoot;
+ }
+ else
+ {
+ xShare = getOrCreateRootStorageShare();
+ xUser = getOrCreateRootStorageUser();
+ }
+
+ // #...#
+ try
+ {
+
+ // a) inside share layer we should not create any new structures ... We jave to use
+ // existing ones only!
+ // b) inside user layer we can (SOFT mode!) but sometimes we shouldnt (HARD mode!)
+ // create new empty structures. We should preferr using of any existing structure.
+ sal_Int32 eShareMode = (css::embed::ElementModes::READ | css::embed::ElementModes::NOCREATE);
+ sal_Int32 eUserMode = (css::embed::ElementModes::READWRITE );
+
+ ::rtl::OUStringBuffer sRelPathBuf(1024);
+ ::rtl::OUString sRelPathShare;
+ ::rtl::OUString sRelPathNoLang;
+ ::rtl::OUString sRelPathUser;
+ switch(eConfigType)
+ {
+ case E_GLOBAL :
+ {
+ sRelPathBuf.append(SUBSTORAGE_GLOBAL);
+ sRelPathBuf.append(PATH_SEPERATOR );
+ sRelPathBuf.append(sResource );
+ sRelPathShare = sRelPathBuf.makeStringAndClear();
+ sRelPathUser = sRelPathShare;
+
+ xShare = impl_openPathIgnoringErrors(sRelPathShare, eShareMode, sal_True );
+ xUser = impl_openPathIgnoringErrors(sRelPathUser , eUserMode , sal_False);
+ }
+ break;
+
+ case E_MODULES :
+ {
+ sRelPathBuf.append(SUBSTORAGE_MODULES);
+ sRelPathBuf.append(PATH_SEPERATOR );
+ sRelPathBuf.append(sModule );
+ sRelPathBuf.append(PATH_SEPERATOR );
+ sRelPathBuf.append(sResource );
+ sRelPathShare = sRelPathBuf.makeStringAndClear();
+ sRelPathUser = sRelPathShare;
+
+ xShare = impl_openPathIgnoringErrors(sRelPathShare, eShareMode, sal_True );
+ xUser = impl_openPathIgnoringErrors(sRelPathUser , eUserMode , sal_False);
+ }
+ break;
+
+ case E_DOCUMENT :
+ {
+ // A document does not have a share layer in real.
+ // It has one layer only, and this one should be opened READ_WRITE.
+ // So we open the user layer here only and set the share layer equals to it .-)
+
+ sRelPathBuf.append(sResource);
+ sRelPathUser = sRelPathBuf.makeStringAndClear();
+ sRelPathShare = sRelPathUser;
+
+ try
+ {
+ xUser = m_lDocumentStorages.openPath(sRelPathUser , eUserMode );
+ xShare = xUser;
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { xShare.clear(); xUser.clear(); }
+ }
+ break;
+ }
+
+ // Non-localized global share
+ xNoLang = xShare;
+ sRelPathNoLang = sRelPathShare;
+
+ if (
+ (aLocale != ::comphelper::Locale::X_NOTRANSLATE()) && // localized level?
+ (eConfigType != E_DOCUMENT ) // no localization in document mode!
+ )
+ {
+ // First try to find the right localized set inside share layer.
+ // Fallbacks are allowed there.
+ ::comphelper::Locale aShareLocale = aLocale ;
+ ::rtl::OUString sLocalizedSharePath(sRelPathShare);
+ sal_Bool bAllowFallbacks = sal_True ;
+ xShare = impl_openLocalizedPathIgnoringErrors(sLocalizedSharePath, eShareMode, sal_True , aShareLocale, bAllowFallbacks);
+
+ // The try to locate the right sub dir inside user layer ... without using fallbacks!
+ // Normaly the corresponding sub dir should be created matching the specified locale.
+ // Because we allow creation of storages inside user layer by default.
+ ::comphelper::Locale aUserLocale = aLocale ;
+ ::rtl::OUString sLocalizedUserPath(sRelPathUser);
+ bAllowFallbacks = sal_False ;
+ xUser = impl_openLocalizedPathIgnoringErrors(sLocalizedUserPath, eUserMode , sal_False, aUserLocale, bAllowFallbacks);
+
+ sRelPathShare = sLocalizedSharePath;
+ sRelPathUser = sLocalizedUserPath ;
+ }
+
+ // read content of level 3 (presets, targets)
+ css::uno::Reference< css::container::XNameAccess > xAccess ;
+ css::uno::Sequence< ::rtl::OUString > lNames ;
+ const ::rtl::OUString* pNames ;
+ sal_Int32 c ;
+ sal_Int32 i ;
+ OUStringList lPresets;
+ OUStringList lTargets;
+
+ // read preset names of share layer
+ xAccess = css::uno::Reference< css::container::XNameAccess >(xShare, css::uno::UNO_QUERY);
+ if (xAccess.is())
+ {
+ lNames = xAccess->getElementNames();
+ pNames = lNames.getConstArray();
+ c = lNames.getLength();
+
+ for (i=0; i<c; ++i)
+ {
+ ::rtl::OUString sTemp = pNames[i];
+ sal_Int32 nPos = sTemp.indexOf(FILE_EXTENSION);
+ if (nPos > -1)
+ sTemp = sTemp.copy(0,nPos);
+ lPresets.push_back(sTemp);
+ }
+ }
+
+ // read preset names of user layer
+ xAccess = css::uno::Reference< css::container::XNameAccess >(xUser, css::uno::UNO_QUERY);
+ if (xAccess.is())
+ {
+ lNames = xAccess->getElementNames();
+ pNames = lNames.getConstArray();
+ c = lNames.getLength();
+
+ for (i=0; i<c; ++i)
+ {
+ ::rtl::OUString sTemp = pNames[i];
+ sal_Int32 nPos = sTemp.indexOf(FILE_EXTENSION);
+ if (nPos > -1)
+ sTemp = sTemp.copy(0,nPos);
+ lTargets.push_back(sTemp);
+ }
+ }
+
+ // SAFE -> ----------------------------------
+ aWriteLock.lock();
+
+ m_xWorkingStorageShare = xShare ;
+ m_xWorkingStorageNoLang= xNoLang;
+ m_xWorkingStorageUser = xUser ;
+ m_lPresets = lPresets;
+ m_lTargets = lTargets;
+ m_sRelPathShare = sRelPathShare;
+ m_sRelPathNoLang = sRelPathNoLang;
+ m_sRelPathUser = sRelPathUser;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::configuration::CorruptedUIConfigurationException(
+ lcl_getLocalizedMessage(ID_CORRUPT_UICONFIG_GENERAL),
+ css::uno::Reference< css::uno::XInterface >(),
+ ex.Message);
+ }
+}
+
+//-----------------------------------------------
+void PresetHandler::copyPresetToTarget(const ::rtl::OUString& sPreset,
+ const ::rtl::OUString& sTarget)
+{
+ // dont check our preset list, if element exists
+ // We try to open it and forward all errors to the user!
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xWorkingShare = m_xWorkingStorageShare;
+ css::uno::Reference< css::embed::XStorage > xWorkingNoLang= m_xWorkingStorageNoLang;
+ css::uno::Reference< css::embed::XStorage > xWorkingUser = m_xWorkingStorageUser ;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // e.g. module without any config data ?!
+ if (
+ (!xWorkingShare.is()) ||
+ (!xWorkingUser.is() )
+ )
+ {
+ return;
+ }
+
+ ::rtl::OUString sPresetFile(sPreset);
+ sPresetFile += FILE_EXTENSION;
+
+ ::rtl::OUString sTargetFile(sTarget);
+ sTargetFile += FILE_EXTENSION;
+
+ // remove existing elements before you try to copy the preset to that location ...
+ // Otherwise w will get an ElementExistException inside copyElementTo()!
+ css::uno::Reference< css::container::XNameAccess > xCheckingUser(xWorkingUser, css::uno::UNO_QUERY_THROW);
+ if (xCheckingUser->hasByName(sTargetFile))
+ xWorkingUser->removeElement(sTargetFile);
+
+ xWorkingShare->copyElementTo(sPresetFile, xWorkingUser, sTargetFile);
+
+ // If our storages work in transacted mode, we have
+ // to commit all changes from bottom to top!
+ commitUserChanges();
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::io::XStream > PresetHandler::openPreset(const ::rtl::OUString& sPreset,
+ sal_Bool bUseNoLangGlobal)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xFolder = bUseNoLangGlobal? m_xWorkingStorageNoLang: m_xWorkingStorageShare;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // e.g. module without any config data ?!
+ if (!xFolder.is())
+ return css::uno::Reference< css::io::XStream >();
+
+ ::rtl::OUString sFile(sPreset);
+ sFile += FILE_EXTENSION;
+
+ // inform user about errors (use original exceptions!)
+ css::uno::Reference< css::io::XStream > xStream = xFolder->openStreamElement(sFile, css::embed::ElementModes::READ);
+ return xStream;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::io::XStream > PresetHandler::openTarget(const ::rtl::OUString& sTarget ,
+ sal_Bool bCreateIfMissing)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xFolder = m_xWorkingStorageUser;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // e.g. module without any config data ?!
+ if (!xFolder.is())
+ return css::uno::Reference< css::io::XStream >();
+
+ ::rtl::OUString sFile(sTarget);
+ sFile += FILE_EXTENSION;
+
+ sal_Int32 nOpenMode = css::embed::ElementModes::READWRITE;
+ if (!bCreateIfMissing)
+ nOpenMode |= css::embed::ElementModes::NOCREATE;
+
+ // try it in read/write mode first and ignore errors.
+ css::uno::Reference< css::io::XStream > xStream;
+ try
+ {
+ xStream = xFolder->openStreamElement(sFile, nOpenMode);
+ return xStream;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { xStream.clear(); }
+
+ // try it readonly if it failed before.
+ // inform user about errors (use original exceptions!)
+ nOpenMode &= ~css::embed::ElementModes::WRITE;
+ xStream = xFolder->openStreamElement(sFile, nOpenMode);
+
+ return xStream;
+}
+
+//-----------------------------------------------
+void PresetHandler::commitUserChanges()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xWorking = m_xWorkingStorageUser;
+ EConfigType eCfgType = m_eConfigType;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // e.g. module without any config data ?!
+ if (!xWorking.is())
+ return;
+
+ ::rtl::OUString sPath;
+
+ switch(eCfgType)
+ {
+ case E_GLOBAL :
+ case E_MODULES :
+ {
+ sPath = m_aSharedStorages->m_lStoragesUser.getPathOfStorage(xWorking);
+ m_aSharedStorages->m_lStoragesUser.commitPath(sPath);
+ m_aSharedStorages->m_lStoragesUser.notifyPath(sPath);
+ }
+ break;
+
+ case E_DOCUMENT :
+ {
+ sPath = m_lDocumentStorages.getPathOfStorage(xWorking);
+ m_lDocumentStorages.commitPath(sPath);
+ m_lDocumentStorages.notifyPath(sPath);
+ }
+ break;
+ }
+}
+
+//-----------------------------------------------
+void PresetHandler::addStorageListener(IStorageListener* pListener)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ ::rtl::OUString sRelPath = m_sRelPathUser; // use user path ... because we dont work directly on the share layer!
+ EConfigType eCfgType = m_eConfigType;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (!sRelPath.getLength())
+ return;
+
+ switch(eCfgType)
+ {
+ case E_GLOBAL :
+ case E_MODULES :
+ {
+ m_aSharedStorages->m_lStoragesUser.addStorageListener(pListener, sRelPath);
+ }
+ break;
+
+ case E_DOCUMENT :
+ {
+ m_lDocumentStorages.addStorageListener(pListener, sRelPath);
+ }
+ break;
+ }
+}
+
+//-----------------------------------------------
+void PresetHandler::removeStorageListener(IStorageListener* pListener)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ ::rtl::OUString sRelPath = m_sRelPathUser; // use user path ... because we dont work directly on the share layer!
+ EConfigType eCfgType = m_eConfigType;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (!sRelPath.getLength())
+ return;
+
+ switch(eCfgType)
+ {
+ case E_GLOBAL :
+ case E_MODULES :
+ {
+ m_aSharedStorages->m_lStoragesUser.removeStorageListener(pListener, sRelPath);
+ }
+ break;
+
+ case E_DOCUMENT :
+ {
+ m_lDocumentStorages.removeStorageListener(pListener, sRelPath);
+ }
+ break;
+ }
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::impl_openPathIgnoringErrors(const ::rtl::OUString& sPath ,
+ sal_Int32 eMode ,
+ sal_Bool bShare)
+{
+ css::uno::Reference< css::embed::XStorage > xPath;
+ try
+ {
+ if (bShare)
+ xPath = m_aSharedStorages->m_lStoragesShare.openPath(sPath, eMode);
+ else
+ xPath = m_aSharedStorages->m_lStoragesUser.openPath(sPath, eMode);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { xPath.clear(); }
+ return xPath;
+}
+
+//-----------------------------------------------
+::std::vector< ::rtl::OUString >::const_iterator PresetHandler::impl_findMatchingLocalizedValue(const ::std::vector< ::rtl::OUString >& lLocalizedValues,
+ ::comphelper::Locale& aLocale ,
+ sal_Bool bAllowFallbacks )
+{
+ ::std::vector< ::rtl::OUString >::const_iterator pFound = lLocalizedValues.end();
+ if (bAllowFallbacks)
+ {
+ pFound = ::comphelper::Locale::getFallback(lLocalizedValues, aLocale.toISO());
+ }
+ else
+ {
+ for ( pFound = lLocalizedValues.begin();
+ pFound != lLocalizedValues.end() ;
+ ++pFound )
+ {
+ const ::rtl::OUString& sCheckISO = *pFound;
+ ::comphelper::Locale aCheckLocale(sCheckISO);
+ if (aCheckLocale.equals(aLocale))
+ break;
+ }
+ }
+
+ // if we found a valid locale ... take it over to our in/out parameter aLocale
+ if (pFound != lLocalizedValues.end())
+ {
+ const ::rtl::OUString& sISOLocale = *pFound;
+ aLocale.fromISO(sISOLocale);
+ }
+
+ return pFound;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::impl_openLocalizedPathIgnoringErrors(::rtl::OUString& sPath ,
+ sal_Int32 eMode ,
+ sal_Bool bShare ,
+ ::comphelper::Locale& aLocale ,
+ sal_Bool bAllowFallback)
+{
+ css::uno::Reference< css::embed::XStorage > xPath = impl_openPathIgnoringErrors(sPath, eMode, bShare);
+ ::std::vector< ::rtl::OUString > lSubFolders = impl_getSubFolderNames(xPath);
+ ::std::vector< ::rtl::OUString >::const_iterator pLocaleFolder = impl_findMatchingLocalizedValue(lSubFolders, aLocale, bAllowFallback);
+
+ // no fallback ... creation not allowed => no storage
+ if (
+ (pLocaleFolder == lSubFolders.end() ) &&
+ ((eMode & css::embed::ElementModes::NOCREATE) == css::embed::ElementModes::NOCREATE)
+ )
+ return css::uno::Reference< css::embed::XStorage >();
+
+ // it doesnt matter, if there is a locale fallback or not
+ // If creation of storages is allowed, we do it anyway.
+ // Otherwhise we have no acc config at all, which can make other trouble.
+ ::rtl::OUString sLocalizedPath;
+ sLocalizedPath = sPath;
+ sLocalizedPath += PATH_SEPERATOR;
+ if (pLocaleFolder != lSubFolders.end())
+ sLocalizedPath += *pLocaleFolder;
+ else
+ sLocalizedPath += aLocale.toISO();
+
+ css::uno::Reference< css::embed::XStorage > xLocalePath = impl_openPathIgnoringErrors(sLocalizedPath, eMode, bShare);
+
+ if (xLocalePath.is())
+ sPath = sLocalizedPath;
+ else
+ sPath = ::rtl::OUString();
+
+ return xLocalePath;
+}
+
+//-----------------------------------------------
+::std::vector< ::rtl::OUString > PresetHandler::impl_getSubFolderNames(const css::uno::Reference< css::embed::XStorage >& xFolder)
+{
+ css::uno::Reference< css::container::XNameAccess > xAccess(xFolder, css::uno::UNO_QUERY);
+ if (!xAccess.is())
+ return ::std::vector< ::rtl::OUString >();
+
+ ::std::vector< ::rtl::OUString > lSubFolders;
+ const css::uno::Sequence< ::rtl::OUString > lNames = xAccess->getElementNames();
+ const ::rtl::OUString* pNames = lNames.getConstArray();
+ sal_Int32 c = lNames.getLength();
+ sal_Int32 i = 0;
+
+ for (i=0; i<c; ++i)
+ {
+ try
+ {
+ if (xFolder->isStorageElement(pNames[i]))
+ lSubFolders.push_back(pNames[i]);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+ }
+
+ return lSubFolders;
+}
+
+//-----------------------------------------------
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/accelerators/storageholder.cxx b/framework/source/accelerators/storageholder.cxx
new file mode 100644
index 000000000000..858cc392de9f
--- /dev/null
+++ b/framework/source/accelerators/storageholder.cxx
@@ -0,0 +1,624 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <accelerators/storageholder.hxx>
+
+//===============================================
+// own includes
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <services.h>
+
+//===============================================
+// interface includes
+
+#include <com/sun/star/container/NoSuchElementException.hpp>
+
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <com/sun/star/embed/ElementModes.hpp>
+
+#include <com/sun/star/embed/XTransactedObject.hpp>
+
+#include <com/sun/star/embed/XPackageStructureCreator.hpp>
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+#include <com/sun/star/io/XSeekable.hpp>
+
+//===============================================
+// other includes
+#include <comphelper/processfactory.hxx>
+
+//===============================================
+// const
+
+#define PATH_SEPERATOR_ASCII "/"
+#define PATH_SEPERATOR_UNICODE ((sal_Unicode)'/')
+#define PATH_SEPERATOR ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(PATH_SEPERATOR_ASCII))
+
+//===============================================
+// namespace
+
+namespace framework
+{
+
+namespace css = ::com::sun::star;
+
+//-----------------------------------------------
+StorageHolder::StorageHolder()
+ : ThreadHelpBase( )
+ , m_xSMGR (::comphelper::getProcessServiceFactory())
+{
+}
+
+//-----------------------------------------------
+StorageHolder::StorageHolder(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase( )
+ , m_xSMGR (xSMGR)
+{
+}
+
+//-----------------------------------------------
+StorageHolder::~StorageHolder()
+{
+ // TODO implement me
+ // dispose/clear etcpp.
+}
+
+//-----------------------------------------------
+void StorageHolder::forgetCachedStorages()
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ TPath2StorageInfo::iterator pIt;
+ for ( pIt = m_lStorages.begin();
+ pIt != m_lStorages.end() ;
+ ++pIt )
+ {
+ TStorageInfo& rInfo = pIt->second;
+ // TODO think about listener !
+ rInfo.Storage.clear();
+ }
+ m_lStorages.clear();
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void StorageHolder::setRootStorage(const css::uno::Reference< css::embed::XStorage >& xRoot)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xRoot = xRoot;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > StorageHolder::getRootStorage() const
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ return m_xRoot;
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > StorageHolder::openPath(const ::rtl::OUString& sPath ,
+ sal_Int32 nOpenMode)
+{
+ ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
+ OUStringList lFolders = StorageHolder::impl_st_parsePath(sNormedPath);
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xParent = m_xRoot;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::embed::XStorage > xChild ;
+ ::rtl::OUString sRelPath;
+ OUStringList::const_iterator pIt ;
+
+ for ( pIt = lFolders.begin();
+ pIt != lFolders.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sChild = *pIt;
+ ::rtl::OUString sCheckPath (sRelPath);
+ sCheckPath += sChild;
+ sCheckPath += PATH_SEPERATOR;
+
+ // SAFE -> ------------------------------
+ aReadLock.lock();
+
+ // If we found an already open storage ... we must increase
+ // its use count. Otherwhise it will may be closed to early :-)
+ TPath2StorageInfo::iterator pCheck = m_lStorages.find(sCheckPath);
+ TStorageInfo* pInfo = 0;
+ if (pCheck != m_lStorages.end())
+ {
+ pInfo = &(pCheck->second);
+ ++(pInfo->UseCount);
+ xChild = pInfo->Storage;
+ }
+ else
+ {
+ aReadLock.unlock();
+ // <- SAFE ------------------------------
+
+ try
+ {
+ xChild = StorageHolder::openSubStorageWithFallback(xParent, sChild, nOpenMode, sal_True); // TODO think about delegating fallback decision to our own calli!
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception& exAny)
+ {
+ /* TODO URGENT!
+ in case we found some "already existing storages" on the path before and increased its UseCount ...
+ and now we will get an exception on creating a new sub storage ...
+ we must decrease all UseCounts, which was touched before. Otherwise these storages cant be closed!
+
+ Idea: Using of another structure member "PossibleUseCount" as vector of unique numbers.
+ Every thread use another unique number to identify all "owned candidates".
+ A flush method with the same unique number force increasing of the "UseCount" variable then
+ inside a synchronized block ...
+ */
+ throw exAny;
+ }
+
+ // SAFE -> ------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ pInfo = &(m_lStorages[sCheckPath]);
+ pInfo->Storage = xChild;
+ pInfo->UseCount = 1;
+ aWriteLock.unlock();
+ // <- SAFE ------------------------------
+ }
+
+ xParent = xChild;
+ sRelPath += sChild;
+ sRelPath += PATH_SEPERATOR;
+ }
+
+ // TODO think about return last storage as working storage ... but dont caching it inside this holder!
+ // => otherwhise the same storage is may be commit more then once.
+
+ return xChild;
+}
+
+//-----------------------------------------------
+StorageHolder::TStorageList StorageHolder::getAllPathStorages(const ::rtl::OUString& sPath)
+{
+ ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
+ OUStringList lFolders = StorageHolder::impl_st_parsePath(sNormedPath);
+
+ StorageHolder::TStorageList lStoragesOfPath;
+ ::rtl::OUString sRelPath ;
+ OUStringList::const_iterator pIt ;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ for ( pIt = lFolders.begin();
+ pIt != lFolders.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sChild = *pIt;
+ ::rtl::OUString sCheckPath (sRelPath);
+ sCheckPath += sChild;
+ sCheckPath += PATH_SEPERATOR;
+
+ TPath2StorageInfo::iterator pCheck = m_lStorages.find(sCheckPath);
+ if (pCheck == m_lStorages.end())
+ {
+ // at least one path element was not found
+ // Seems that this path isnt open ...
+ lStoragesOfPath.clear();
+ return lStoragesOfPath;
+ }
+
+ TStorageInfo& rInfo = pCheck->second;
+ lStoragesOfPath.push_back(rInfo.Storage);
+
+ sRelPath += sChild;
+ sRelPath += PATH_SEPERATOR;
+ }
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return lStoragesOfPath;
+}
+
+//-----------------------------------------------
+void StorageHolder::commitPath(const ::rtl::OUString& sPath)
+{
+ StorageHolder::TStorageList lStorages = getAllPathStorages(sPath);
+
+ css::uno::Reference< css::embed::XTransactedObject > xCommit;
+ StorageHolder::TStorageList::reverse_iterator pIt;
+ for ( pIt = lStorages.rbegin(); // order of commit is important ... otherwhise changes are not recognized!
+ pIt != lStorages.rend() ;
+ ++pIt )
+ {
+ xCommit = css::uno::Reference< css::embed::XTransactedObject >(*pIt, css::uno::UNO_QUERY);
+ if (!xCommit.is())
+ continue;
+ xCommit->commit();
+ }
+
+ // SAFE -> ------------------------------
+ ReadGuard aReadLock(m_aLock);
+ xCommit = css::uno::Reference< css::embed::XTransactedObject >(m_xRoot, css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE ------------------------------
+
+ if (xCommit.is())
+ xCommit->commit();
+}
+
+//-----------------------------------------------
+void StorageHolder::closePath(const ::rtl::OUString& rPath)
+{
+ ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(rPath);
+ OUStringList lFolders = StorageHolder::impl_st_parsePath(sNormedPath);
+
+ /* convert list of pathes in the following way:
+ [0] = "path_1" => "path_1
+ [1] = "path_2" => "path_1/path_2"
+ [2] = "path_3" => "path_1/path_2/path_3"
+ */
+ OUStringList::iterator pIt1 ;
+ ::rtl::OUString sParentPath;
+ for ( pIt1 = lFolders.begin();
+ pIt1 != lFolders.end() ;
+ ++pIt1 )
+ {
+ ::rtl::OUString sCurrentRelPath = sParentPath;
+ sCurrentRelPath += *pIt1;
+ sCurrentRelPath += PATH_SEPERATOR;
+ *pIt1 = sCurrentRelPath;
+ sParentPath = sCurrentRelPath;
+ }
+
+ // SAFE -> ------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ OUStringList::reverse_iterator pIt2;
+ for ( pIt2 = lFolders.rbegin();
+ pIt2 != lFolders.rend() ;
+ ++pIt2 )
+ {
+ ::rtl::OUString sPath = *pIt2;
+ TPath2StorageInfo::iterator pPath = m_lStorages.find(sPath);
+ if (pPath == m_lStorages.end())
+ continue; // ???
+
+ TStorageInfo& rInfo = pPath->second;
+ --rInfo.UseCount;
+ if (rInfo.UseCount < 1)
+ {
+ rInfo.Storage.clear();
+ m_lStorages.erase(pPath);
+ }
+ }
+
+ aReadLock.unlock();
+ // <- SAFE ------------------------------
+}
+
+//-----------------------------------------------
+void StorageHolder::notifyPath(const ::rtl::OUString& sPath)
+{
+ ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
+
+ // SAFE -> ------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ TPath2StorageInfo::iterator pIt1 = m_lStorages.find(sNormedPath);
+ if (pIt1 == m_lStorages.end())
+ return;
+
+ TStorageInfo& rInfo = pIt1->second;
+ TStorageListenerList::iterator pIt2;
+ for ( pIt2 = rInfo.Listener.begin();
+ pIt2 != rInfo.Listener.end() ;
+ ++pIt2 )
+ {
+ IStorageListener* pListener = *pIt2;
+ if (pListener)
+ pListener->changesOccurred(sNormedPath);
+ }
+
+ aReadLock.unlock();
+ // <- SAFE ------------------------------
+}
+
+//-----------------------------------------------
+void StorageHolder::addStorageListener( IStorageListener* pListener,
+ const ::rtl::OUString& sPath )
+{
+ ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
+
+ // SAFE -> ------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ TPath2StorageInfo::iterator pIt1 = m_lStorages.find(sNormedPath);
+ if (pIt1 == m_lStorages.end())
+ return;
+
+ TStorageInfo& rInfo = pIt1->second;
+ TStorageListenerList::iterator pIt2 = ::std::find(rInfo.Listener.begin(), rInfo.Listener.end(), pListener);
+ if (pIt2 == rInfo.Listener.end())
+ rInfo.Listener.push_back(pListener);
+
+ aReadLock.unlock();
+ // <- SAFE ------------------------------
+}
+
+//-----------------------------------------------
+void StorageHolder::removeStorageListener( IStorageListener* pListener,
+ const ::rtl::OUString& sPath )
+{
+ ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
+
+ // SAFE -> ------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ TPath2StorageInfo::iterator pIt1 = m_lStorages.find(sNormedPath);
+ if (pIt1 == m_lStorages.end())
+ return;
+
+ TStorageInfo& rInfo = pIt1->second;
+ TStorageListenerList::iterator pIt2 = ::std::find(rInfo.Listener.begin(), rInfo.Listener.end(), pListener);
+ if (pIt2 != rInfo.Listener.end())
+ rInfo.Listener.erase(pIt2);
+
+ aReadLock.unlock();
+ // <- SAFE ------------------------------
+}
+
+//-----------------------------------------------
+::rtl::OUString StorageHolder::getPathOfStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
+{
+ // SAFE -> ------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ TPath2StorageInfo::const_iterator pIt;
+ for ( pIt = m_lStorages.begin();
+ pIt != m_lStorages.end() ;
+ ++pIt )
+ {
+ const TStorageInfo& rInfo = pIt->second;
+ if (rInfo.Storage == xStorage)
+ break;
+ }
+
+ if (pIt == m_lStorages.end())
+ return ::rtl::OUString();
+
+ return pIt->first;
+
+ // <- SAFE ------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > StorageHolder::getParentStorage(const css::uno::Reference< css::embed::XStorage >& xChild)
+{
+ ::rtl::OUString sChildPath = getPathOfStorage(xChild);
+ return getParentStorage(sChildPath);
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > StorageHolder::getParentStorage(const ::rtl::OUString& sChildPath)
+{
+ // normed path = "a/b/c/" ... we search for "a/b/"
+ ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sChildPath);
+ OUStringList lFolders = StorageHolder::impl_st_parsePath(sNormedPath);
+ sal_Int32 c = lFolders.size();
+
+ // a) "" => - => no parent
+ // b) "a/b/c/" => "a/b/" => return storage "a/b/"
+ // c) "a/" => "" => return root !
+
+ // a)
+ if (c < 1)
+ return css::uno::Reference< css::embed::XStorage >();
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ // b)
+ if (c < 2)
+ return m_xRoot;
+
+ // c)
+ ::rtl::OUString sParentPath;
+ sal_Int32 i = 0;
+ for (i=0; i<c-1; ++i)
+ {
+ sParentPath += lFolders[i];
+ sParentPath += PATH_SEPERATOR;
+ }
+
+ TPath2StorageInfo::const_iterator pParent = m_lStorages.find(sParentPath);
+ if (pParent != m_lStorages.end())
+ return pParent->second.Storage;
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // ?
+ LOG_WARNING("StorageHolder::getParentStorage()", "Unexpected situation. Cached storage item seems to be wrong.")
+ return css::uno::Reference< css::embed::XStorage >();
+}
+
+//-----------------------------------------------
+void StorageHolder::operator=(const StorageHolder& rCopy)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ m_xSMGR = rCopy.m_xSMGR; // ???
+ m_xRoot = rCopy.m_xRoot;
+ m_lStorages = rCopy.m_lStorages;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > StorageHolder::openSubStorageWithFallback(const css::uno::Reference< css::embed::XStorage >& xBaseStorage ,
+ const ::rtl::OUString& sSubStorage ,
+ sal_Int32 eOpenMode ,
+ sal_Bool bAllowFallback)
+{
+ // a) try it first with user specified open mode
+ // ignore errors ... but save it for later use!
+ css::uno::Exception exResult;
+ try
+ {
+ css::uno::Reference< css::embed::XStorage > xSubStorage = xBaseStorage->openStorageElement(sSubStorage, eOpenMode);
+ if (xSubStorage.is())
+ return xSubStorage;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception& ex)
+ { exResult = ex; }
+
+ // b) readonly already tried? => forward last error!
+ if (
+ (!bAllowFallback ) || // fallback allowed ?
+ ((eOpenMode & css::embed::ElementModes::WRITE) != css::embed::ElementModes::WRITE) // fallback possible ?
+ )
+ throw exResult;
+
+ // c) try it readonly
+ // dont catch exception here! Outside code whish to know, if operation failed or not.
+ // Otherwhise they work on NULL references ...
+ sal_Int32 eNewMode = (eOpenMode & ~css::embed::ElementModes::WRITE);
+ css::uno::Reference< css::embed::XStorage > xSubStorage = xBaseStorage->openStorageElement(sSubStorage, eNewMode);
+ if (xSubStorage.is())
+ return xSubStorage;
+
+ // d) no chance!
+ LOG_WARNING("openSubStorageWithFallback()", "Unexpected situation! Got no exception for missing storage ...")
+ return css::uno::Reference< css::embed::XStorage >();
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::io::XStream > StorageHolder::openSubStreamWithFallback(const css::uno::Reference< css::embed::XStorage >& xBaseStorage ,
+ const ::rtl::OUString& sSubStream ,
+ sal_Int32 eOpenMode ,
+ sal_Bool bAllowFallback)
+{
+ // a) try it first with user specified open mode
+ // ignore errors ... but save it for later use!
+ css::uno::Exception exResult;
+ try
+ {
+ css::uno::Reference< css::io::XStream > xSubStream = xBaseStorage->openStreamElement(sSubStream, eOpenMode);
+ if (xSubStream.is())
+ return xSubStream;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception& ex)
+ { exResult = ex; }
+
+ // b) readonly already tried? => forward last error!
+ if (
+ (!bAllowFallback ) || // fallback allowed ?
+ ((eOpenMode & css::embed::ElementModes::WRITE) != css::embed::ElementModes::WRITE) // fallback possible ?
+ )
+ throw exResult;
+
+ // c) try it readonly
+ // dont catch exception here! Outside code whish to know, if operation failed or not.
+ // Otherwhise they work on NULL references ...
+ sal_Int32 eNewMode = (eOpenMode & ~css::embed::ElementModes::WRITE);
+ css::uno::Reference< css::io::XStream > xSubStream = xBaseStorage->openStreamElement(sSubStream, eNewMode);
+ if (xSubStream.is())
+ return xSubStream;
+
+ // d) no chance!
+ LOG_WARNING("openSubStreamWithFallbacks()", "Unexpected situation! Got no exception for missing stream ...")
+ return css::uno::Reference< css::io::XStream >();
+}
+
+//-----------------------------------------------
+::rtl::OUString StorageHolder::impl_st_normPath(const ::rtl::OUString& sPath)
+{
+ // path must start without "/" but end with "/"!
+
+ ::rtl::OUString sNormedPath = sPath;
+
+ // "/bla" => "bla" && "/" => "" (!)
+ if (sNormedPath.indexOf(PATH_SEPERATOR) == 0)
+ sNormedPath += sNormedPath.copy(1);
+
+ // "/" => "" || "" => "" ?
+ if (sNormedPath.getLength() < 1)
+ return ::rtl::OUString();
+
+ // "bla" => "bla/"
+ if (sNormedPath.lastIndexOf(PATH_SEPERATOR) != (sNormedPath.getLength()-1))
+ sNormedPath += PATH_SEPERATOR;
+
+ return sNormedPath;
+}
+
+//-----------------------------------------------
+OUStringList StorageHolder::impl_st_parsePath(const ::rtl::OUString& sPath)
+{
+ OUStringList lToken;
+ sal_Int32 i = 0;
+ while (sal_True)
+ {
+ ::rtl::OUString sToken = sPath.getToken(0, PATH_SEPERATOR_UNICODE, i);
+ if (i < 0)
+ break;
+ lToken.push_back(sToken);
+ }
+ return lToken;
+}
+
+//===============================================
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/application/framework.cxx b/framework/source/application/framework.cxx
new file mode 100644
index 000000000000..f7e82da58413
--- /dev/null
+++ b/framework/source/application/framework.cxx
@@ -0,0 +1,257 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <helper/oinstanceprovider.hxx>
+#include <classes/servicemanager.hxx>
+#include <macros/debug.hxx>
+#include <osl/process.h>
+
+#include <defines.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/frame/XFrameLoader.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/XLoadEventListener.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XFrames.hpp>
+
+#include <com/sun/star/connection/XConnection.hpp>
+
+#include <com/sun/star/bridge/XBridgeFactory.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svtools/unoiface.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::rtl ;
+using namespace ::comphelper ;
+using namespace ::framework ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::frame ;
+using namespace ::com::sun::star::awt ;
+using namespace ::com::sun::star::beans ;
+using namespace ::com::sun::star::util ;
+using namespace ::com::sun::star::connection ;
+using namespace ::com::sun::star::bridge ;
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+#define APPLICATIONNAME "FrameWork"
+#define COMMANDARGUMENT_PLUGIN DECLARE_ASCII("-plugin" )
+#define NAME_PLUGINBRIDGE DECLARE_ASCII("mozilla plugin bridge" )
+#define PROTOCOL_PLUGINBRIDGE DECLARE_ASCII("urp" )
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+/*-************************************************************************************************************//**
+ @short normal application
+ @descr An instance of these class can be a normal node in frame tree only. The highest level to be allowed is 3!
+ On 1 stand the desktop himself as the only one, on 2 are all tasks present ... and then comes frames only.
+ A frame support influencing of his subtree, find of subframes, activate- and deactivate-mechanism as well as
+ set/get of a frame window, component or controller.
+
+ @implements XInterface
+ XTypeProvider
+ XServiceInfo
+ XFramesSupplier
+ XFrame
+ XComponent
+ XStatusIndicatorSupplier
+ XDispatchProvider
+ XDispatchProviderInterception
+ XBrowseHistoryRegistry
+ XLoadEventListener
+ XEventListener
+ XWindowListener
+ XTopWindowListener
+ [ XDebugging, if TEST_TREE is defined! ]
+ @base OMutexMember
+ OWeakObject
+
+ @devstatus deprecated
+*//*-*************************************************************************************************************/
+class FrameWork : public Application
+{
+ //-------------------------------------------------------------------------------------------------------------
+ // public methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ public:
+ void Main();
+
+ private:
+ void impl_analyzeCommandArguments();
+
+ private:
+ sal_Bool m_bUsePlugIn ;
+
+}; // class FrameWork
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// global variables
+//_________________________________________________________________________________________________________________
+
+FrameWork aFrameWork ;
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// private methods
+//*****************************************************************************************************************
+void FrameWork::impl_analyzeCommandArguments()
+{
+ // First reset all member variables which present states of incoming arguments!
+ m_bUsePlugIn = sal_False; // depends from "/plugin"
+
+ // Then step over all given arguments and search for supported one.
+ OUString sArgument ;
+ sal_uInt32 nCount = osl_getCommandArgCount();
+ for ( sal_uInt32 nArgument=0; nArgument<nCount; ++nArgument )
+ {
+ // If extraction of current argument successfull ...
+ if ( osl_getCommandArg( nArgument, &sArgument.pData ) == osl_Process_E_None )
+ {
+ // ... search for matching with supported values.
+ if ( sArgument == COMMANDARGUMENT_PLUGIN )
+ {
+ // We found "/plugin" => set internal equivalent.
+ m_bUsePlugIn = sal_True;
+ }
+ }
+ }
+}
+
+//_________________________________________________________________________________________________________________
+// main
+//_________________________________________________________________________________________________________________
+
+void FrameWork::Main()
+{
+ //-------------------------------------------------------------------------------------------------------------
+ // a) Initialize ouer application
+
+ // Analyze command arguments.
+ impl_analyzeCommandArguments();
+
+ // Create new global servicemanager.
+ ServiceManager aManager;
+ Reference< XMultiServiceFactory > xGlobalServiceManager = aManager.getGlobalUNOServiceManager();
+
+ if ( xGlobalServiceManager.is() == sal_True )
+ {
+ // If it was successful - set in as static value in UNOTOOLS!
+ setProcessServiceFactory( xGlobalServiceManager );
+
+ //---------------------------------------------------------------------------------------------------------
+ // b) Create root of ouer frame tree
+
+ // Create top of frame hierarchy - the desktop.
+ Reference< XDesktop > xDesktop( xGlobalServiceManager->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
+ // Safe impossible cases
+ // We need the desktop for working.
+ LOG_ASSERT( !(xDesktop.is()==sal_False), "FrameWork::Main()\nCan't instanciate desktop!Servicename unknown?\n" )
+
+ //---------------------------------------------------------------------------------------------------------
+ // c) Initialize connection to possible PlugIn dll.
+
+// OPipeConnection removed, connection to plugin now uses acceptor service
+ //---------------------------------------------------------------------------------------------------------
+ // d) Initialize new task with a HTML-URL in it.
+
+ // Cast desktop to right interface to do this.
+ Reference< XDispatchProvider > xDispatchProvider( xDesktop, UNO_QUERY );
+ // Safe impossible cases.
+ // Desktop MUST support these interface!
+ LOG_ASSERT( !(xDispatchProvider.is()==sal_False), "FrameWork::Main()\nDesktop don't support XDispatchProvider interface.\n" )
+ if ( xDispatchProvider.is() == sal_True )
+ {
+ // Build URL ...
+ OUString sURL( RTL_CONSTASCII_USTRINGPARAM( "file://e|/dokumentation/Documentation/projekte/services/inimanager/inimanager/index.html" ));
+ URL aURL;
+ aURL.Complete = sURL;
+ // ... and dispatch it.
+ Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aURL, FRAMETYPE_BLANK, 0 );
+ xDispatch->dispatch( aURL, Sequence< PropertyValue >() );
+
+ // Use special feature of desktop service and log current tree state in file.
+// LOG_TREE( xDesktop )
+
+ // Build URL ...
+ sURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "file://d|/menu.htm" ));
+ aURL.Complete = sURL;
+ // ... and dispatch it.
+ xDispatch = xDispatchProvider->queryDispatch( aURL, FRAMETYPE_BLANK, 0 );
+ xDispatch->dispatch( aURL, Sequence< PropertyValue >() );
+
+ // Use special feature of desktop service and log current tree state in file.
+// LOG_TREE( xDesktop )
+ }
+
+ // Set running-mode for application.
+ Execute();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/application/login.cxx b/framework/source/application/login.cxx
new file mode 100644
index 000000000000..45a2d0329ff8
--- /dev/null
+++ b/framework/source/application/login.cxx
@@ -0,0 +1,296 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <services/logindialog.hxx>
+#include <classes/servicemanager.hxx>
+#include <macros/generic.hxx>
+#include <macros/debug.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/awt/XDialog.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <osl/process.h>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <stdio.h>
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+#define TEMPFILE_ENCODING RTL_TEXTENCODING_UTF8 // encoding of written temp. ascii file
+#define LOGIN_RDB DECLARE_ASCII("login.rdb") // name of our own registry file - neccessary to create own servicemanager
+#define SEPERATOR "\n" // used to seperate parts in temp. file
+
+#define MINARGUMENTCOUNT 1 // count of min. required arguments
+#define ARGUMENTFOUND 0 // OUString::compareTo returns 0 if searched string match given one
+#define ARGUMENTLENGTH 3 // length of fixed part of any argument to detect it easier!
+
+#define ARGUMENT_TEMPFILE DECLARE_ASCII("-f=") // we support "-f=c:\temp\test.txt" to write dialog data in temp. file
+#define ARGUMENT_DIALOGPARENT DECLARE_ASCII("-p=") // we support "-p=36748322" as window handle of parent for vcl dialog
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::rtl ;
+using namespace ::comphelper ;
+using namespace ::framework ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::awt ;
+using namespace ::com::sun::star::beans ;
+
+//_________________________________________________________________________________________________________________
+// defines
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+/*-************************************************************************************************************//**
+ @short implement command application to show login dialog and save his information in temp. file!
+ @descr We need this temp. file to share informations between our dialog and different processes, which
+ can't use vcl directly. Caller of this executable give us the file name as an argument - we save
+ all informations in it - caller can read it and MUST delete temp. file.
+ This is neccessary for example; to hide the password!
+
+ @implements -
+
+ @base Application
+*//*-*************************************************************************************************************/
+class LoginApplication : public Application
+{
+ //*************************************************************************************************************
+ // public methods
+ //*************************************************************************************************************
+ public:
+ void Main();
+
+ //*************************************************************************************************************
+ // private methods
+ //*************************************************************************************************************
+ private:
+ void impl_parseCommandline(); // search supported arguments on command line
+
+ //*************************************************************************************************************
+ // private variables
+ //*************************************************************************************************************
+ private:
+ OString m_sTempFile ; // name of temp. file in system notation
+ sal_Int32 m_nParentHandle ; // a parent window handle for used vcl dialog
+
+}; // class LoginApplication
+
+//_________________________________________________________________________________________________________________
+// global variables
+//_________________________________________________________________________________________________________________
+
+LoginApplication gLoginApplication;
+
+//_________________________________________________________________________________________________________________
+// main
+//_________________________________________________________________________________________________________________
+
+void LoginApplication::Main()
+{
+ // Init global uno servicemanager.
+ ServiceManager aManager;
+ Reference< XMultiServiceFactory > xServiceManager = aManager.getSharedUNOServiceManager( DECLARE_ASCII("login.rdb") );
+ LOG_ASSERT( !(xServiceManager.is()==sal_False), "LoginApplication::Main()\nCould not create uno service manager!\n" )
+
+ // Parse command line and set found arguments on application member.
+ impl_parseCommandline();
+ LOG_ASSERT( !(m_sTempFile.getLength()<1), "LoginApplication::Main()\nWrong or missing argument for temp. file detected!\n" )
+
+ // Try to get neccessary dialog service.
+ // By the way - cast it to interface XPropertySet too - we need it later.
+ // (define SERVICENAME... comes from defines.hxx!)
+ Reference< XDialog > xLoginDialog( xServiceManager->createInstance( SERVICENAME_LOGINDIALOG ), UNO_QUERY );
+ Reference< XPropertySet > xPropertySet( xLoginDialog , UNO_QUERY );
+
+ // Work with valid ressources only!
+ // Otherwise do nothing ...
+ if (
+ ( xLoginDialog.is() == sal_True ) &&
+ ( xPropertySet.is() == sal_True ) &&
+ ( m_sTempFile.getLength() > 0 )
+ )
+ {
+ // Exist a parent window? YES => set right property.
+ if( m_nParentHandle != 0 )
+ {
+ Any aParentWindow;
+ aParentWindow <<= m_nParentHandle;
+ xPropertySet->setPropertyValue( PROPERTYNAME_PARENTWINDOW, aParentWindow );
+ }
+
+ Any aConnectionType;
+ aConnectionType <<= PROPERTYNAME_HTTPS;
+ xPropertySet->setPropertyValue( PROPERTYNAME_CONNECTIONTYPE, aConnectionType );
+
+ // Show login dialog and get decision of user.
+ sal_Bool bDecision = (sal_Bool)(xLoginDialog->execute());
+
+ OUString sUserName ;
+ OUString sPassword ;
+ OUString sServer ;
+ OUString sConnectionType ;
+ sal_Int32 nPort=0 ; // We need this default if follow "if"-statement "failed"!
+
+ // If user say "OK" ... get values from dialog.
+ // If user say "NO" ... leave it. Then we save empty informations later ...
+ if( bDecision == sal_True )
+ {
+ // defines PROPERTYNAME... comes from logindialog.hxx!
+ xPropertySet->getPropertyValue( PROPERTYNAME_USERNAME ) >>= sUserName ;
+ xPropertySet->getPropertyValue( PROPERTYNAME_PASSWORD ) >>= sPassword ;
+ xPropertySet->getPropertyValue( PROPERTYNAME_SERVER ) >>= sServer ;
+ xPropertySet->getPropertyValue( PROPERTYNAME_CONNECTIONTYPE ) >>= sConnectionType ;
+ if( sConnectionType.getLength() > 0 )
+ {
+ xPropertySet->getPropertyValue( sConnectionType ) >>= nPort;
+ }
+ }
+
+ // Build string for output.
+ // At this point it doesnt matter if information exist or not!
+ // Format of output: "<decision> [0|1] SEPERATOR
+ // <username> [string] SEPERATOR
+ // <password> [string] SEPERATOR
+ // <servername> [string] SEPERATOR
+ // <port> [int] SEPERATOR"
+ OUStringBuffer sBuffer( 1000 );
+
+ if( bDecision == sal_True )
+ {
+ sBuffer.appendAscii( "1" );
+ }
+ else
+ {
+ sBuffer.appendAscii( "0" );
+ }
+ sBuffer.appendAscii ( SEPERATOR );
+ sBuffer.append ( sUserName );
+ sBuffer.appendAscii ( SEPERATOR );
+ sBuffer.append ( sPassword );
+ sBuffer.appendAscii ( SEPERATOR );
+ sBuffer.append ( sServer );
+ sBuffer.appendAscii ( SEPERATOR );
+ sBuffer.append ( sConnectionType );
+ sBuffer.appendAscii ( SEPERATOR );
+ sBuffer.append ( nPort );
+ sBuffer.appendAscii ( SEPERATOR );
+
+ // Write informations in temp. file.
+ // If given file name isnt valid ... caller will have a problem!!!
+ // If fil already exist (That's out of specification!!!) we overwrite it everytime.
+ FILE* pFile = fopen( m_sTempFile.getStr(), "w" );
+ LOG_ASSERT( !(pFile==NULL), "LoginApplication::Main()\nCould not open file!\n" );
+ if( pFile != NULL )
+ {
+ OString sEncodedOut = U2B_ENC( sBuffer.makeStringAndClear(), TEMPFILE_ENCODING );
+ fprintf( pFile, sEncodedOut.getStr() );
+ fclose ( pFile );
+ }
+ }
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void LoginApplication::impl_parseCommandline()
+{
+ // Step over all arguments, search for supported ones and try to get his values.
+ // Set it on our member. Caller of this method must control setted values.
+
+ sal_uInt32 nCount = osl_getCommandArgCount();
+ sal_uInt32 nArgument = 0 ;
+ OUString sArgument ;
+ OUString sValue ;
+
+ // Warn programmer if argument count isnt ok!
+ LOG_ASSERT( !(nCount!=MINARGUMENTCOUNT), "LoginApplication::impl_parseCommandline()\nWrong argument count detected!\n" )
+
+ // Reset all possible argument variables to defaults if someone is missing.
+ m_sTempFile = OString();
+ m_nParentHandle = 0 ;
+
+ // Step over all arguments ...
+ for( nArgument=0; nArgument<nCount; ++nArgument )
+ {
+ // .. but work with valid ones only!
+ // Don't check values here. Caller of this method must decide between wrong and allowed values!
+ osl_getCommandArg( nArgument, &sArgument.pData );
+
+ //_____________________________________________________________________________________________________
+ // Look for "-f=<temp. file name>"
+ if( sArgument.compareTo( ARGUMENT_TEMPFILE, ARGUMENTLENGTH ) == ARGUMENTFOUND )
+ {
+ sValue = sArgument.copy( ARGUMENTLENGTH );
+ m_sTempFile = U2B(sValue);
+ }
+ else
+ //_____________________________________________________________________________________________________
+ // Look for "-p=<parent window handle>"
+ if( sArgument.compareTo( ARGUMENT_DIALOGPARENT, ARGUMENTLENGTH ) == ARGUMENTFOUND )
+ {
+ sValue = sArgument.copy( ARGUMENTLENGTH );
+ m_nParentHandle = sValue.toInt32();
+ }
+ }
+
+ // Parent window handle is an optional argument ... but should be used mostly!
+ // Warn programmer.
+ LOG_ASSERT( !(m_nParentHandle==0), "Login.exe\nYou should give me a parent window handle!\n" )
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/classes/droptargetlistener.cxx b/framework/source/classes/droptargetlistener.cxx
new file mode 100644
index 000000000000..e56725288813
--- /dev/null
+++ b/framework/source/classes/droptargetlistener.cxx
@@ -0,0 +1,256 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <classes/droptargetlistener.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <targets.h>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <svtools/transfer.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <sot/filelist.hxx>
+
+#include <osl/file.hxx>
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+
+DropTargetListener::DropTargetListener( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory,
+ const css::uno::Reference< css::frame::XFrame >& xFrame )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , m_xFactory ( xFactory )
+ , m_xTargetFrame ( xFrame )
+ , m_pFormats ( new DataFlavorExVector )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+DropTargetListener::~DropTargetListener()
+{
+ m_xTargetFrame = css::uno::WeakReference< css::frame::XFrame >();
+ m_xFactory = css::uno::Reference< css::lang::XMultiServiceFactory >();
+ delete m_pFormats;
+ m_pFormats = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::disposing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
+{
+ m_xTargetFrame = css::uno::WeakReference< css::frame::XFrame >();
+ m_xFactory = css::uno::Reference< css::lang::XMultiServiceFactory >();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::drop( const css::datatransfer::dnd::DropTargetDropEvent& dtde ) throw( css::uno::RuntimeException )
+{
+ const sal_Int8 nAction = dtde.DropAction;
+
+ try
+ {
+ if ( css::datatransfer::dnd::DNDConstants::ACTION_NONE != nAction )
+ {
+ TransferableDataHelper aHelper( dtde.Transferable );
+ sal_Bool bFormatFound = sal_False;
+ FileList aFileList;
+
+ // at first check filelist format
+ if ( aHelper.GetFileList( SOT_FORMAT_FILE_LIST, aFileList ) )
+ {
+ sal_uLong i, nCount = aFileList.Count();
+ for ( i = 0; i < nCount; ++i )
+ implts_OpenFile( aFileList.GetFile(i) );
+ bFormatFound = sal_True;
+ }
+
+ // then, if necessary, the file format
+ String aFilePath;
+ if ( !bFormatFound && aHelper.GetString( SOT_FORMAT_FILE, aFilePath ) )
+ implts_OpenFile( aFilePath );
+ }
+ dtde.Context->dropComplete( css::datatransfer::dnd::DNDConstants::ACTION_NONE != nAction );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) throw( css::uno::RuntimeException )
+{
+ try
+ {
+ implts_BeginDrag( dtdee.SupportedDataFlavors );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ dragOver( dtdee );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dragExit( const css::datatransfer::dnd::DropTargetEvent& ) throw( css::uno::RuntimeException )
+{
+ try
+ {
+ implts_EndDrag();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dragOver( const css::datatransfer::dnd::DropTargetDragEvent& dtde ) throw( css::uno::RuntimeException )
+{
+ try
+ {
+ sal_Bool bAccept = ( implts_IsDropFormatSupported( SOT_FORMAT_FILE ) ||
+ implts_IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) );
+
+ if ( !bAccept )
+ dtde.Context->rejectDrag();
+ else
+ dtde.Context->acceptDrag( css::datatransfer::dnd::DNDConstants::ACTION_COPY );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dropActionChanged( const css::datatransfer::dnd::DropTargetDragEvent& ) throw( css::uno::RuntimeException )
+{
+}
+
+void DropTargetListener::implts_BeginDrag( const css::uno::Sequence< css::datatransfer::DataFlavor >& rSupportedDataFlavors )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ m_pFormats->clear();
+ TransferableDataHelper::FillDataFlavorExVector(rSupportedDataFlavors,*m_pFormats);
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+void DropTargetListener::implts_EndDrag()
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ m_pFormats->clear();
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+sal_Bool DropTargetListener::implts_IsDropFormatSupported( SotFormatStringId nFormat )
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ DataFlavorExVector::iterator aIter( m_pFormats->begin() ), aEnd( m_pFormats->end() );
+ sal_Bool bRet = sal_False;
+
+ while ( aIter != aEnd )
+ {
+ if ( nFormat == (*aIter++).mnSotId )
+ {
+ bRet = sal_True;
+ aIter = aEnd;
+ }
+ }
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return bRet;
+}
+
+void DropTargetListener::implts_OpenFile( const String& rFilePath )
+{
+ String aFileURL;
+ if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFilePath, aFileURL ) )
+ aFileURL = rFilePath;
+
+ ::osl::FileStatus aStatus( FileStatusMask_FileURL );
+ ::osl::DirectoryItem aItem;
+ if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
+ ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
+ aFileURL = aStatus.getFileURL();
+
+ // open file
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XFrame > xTargetFrame( m_xTargetFrame.get() , css::uno::UNO_QUERY );
+ css::uno::Reference< css::util::XURLTransformer > xParser ( m_xFactory->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY );
+ aReadLock.unlock();
+ /* } SAFE */
+ if (xTargetFrame.is() && xParser.is())
+ {
+ css::util::URL aURL;
+ aURL.Complete = aFileURL;
+ xParser->parseStrict(aURL);
+
+ css::uno::Reference < css::frame::XDispatchProvider > xProvider( xTargetFrame, css::uno::UNO_QUERY );
+ css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch( aURL, SPECIALTARGET_DEFAULT, 0 );
+ if ( xDispatcher.is() )
+ xDispatcher->dispatch( aURL, css::uno::Sequence < css::beans::PropertyValue >() );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/classes/framecontainer.cxx b/framework/source/classes/framecontainer.cxx
new file mode 100644
index 000000000000..f692029371b2
--- /dev/null
+++ b/framework/source/classes/framecontainer.cxx
@@ -0,0 +1,401 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <classes/framecontainer.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+/**-***************************************************************************************************************
+ @short initialize an empty container
+ @descr The container will be empty then - special features (e.g. the async quit mechanism) are disabled.
+
+ @threadsafe not neccessary - its not a singleton
+ @modified 01.07.2002 14:42,as96863
+ *****************************************************************************************************************/
+FrameContainer::FrameContainer()
+ // initialize base classes first.
+ // Order is neccessary for right initilization of his and OUR member ... m_aLock
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+/*DEPRECATEME
+ , m_bAsyncQuit ( sal_False ) // default must be "disabled"!
+ , m_aAsyncCall ( LINK( this, FrameContainer, implts_asyncQuit ) )
+*/
+{
+}
+
+/**-***************************************************************************************************************
+ @short deinitialize may a filled container
+ @descr Special features (if the currently are running) will be dsiabled and we free all used other ressources.
+
+ @threadsafe not neccessary - its not a singleton
+ @modified 01.07.2002 14:43,as96863
+ *****************************************************************************************************************/
+FrameContainer::~FrameContainer()
+{
+ // Don't forget to free memory!
+ m_aContainer.clear();
+ m_xActiveFrame.clear();
+}
+
+/**-***************************************************************************************************************
+ @short append a new frame to the container
+ @descr We accept the incoming frame only, if it is a valid reference and dosnt exist already.
+
+ @param xFrame
+ frame, which should be added to this container
+ Must be a valid reference.
+
+ @threadsafe yes
+ @modified 01.07.2002 14:44,as96863
+ *****************************************************************************************************************/
+void FrameContainer::append( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ if (xFrame.is() && ! exist(xFrame))
+ {
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_aContainer.push_back( xFrame );
+ aWriteLock.unlock();
+ /* } SAFE */
+ }
+}
+
+/**-***************************************************************************************************************
+ @short remove a frame from the container
+ @descr In case we remove the last frame and our internal special feature (the async quit mechanism)
+ was enabled by the desktop instance, we start it.
+
+ @param xFrame
+ frame, which should be deleted from this container
+ Must be a valid reference.
+
+ @threadsafe yes
+ @modified 01.07.2002 14:52,as96863
+ *****************************************************************************************************************/
+void FrameContainer::remove( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ /* SAFE { */
+ // write lock neccessary for follwing erase()!
+ WriteGuard aWriteLock( m_aLock );
+
+ TFrameIterator aSearchedItem = ::std::find( m_aContainer.begin(), m_aContainer.end(), xFrame );
+ if (aSearchedItem!=m_aContainer.end())
+ {
+ m_aContainer.erase( aSearchedItem );
+
+ // If removed frame was the current active frame - reset state variable.
+ if (m_xActiveFrame==xFrame)
+ m_xActiveFrame = css::uno::Reference< css::frame::XFrame >();
+
+ // We don't need the write lock any longer ...
+ // downgrade to read access.
+ aWriteLock.downgrade();
+ }
+
+ aWriteLock.unlock();
+ // } SAFE
+}
+
+/**-***************************************************************************************************************
+ @short check if the given frame currently exist inside the container
+ @descr -
+
+ @param xFrame
+ reference to the queried frame
+
+ @return <TRUE/> if frame is oart of this container
+ <FALSE/> otherwhise
+
+ @threadsafe yes
+ @modified 01.07.2002 14:55,as96863
+ *****************************************************************************************************************/
+sal_Bool FrameContainer::exist( const css::uno::Reference< css::frame::XFrame >& xFrame ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ return( ::std::find( m_aContainer.begin(), m_aContainer.end(), xFrame ) != m_aContainer.end() );
+ /* } SAFE */
+}
+
+/**-***************************************************************************************************************
+ @short delete all existing items of the container
+ @descr -
+
+ @threadsafe yes
+ @modified 01.07.2002 15:00,as96863
+ *****************************************************************************************************************/
+void FrameContainer::clear()
+{
+ // SAFE {
+ WriteGuard aWriteLock( m_aLock );
+
+ // Clear the container ...
+ m_aContainer.clear();
+ // ... and don't forget to reset the active frame.
+ // Its an reference to a valid container-item.
+ // But no container item => no active frame!
+ m_xActiveFrame = css::uno::Reference< css::frame::XFrame >();
+
+ aWriteLock.unlock();
+ // } SAFE
+}
+
+/**-***************************************************************************************************************
+ @short returns count of all current existing frames
+ @descr -
+
+ @deprecated This value can't be guaranteed for multithreading environments.
+ So it will be marked as deprecated and should be replaced by "getAllElements()".
+
+ @return the count of existing container items
+
+ @threadsafe yes
+ @modified 01.07.2002 15:00,as96863
+ *****************************************************************************************************************/
+sal_uInt32 FrameContainer::getCount() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ return( (sal_uInt32)m_aContainer.size() );
+ /* } SAFE */
+}
+
+/**-***************************************************************************************************************
+ @short returns one item of this container
+ @descr -
+
+ @deprecated This value can't be guaranteed for multithreading environments.
+ So it will be marked as deprecated and should be replaced by "getAllElements()".
+
+ @param nIndex
+ a valud between 0 and (getCount()-1) to adress one container item
+
+ @return a reference to a frame inside the container, which match with given index
+
+ @threadsafe yes
+ @modified 01.07.2002 15:03,as96863
+ *****************************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > FrameContainer::operator[]( sal_uInt32 nIndex ) const
+{
+
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ try
+ {
+ // Get element form container WITH automatic test of ranges!
+ // If index not valid, a out_of_range exception is thrown.
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ xFrame = m_aContainer.at( nIndex );
+ aReadLock.unlock();
+ /* } SAFE */
+ }
+ catch( std::out_of_range& )
+ {
+ // The index is not valid for current container-content - we must handle this case!
+ // We can return the default value ...
+ LOG_EXCEPTION( "FrameContainer::operator[]", "Exception catched ...", DECLARE_ASCII("::std::out_of_range") )
+ }
+ return xFrame;
+}
+
+/**-***************************************************************************************************************
+ @short returns a snapshot of all currently existing frames inside this container
+ @descr Should be used to replace the deprecated functions getCount()/operator[]!
+
+ @return a list of all frame refrences inside this container
+
+ @threadsafe yes
+ @modified 01.07.2002 15:09,as96863
+ *****************************************************************************************************************/
+css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > FrameContainer::getAllElements() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+
+ sal_Int32 nPosition = 0;
+ css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > lElements ( (sal_uInt32)m_aContainer.size() );
+ for (TConstFrameIterator pItem=m_aContainer.begin(); pItem!=m_aContainer.end(); ++pItem)
+ lElements[nPosition++] = *pItem;
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return lElements;
+}
+
+/**-***************************************************************************************************************
+ @short set the given frame as the new active one inside this container
+ @descr We accept this frame only, if it's already a part of this container.
+
+ @param xFrame
+ reference to the new active frame
+ Must be a valid reference and already part of this container.
+
+ @threadsafe yes
+ @modified 01.07.2002 15:11,as96863
+ *****************************************************************************************************************/
+void FrameContainer::setActive( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ if ( !xFrame.is() || exist(xFrame) )
+ {
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_xActiveFrame = xFrame;
+ aWriteLock.unlock();
+ /* } SAFE */
+ }
+}
+
+/**-***************************************************************************************************************
+ @short return sthe current active frame of this container
+ @descr Value can be null in case the frame was removed from the container and nobody
+ from outside decide which of all others should be the new one ...
+
+ @return a reference to the current active frame
+ Value can be NULL!
+
+ @threadsafe yes
+ @modified 01.07.2002 15:11,as96863
+ *****************************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > FrameContainer::getActive() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ return m_xActiveFrame;
+ /* } SAFE */
+}
+
+/**-***************************************************************************************************************
+ @short implements a simple search based on current container items
+ @descr It can be used for findFrame() and implements a deep down search.
+
+ @param sName
+ target name, which is searched
+
+ @return reference to the found frame or NULL if not.
+
+ @threadsafe yes
+ @modified 01.07.2002 15:22,as96863
+ *****************************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > FrameContainer::searchOnAllChildrens( const ::rtl::OUString& sName ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+
+ // Step over all child frames. But if direct child isn't the right one search on his children first - before
+ // you go to next direct child of this container!
+ css::uno::Reference< css::frame::XFrame > xSearchedFrame;
+ for( TConstFrameIterator pIterator=m_aContainer.begin(); pIterator!=m_aContainer.end(); ++pIterator )
+ {
+ if ((*pIterator)->getName()==sName)
+ {
+ xSearchedFrame = *pIterator;
+ break;
+ }
+ else
+ {
+ xSearchedFrame = (*pIterator)->findFrame( sName, css::frame::FrameSearchFlag::CHILDREN );
+ if (xSearchedFrame.is())
+ break;
+ }
+ }
+ aReadLock.unlock();
+ /* } SAFE */
+ return xSearchedFrame;
+}
+
+/**-***************************************************************************************************************
+ @short implements a simple search based on current container items
+ @descr It can be used for findFrame() and search on members of this container only!
+
+ @param sName
+ target name, which is searched
+
+ @return reference to the found frame or NULL if not.
+
+ @threadsafe yes
+ @modified 01.07.2002 15:22,as96863
+ *****************************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > FrameContainer::searchOnDirectChildrens( const ::rtl::OUString& sName ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+
+ css::uno::Reference< css::frame::XFrame > xSearchedFrame;
+ for( TConstFrameIterator pIterator=m_aContainer.begin(); pIterator!=m_aContainer.end(); ++pIterator )
+ {
+ if ((*pIterator)->getName()==sName)
+ {
+ xSearchedFrame = *pIterator;
+ break;
+ }
+ }
+ aReadLock.unlock();
+ /* } SAFE */
+ return xSearchedFrame;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/classes/fwktabwindow.cxx b/framework/source/classes/fwktabwindow.cxx
new file mode 100644
index 000000000000..3c3cd7d21bff
--- /dev/null
+++ b/framework/source/classes/fwktabwindow.cxx
@@ -0,0 +1,412 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <classes/fwktabwindow.hxx>
+#include "framework.hrc"
+#include <classes/fwkresid.hxx>
+
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XContainerWindowEventHandler.hpp>
+#include <com/sun/star/awt/XContainerWindowProvider.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/stream.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/bitmap.hxx>
+#include <vcl/image.hxx>
+#include <vcl/msgbox.hxx>
+
+const ::rtl::OUString SERVICENAME_WINPROVIDER(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.ContainerWindowProvider"));
+const ::rtl::OUString EXTERNAL_EVENT(RTL_CONSTASCII_USTRINGPARAM("external_event"));
+const ::rtl::OUString BACK_METHOD(RTL_CONSTASCII_USTRINGPARAM("back"));
+const ::rtl::OUString INITIALIZE_METHOD(RTL_CONSTASCII_USTRINGPARAM("initialize"));
+const ::rtl::OUString OK_METHOD(RTL_CONSTASCII_USTRINGPARAM("ok"));
+
+using namespace ::com::sun::star;
+
+namespace framework
+{
+
+// class FwkTabControl ---------------------------------------------------
+FwkTabControl::FwkTabControl( Window* pParent, const ResId& rResId ) :
+
+ TabControl( pParent, rResId )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabControl::BroadcastEvent( sal_uLong nEvent )
+{
+ if ( VCLEVENT_TABPAGE_ACTIVATE == nEvent || VCLEVENT_TABPAGE_DEACTIVATE == nEvent )
+ ImplCallEventListeners( nEvent, (void*)(sal_uIntPtr)GetCurPageId() );
+ else
+ {
+ DBG_ERRORFILE( "FwkTabControl::BroadcastEvent(): illegal event" );
+ }
+}
+
+// class FwkTabPage ------------------------------------------------
+
+FwkTabPage::FwkTabPage(
+ Window* pParent, const rtl::OUString& rPageURL,
+ const css::uno::Reference< css::awt::XContainerWindowEventHandler >& rEventHdl,
+ const css::uno::Reference< css::awt::XContainerWindowProvider >& rProvider ) :
+
+ TabPage( pParent, WB_DIALOGCONTROL | WB_TABSTOP | WB_CHILDDLGCTRL ),
+
+ m_sPageURL ( rPageURL ),
+ m_xEventHdl ( rEventHdl ),
+ m_xWinProvider ( rProvider )
+
+{
+}
+
+// -----------------------------------------------------------------------
+
+FwkTabPage::~FwkTabPage()
+{
+ Hide();
+ DeactivatePage();
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabPage::CreateDialog()
+{
+ try
+ {
+ uno::Reference< uno::XInterface > xHandler;
+ if ( m_xEventHdl.is() )
+ xHandler = m_xEventHdl;
+
+ uno::Reference< awt::XWindowPeer > xParent( VCLUnoHelper::GetInterface( this ), uno::UNO_QUERY );
+ m_xPage = uno::Reference < awt::XWindow >(
+ m_xWinProvider->createContainerWindow(
+ m_sPageURL, rtl::OUString(), xParent, xHandler ), uno::UNO_QUERY );
+
+ uno::Reference< awt::XControl > xPageControl( m_xPage, uno::UNO_QUERY );
+ if ( xPageControl.is() )
+ {
+ uno::Reference< awt::XWindowPeer > xWinPeer( xPageControl->getPeer() );
+ if ( xWinPeer.is() )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( xWinPeer );
+ if ( pWindow )
+ pWindow->SetStyle( pWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL );
+ }
+ }
+
+ CallMethod( INITIALIZE_METHOD );
+ }
+ catch ( lang::IllegalArgumentException& )
+ {
+ DBG_ERRORFILE( "FwkTabPage::CreateDialog(): illegal argument" );
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERRORFILE( "FwkTabPage::CreateDialog(): exception of XDialogProvider2::createContainerWindow()" );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool FwkTabPage::CallMethod( const rtl::OUString& rMethod )
+{
+ sal_Bool bRet = sal_False;
+ if ( m_xEventHdl.is() )
+ {
+ try
+ {
+ bRet = m_xEventHdl->callHandlerMethod( m_xPage, uno::makeAny( rMethod ), EXTERNAL_EVENT );
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabPage::ActivatePage()
+{
+ TabPage::ActivatePage();
+
+ if ( !m_xPage.is() )
+ CreateDialog();
+
+ if ( m_xPage.is() )
+ {
+ Resize ();
+ m_xPage->setVisible( sal_True );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabPage::DeactivatePage()
+{
+ TabPage::DeactivatePage();
+
+ if ( m_xPage.is() )
+ m_xPage->setVisible( sal_False );
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabPage::Resize()
+{
+ if ( m_xPage.is () )
+ {
+ Size aSize = GetSizePixel();
+
+ m_xPage->setPosSize( 0, 0, aSize.Width()-1 , aSize.Height()-1, awt::PosSize::POSSIZE );
+ }
+}
+
+// class FwkTabWindow ---------------------------------------------
+
+FwkTabWindow::FwkTabWindow( Window* pParent ) :
+
+ Window( pParent, FwkResId( WIN_TABWINDOW ) ),
+
+ m_aTabCtrl ( this, FwkResId( TC_TABCONTROL ) )
+{
+ uno::Reference < lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ m_xWinProvider = uno::Reference < awt::XContainerWindowProvider >(
+ xFactory->createInstance( SERVICENAME_WINPROVIDER ), uno::UNO_QUERY );
+
+ SetPaintTransparent(true);
+
+ m_aTabCtrl.SetActivatePageHdl( LINK( this, FwkTabWindow, ActivatePageHdl ) );
+ m_aTabCtrl.SetDeactivatePageHdl( LINK( this, FwkTabWindow, DeactivatePageHdl ) );
+ m_aTabCtrl.Show();
+}
+
+// -----------------------------------------------------------------------
+
+FwkTabWindow::~FwkTabWindow()
+{
+ ClearEntryList();
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabWindow::ClearEntryList()
+{
+ TabEntryList::const_iterator pIt;
+ for ( pIt = m_TabList.begin();
+ pIt != m_TabList.end();
+ ++pIt )
+ {
+ delete *pIt;
+ }
+
+ m_TabList.clear();
+}
+
+// -----------------------------------------------------------------------
+
+bool FwkTabWindow::RemoveEntry( sal_Int32 nIndex )
+{
+ TabEntryList::iterator pIt;
+ for ( pIt = m_TabList.begin();
+ pIt != m_TabList.end();
+ ++pIt )
+ {
+ if ( (*pIt)->m_nIndex == nIndex )
+ break;
+ }
+
+ // remove entry from vector
+ if ( pIt != m_TabList.end())
+ {
+ m_TabList.erase(pIt);
+ return true;
+ }
+ else
+ return false;
+}
+
+// -----------------------------------------------------------------------
+TabEntry* FwkTabWindow::FindEntry( sal_Int32 nIndex ) const
+{
+ TabEntry* pEntry = NULL;
+
+ TabEntryList::const_iterator pIt;
+ for ( pIt = m_TabList.begin();
+ pIt != m_TabList.end();
+ ++pIt )
+ {
+ if ( (*pIt)->m_nIndex == nIndex )
+ {
+ pEntry = *pIt;
+ break;
+ }
+ }
+
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( FwkTabWindow, ActivatePageHdl, TabControl *, EMPTYARG )
+{
+ const sal_uInt16 nId = m_aTabCtrl.GetCurPageId();
+ FwkTabPage* pTabPage = static_cast< FwkTabPage* >( m_aTabCtrl.GetTabPage( nId ) );
+ if ( !pTabPage )
+ {
+ TabEntry* pEntry = FindEntry( nId );
+ if ( pEntry )
+ {
+ pTabPage = new FwkTabPage( &m_aTabCtrl, pEntry->m_sPageURL, pEntry->m_xEventHdl, m_xWinProvider );
+ pEntry->m_pPage = pTabPage;
+ m_aTabCtrl.SetTabPage( nId, pTabPage );
+ pTabPage->Show();
+ pTabPage->ActivatePage();
+ }
+ } else {
+ pTabPage->ActivatePage();
+ }
+ m_aTabCtrl.BroadcastEvent( VCLEVENT_TABPAGE_ACTIVATE );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( FwkTabWindow, DeactivatePageHdl, TabControl *, EMPTYARG )
+{
+ m_aTabCtrl.BroadcastEvent( VCLEVENT_TABPAGE_DEACTIVATE );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( FwkTabWindow, CloseHdl, PushButton *, EMPTYARG )
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabWindow::AddEventListener( const Link& rEventListener )
+{
+ m_aTabCtrl.AddEventListener( rEventListener );
+}
+
+void FwkTabWindow::RemoveEventListener( const Link& rEventListener )
+{
+ m_aTabCtrl.RemoveEventListener( rEventListener );
+}
+
+// -----------------------------------------------------------------------
+
+FwkTabPage* FwkTabWindow::AddTabPage( sal_Int32 nIndex, const uno::Sequence< beans::NamedValue >& rProperties )
+{
+ ::rtl::OUString sTitle, sToolTip, sPageURL;
+ uno::Reference< css::awt::XContainerWindowEventHandler > xEventHdl;
+ uno::Reference< graphic::XGraphic > xImage;
+ bool bDisabled = false;
+
+ sal_Int32 i = 0, nLen = rProperties.getLength();
+ for ( i = 0; i < nLen; ++i )
+ {
+ beans::NamedValue aValue = rProperties[i];
+ ::rtl::OUString sName = aValue.Name;
+
+ if ( sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Title")) )
+ aValue.Value >>= sTitle;
+ else if ( sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ToolTip")) )
+ aValue.Value >>= sToolTip;
+ else if ( sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("PageURL")) )
+ aValue.Value >>= sPageURL;
+ else if ( sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("EventHdl")) )
+ aValue.Value >>= xEventHdl;
+ else if ( sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Image")) )
+ aValue.Value >>= xImage;
+ else if ( sName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Disabled")) )
+ aValue.Value >>= bDisabled;
+ }
+
+ TabEntry* pEntry = new TabEntry( nIndex, sPageURL, xEventHdl );
+ m_TabList.push_back( pEntry );
+ sal_uInt16 nIdx = static_cast< sal_uInt16 >( nIndex );
+ m_aTabCtrl.InsertPage( nIdx, sTitle );
+ if ( sToolTip.getLength() > 0 )
+ m_aTabCtrl.SetHelpText( nIdx, sToolTip );
+ if ( xImage.is() )
+ m_aTabCtrl.SetPageImage( nIdx, Image( xImage ) );
+ if ( bDisabled )
+ m_aTabCtrl.EnablePage( nIdx, false );
+
+ return pEntry->m_pPage;
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabWindow::ActivatePage( sal_Int32 nIndex )
+{
+ m_aTabCtrl.SetCurPageId( static_cast< sal_uInt16 >( nIndex ) );
+ ActivatePageHdl( &m_aTabCtrl );
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabWindow::RemovePage( sal_Int32 nIndex )
+{
+ TabEntry* pEntry = FindEntry(nIndex);
+ if ( pEntry )
+ {
+ m_aTabCtrl.RemovePage( static_cast< sal_uInt16 >( nIndex ) );
+ if (RemoveEntry(nIndex))
+ delete pEntry;
+ }
+}
+
+// -----------------------------------------------------------------------
+void FwkTabWindow::Resize()
+{
+ Size aPageSize = GetSizePixel();
+ m_aTabCtrl.SetTabPageSizePixel( aPageSize );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/classes/fwlresid.cxx b/framework/source/classes/fwlresid.cxx
new file mode 100644
index 000000000000..99836e48f256
--- /dev/null
+++ b/framework/source/classes/fwlresid.cxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "classes/fwlresid.hxx"
+#include <tools/string.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+#include <rtl/strbuf.hxx>
+
+namespace framework
+{
+
+ResMgr* FwlResId::GetResManager()
+{
+ static ResMgr* pResMgr = NULL;
+
+ if ( !pResMgr )
+ {
+ SolarMutexGuard aSolarGuard;
+ pResMgr = ResMgr::CreateResMgr("fwe");
+ }
+
+ return pResMgr;
+}
+
+// -----------------------------------------------------------------------
+
+FwlResId::FwlResId( sal_uInt16 nId ) :
+ ResId( nId, *FwlResId::GetResManager() )
+{
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/classes/menumanager.cxx b/framework/source/classes/menumanager.cxx
new file mode 100644
index 000000000000..80519d57987a
--- /dev/null
+++ b/framework/source/classes/menumanager.cxx
@@ -0,0 +1,1055 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <classes/menumanager.hxx>
+#include <framework/menuconfiguration.hxx>
+#include <framework/bmkmenu.hxx>
+#include <framework/addonmenu.hxx>
+#include <framework/imageproducer.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include "framework/addonsoptions.hxx"
+#include <classes/fwkresid.hxx>
+#include <services.h>
+#include "classes/resource.hrc"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/util/XStringWidth.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <comphelper/processfactory.hxx>
+
+#include <comphelper/extract.hxx>
+#include <svtools/menuoptions.hxx>
+#include <unotools/historyoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/localfilehelper.hxx>
+
+#include <toolkit/unohlp.hxx>
+#include <tools/urlobj.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/file.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+
+
+class StringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
+{
+ public:
+ StringLength() {}
+ virtual ~StringLength() {}
+
+ // XStringWidth
+ sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
+ throw (::com::sun::star::uno::RuntimeException)
+ {
+ return aString.getLength();
+ }
+};
+
+namespace framework
+{
+
+// special menu ids/command ids for dynamic popup menus
+#define SID_SFX_START 5000
+#define SID_NEWDOCDIRECT (SID_SFX_START + 537)
+#define SID_AUTOPILOTMENU (SID_SFX_START + 1381)
+#define SID_PICKLIST (SID_SFX_START + 510)
+#define SID_MDIWINDOWLIST (SID_SFX_START + 610)
+#define SID_ADDONLIST (SID_SFX_START + 1677)
+#define SID_HELPMENU (SID_SFX_START + 410)
+
+#define SFX_REFERER_USER "private:user"
+
+#define aSlotNewDocDirect "slot:5537"
+#define aSlotAutoPilot "slot:6381"
+
+#define aSpecialFileMenu "file"
+#define aSpecialWindowMenu "window"
+#define aSlotSpecialFileMenu "slot:5510"
+#define aSlotSpecialWindowMenu "slot:5610"
+#define aSlotSpecialToolsMenu "slot:6677"
+
+// special uno commands for picklist and window list
+#define aSpecialFileCommand "PickList"
+#define aSpecialWindowCommand "WindowList"
+
+const ::rtl::OUString UNO_COMMAND( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
+
+MenuManager::MenuManager(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ REFERENCE< XFRAME >& rFrame, Menu* pMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
+:
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ mxServiceFactory(xServiceFactory)
+{
+ m_bActive = sal_False;
+ m_bDeleteMenu = bDelete;
+ m_bDeleteChildren = bDeleteChildren;
+ m_pVCLMenu = pMenu;
+ m_xFrame = rFrame;
+ m_bInitialized = sal_False;
+ m_bIsBookmarkMenu = sal_False;
+ SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)this )->acquire();
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ m_bShowMenuImages = rSettings.GetUseImagesInMenus();
+
+ sal_Int32 nAddonsURLPrefixLength = ADDONSPOPUPMENU_URL_PREFIX.getLength();
+
+
+ sal_uInt16 nItemCount = pMenu->GetItemCount();
+ m_aMenuItemHandlerVector.reserve(nItemCount);
+ ::rtl::OUString aItemCommand;
+ for ( sal_uInt16 i = 0; i < nItemCount; i++ )
+ {
+ sal_uInt16 nItemId = FillItemCommand(aItemCommand,pMenu, i );
+ bool bShowMenuImages( m_bShowMenuImages );
+
+ // overwrite the show icons on menu option?
+ if (!bShowMenuImages)
+ {
+ MenuItemBits nBits = pMenu->GetItemBits( nItemId );
+ bShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
+ }
+
+ PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nItemId );
+ if ( pPopupMenu )
+ {
+ AddMenu(pPopupMenu,aItemCommand,nItemId,bDeleteChildren,bDeleteChildren);
+ if (! (( aItemCommand.getLength() > nAddonsURLPrefixLength ) &&
+ ( aItemCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 )) )
+ {
+
+ // Create addon popup menu if there exist elements and this is the tools popup menu
+ if (( nItemId == SID_ADDONLIST ||
+ aItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSlotSpecialToolsMenu)) ) &&
+ AddonMenuManager::HasAddonMenuElements() )
+ {
+ sal_uInt16 nCount = 0;
+ AddonMenu* pSubMenu = AddonMenuManager::CreateAddonMenu( rFrame );
+ if ( pSubMenu && ( pSubMenu->GetItemCount() > 0 ))
+ {
+ if ( pPopupMenu->GetItemType( nCount-1 ) != MENUITEM_SEPARATOR )
+ pPopupMenu->InsertSeparator();
+
+ // Use resource to load popup menu title
+ String aAddonsStrRes = String( FwkResId( STR_MENU_ADDONS ));
+ pPopupMenu->InsertItem( ITEMID_ADDONLIST, aAddonsStrRes );
+ pPopupMenu->SetPopupMenu( ITEMID_ADDONLIST, pSubMenu );
+
+ // Set item command for popup menu to enable it for GetImageFromURL
+ const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ aItemCommand = aSlotString;
+ aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)ITEMID_ADDONLIST );
+ pPopupMenu->SetItemCommand( ITEMID_ADDONLIST, aItemCommand );
+
+ AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
+ // Set image for the addon popup menu item
+ if ( bShowMenuImages && !pPopupMenu->GetItemImage( ITEMID_ADDONLIST ))
+ {
+ Image aImage = GetImageFromURL( rFrame, aItemCommand, false );
+ if ( !!aImage )
+ pPopupMenu->SetItemImage( ITEMID_ADDONLIST, aImage );
+ }
+ }
+ else
+ delete pSubMenu;
+ }
+ }
+ }
+ else
+ {
+ if ( nItemId == SID_NEWDOCDIRECT ||
+ aItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSlotNewDocDirect)) )
+ {
+ MenuConfiguration aMenuCfg( getServiceFactory() );
+ BmkMenu* pSubMenu = (BmkMenu*)aMenuCfg.CreateBookmarkMenu( rFrame, BOOKMARK_NEWMENU );
+ pMenu->SetPopupMenu( nItemId, pSubMenu );
+
+ AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
+ if ( bShowMenuImages && !pMenu->GetItemImage( nItemId ))
+ {
+ Image aImage = GetImageFromURL( rFrame, aItemCommand, false );
+ if ( !!aImage )
+ pMenu->SetItemImage( nItemId, aImage );
+ }
+ }
+ else if ( nItemId == SID_AUTOPILOTMENU ||
+ aItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSlotAutoPilot)) )
+ {
+ MenuConfiguration aMenuCfg( getServiceFactory() );
+ BmkMenu* pSubMenu = (BmkMenu*)aMenuCfg.CreateBookmarkMenu( rFrame, BOOKMARK_WIZARDMENU );
+ pMenu->SetPopupMenu( nItemId, pSubMenu );
+
+ AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
+
+
+ if ( bShowMenuImages && !pMenu->GetItemImage( nItemId ))
+ {
+ Image aImage = GetImageFromURL( rFrame, aItemCommand, false );
+ if ( !!aImage )
+ pMenu->SetItemImage( nItemId, aImage );
+ }
+ }
+ else if ( pMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
+ {
+ if ( bShowMenuImages )
+ {
+ if ( AddonMenuManager::IsAddonMenuId( nItemId ))
+ {
+ // Add-Ons uses a images from different places
+ Image aImage;
+ rtl::OUString aImageId;
+
+ MenuConfiguration::Attributes* pMenuAttributes =
+ (MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId );
+
+ if ( pMenuAttributes && pMenuAttributes->aImageId.getLength() > 0 )
+ {
+ // Retrieve image id from menu attributes
+ aImage = GetImageFromURL( rFrame, aImageId, false );
+ }
+
+ if ( !aImage )
+ {
+ aImage = GetImageFromURL( rFrame, aItemCommand, false );
+ if ( !aImage )
+ aImage = AddonsOptions().GetImageFromURL( aItemCommand, false );
+ }
+
+ if ( !!aImage )
+ pMenu->SetItemImage( nItemId, aImage );
+ }
+ else if ( !pMenu->GetItemImage( nItemId ))
+ {
+ Image aImage = GetImageFromURL( rFrame, aItemCommand, false );
+ if ( !!aImage )
+ pMenu->SetItemImage( nItemId, aImage );
+ }
+ }
+
+ REFERENCE< XDISPATCH > aXDispatchRef;
+ m_aMenuItemHandlerVector.push_back( new MenuItemHandler( nItemId, NULL, aXDispatchRef ));
+
+ }
+ }
+ }
+
+ // retrieve label information for all menu items without item text
+
+ SetHdl();
+}
+
+
+void MenuManager::SetHdl()
+{
+ m_pVCLMenu->SetHighlightHdl( LINK( this, MenuManager, Highlight ));
+ m_pVCLMenu->SetActivateHdl( LINK( this, MenuManager, Activate ));
+ m_pVCLMenu->SetDeactivateHdl( LINK( this, MenuManager, Deactivate ));
+ m_pVCLMenu->SetSelectHdl( LINK( this, MenuManager, Select ));
+
+ if ( mxServiceFactory.is() )
+ m_xURLTransformer.set( mxServiceFactory->createInstance(SERVICENAME_URLTRANSFORMER),UNO_QUERY );
+}
+
+MenuManager::~MenuManager()
+{
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ pItemHandler->xMenuItemDispatch.clear();
+ if ( pItemHandler->pSubMenuManager )
+ SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)pItemHandler->pSubMenuManager )->release();
+ delete pItemHandler;
+ }
+
+ if ( m_bDeleteMenu )
+ delete m_pVCLMenu;
+}
+
+
+MenuManager::MenuItemHandler* MenuManager::GetMenuItemHandler( sal_uInt16 nItemId )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ if ( pItemHandler->nItemId == nItemId )
+ return pItemHandler;
+ }
+
+ return 0;
+}
+
+
+void SAL_CALL MenuManager::statusChanged( const FEATURSTATEEVENT& Event )
+throw ( RuntimeException )
+{
+ ::rtl::OUString aFeatureURL = Event.FeatureURL.Complete;
+ MenuItemHandler* pStatusChangedMenu = NULL;
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+ if ( pMenuItemHandler->aMenuItemURL == aFeatureURL )
+ {
+ pStatusChangedMenu = pMenuItemHandler;
+ break;
+ }
+ }
+ }
+
+ if ( pStatusChangedMenu )
+ {
+ SolarMutexGuard aSolarGuard;
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ sal_Bool bSetCheckmark = sal_False;
+ sal_Bool bCheckmark = sal_False;
+ sal_Bool bMenuItemEnabled = m_pVCLMenu->IsItemEnabled( pStatusChangedMenu->nItemId );
+
+ if ( Event.IsEnabled != bMenuItemEnabled )
+ m_pVCLMenu->EnableItem( pStatusChangedMenu->nItemId, Event.IsEnabled );
+
+ if ( Event.State >>= bCheckmark )
+ bSetCheckmark = sal_True;
+
+ if ( bSetCheckmark )
+ m_pVCLMenu->CheckItem( pStatusChangedMenu->nItemId, bCheckmark );
+ }
+
+ if ( Event.Requery )
+ {
+ URL aTargetURL;
+ aTargetURL.Complete = pStatusChangedMenu->aMenuItemURL;
+
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
+ REFERENCE< XDISPATCH > xMenuItemDispatch = xDispatchProvider->queryDispatch(
+ aTargetURL, ::rtl::OUString(), 0 );
+
+ if ( xMenuItemDispatch.is() )
+ {
+ pStatusChangedMenu->xMenuItemDispatch = xMenuItemDispatch;
+ pStatusChangedMenu->aMenuItemURL = aTargetURL.Complete;
+ xMenuItemDispatch->addStatusListener( SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
+ }
+ }
+ }
+}
+
+
+void MenuManager::RemoveListener()
+{
+ ResetableGuard aGuard( m_aLock );
+ ClearMenuDispatch();
+}
+
+void MenuManager::ClearMenuDispatch(const EVENTOBJECT& Source,bool _bRemoveOnly)
+{
+ // disposing called from parent dispatcher
+ // remove all listener to prepare shutdown
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ if ( pItemHandler->xMenuItemDispatch.is() )
+ {
+ URL aTargetURL;
+ aTargetURL.Complete = pItemHandler->aMenuItemURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ pItemHandler->xMenuItemDispatch->removeStatusListener(
+ SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
+ }
+
+ pItemHandler->xMenuItemDispatch.clear();
+ if ( pItemHandler->pSubMenuManager )
+ {
+ if ( _bRemoveOnly )
+ pItemHandler->pSubMenuManager->RemoveListener();
+ else
+ pItemHandler->pSubMenuManager->disposing( Source );
+ }
+ }
+}
+
+
+void SAL_CALL MenuManager::disposing( const EVENTOBJECT& Source ) throw ( RUNTIMEEXCEPTION )
+{
+ if ( Source.Source == m_xFrame )
+ {
+ ResetableGuard aGuard( m_aLock );
+ ClearMenuDispatch(Source,false);
+ }
+ else
+ {
+ // disposing called from menu item dispatcher, remove listener
+ MenuItemHandler* pMenuItemDisposing = NULL;
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+ if ( pMenuItemHandler->xMenuItemDispatch == Source.Source )
+ {
+ pMenuItemDisposing = pMenuItemHandler;
+ break;
+ }
+ }
+
+ if ( pMenuItemDisposing )
+ {
+ URL aTargetURL;
+ aTargetURL.Complete = pMenuItemDisposing->aMenuItemURL;
+
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ pMenuItemDisposing->xMenuItemDispatch->removeStatusListener(SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
+ pMenuItemDisposing->xMenuItemDispatch.clear();
+ }
+ }
+ }
+}
+
+
+void MenuManager::UpdateSpecialFileMenu( Menu* pMenu )
+{
+ // update picklist
+ Sequence< Sequence< PropertyValue > > aHistoryList = SvtHistoryOptions().GetList( ePICKLIST );
+ ::std::vector< MenuItemHandler* > aNewPickVector;
+ Reference< XStringWidth > xStringLength( new StringLength );
+
+ sal_uInt16 nPickItemId = START_ITEMID_PICKLIST;
+ int nPickListMenuItems = ( aHistoryList.getLength() > 99 ) ? 99 : aHistoryList.getLength();
+
+ aNewPickVector.reserve(nPickListMenuItems);
+ for ( int i = 0; i < nPickListMenuItems; i++ )
+ {
+ Sequence< PropertyValue > aPickListEntry = aHistoryList[i];
+
+ REFERENCE< XDISPATCH > aXDispatchRef;
+ MenuItemHandler* pNewMenuItemHandler = new MenuItemHandler(
+ nPickItemId++,
+ NULL,
+ aXDispatchRef );
+
+ for ( int j = 0; j < aPickListEntry.getLength(); j++ )
+ {
+ Any a = aPickListEntry[j].Value;
+
+ if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_URL )
+ a >>= pNewMenuItemHandler->aMenuItemURL;
+ else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_FILTER )
+ a >>= pNewMenuItemHandler->aFilter;
+ else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_TITLE )
+ a >>= pNewMenuItemHandler->aTitle;
+ else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_PASSWORD )
+ a >>= pNewMenuItemHandler->aPassword;
+ }
+
+ aNewPickVector.push_back( pNewMenuItemHandler );
+ }
+
+ if ( !aNewPickVector.empty() )
+ {
+ URL aTargetURL;
+ REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
+
+ REFERENCE< XDISPATCH > xMenuItemDispatch;
+
+ static const ::rtl::OUString s_sDefault(RTL_CONSTASCII_USTRINGPARAM("_default"));
+ // query for dispatcher
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = aNewPickVector.begin(); p != aNewPickVector.end(); ++p )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+
+ aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ if ( !xMenuItemDispatch.is() )
+ {
+ // attention: this code assume that "_blank" can only be consumed by desktop service
+ xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, s_sDefault, 0 );
+ }
+
+ if ( xMenuItemDispatch.is() )
+ {
+ pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
+ pMenuItemHandler->aMenuItemURL = aTargetURL.Complete;
+ }
+ }
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ int nRemoveItemCount = 0;
+ int nItemCount = pMenu->GetItemCount();
+
+ if ( nItemCount > 0 )
+ {
+ // remove all old picklist entries from menu
+ sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_PICKLIST );
+ for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
+ {
+ pMenu->RemoveItem( n );
+ ++nRemoveItemCount;
+ }
+
+ if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
+ pMenu->RemoveItem( pMenu->GetItemCount()-1 );
+
+ // remove all old picklist entries from menu handler
+ if ( nRemoveItemCount > 0 )
+ {
+ for( sal_uInt32 nIndex = m_aMenuItemHandlerVector.size() - nRemoveItemCount;
+ nIndex < m_aMenuItemHandlerVector.size(); )
+ {
+ delete m_aMenuItemHandlerVector.at( nIndex );
+ m_aMenuItemHandlerVector.erase( m_aMenuItemHandlerVector.begin() + nIndex );
+ }
+ }
+ }
+
+ // append new picklist menu entries
+ aNewPickVector.reserve(aNewPickVector.size());
+ pMenu->InsertSeparator();
+ const sal_uInt32 nCount = aNewPickVector.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ char menuShortCut[5] = "~n: ";
+
+ ::rtl::OUString aMenuShortCut;
+ if ( i <= 9 )
+ {
+ if ( i == 9 )
+ aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1~0: " ));
+ else
+ {
+ menuShortCut[1] = (char)( '1' + i );
+ aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( menuShortCut ));
+ }
+ }
+ else
+ {
+ aMenuShortCut = rtl::OUString::valueOf((sal_Int32)( i + 1 ));
+ aMenuShortCut += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": " ));
+ }
+
+ // Abbreviate URL
+ rtl::OUString aURLString( aNewPickVector.at( i )->aMenuItemURL );
+ rtl::OUString aTipHelpText;
+ rtl::OUString aMenuTitle;
+ INetURLObject aURL( aURLString );
+
+ if ( aURL.GetProtocol() == INET_PROT_FILE )
+ {
+ // Do handle file URL differently => convert it to a system
+ // path and abbreviate it with a special function:
+ String aFileSystemPath( aURL.getFSysPath( INetURLObject::FSYS_DETECT ) );
+
+ ::rtl::OUString aSystemPath( aFileSystemPath );
+ ::rtl::OUString aCompactedSystemPath;
+
+ aTipHelpText = aSystemPath;
+ oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, NULL );
+ if ( !nError )
+ aMenuTitle = String( aCompactedSystemPath );
+ else
+ aMenuTitle = aSystemPath;
+ }
+ else
+ {
+ // Use INetURLObject to abbreviate all other URLs
+ String aShortURL;
+ aShortURL = aURL.getAbbreviated( xStringLength, 46, INetURLObject::DECODE_UNAMBIGUOUS );
+ aMenuTitle += aShortURL;
+ aTipHelpText = aURLString;
+ }
+
+ ::rtl::OUString aTitle( aMenuShortCut + aMenuTitle );
+
+ MenuItemHandler* pMenuItemHandler = aNewPickVector.at( i );
+ pMenu->InsertItem( pMenuItemHandler->nItemId, aTitle );
+ pMenu->SetTipHelpText( pMenuItemHandler->nItemId, aTipHelpText );
+ m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
+ }
+ }
+ }
+}
+
+void MenuManager::UpdateSpecialWindowMenu( Menu* pMenu,const Reference< XMultiServiceFactory >& xServiceFactory,framework::IMutex& _rMutex )
+{
+ // update window list
+ ::std::vector< ::rtl::OUString > aNewWindowListVector;
+
+ Reference< XDesktop > xDesktop( xServiceFactory->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
+
+ sal_uInt16 nActiveItemId = 0;
+ sal_uInt16 nItemId = START_ITEMID_WINDOWLIST;
+
+ if ( xDesktop.is() )
+ {
+ Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
+ Reference< XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
+ Reference< XIndexAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
+ sal_Int32 nCount = xList->getCount();
+ aNewWindowListVector.reserve(nCount);
+ for (sal_Int32 i=0; i<nCount; ++i )
+ {
+ Reference< XFrame > xFrame;
+ xList->getByIndex(i) >>= xFrame;
+
+ if (xFrame.is())
+ {
+ if ( xFrame == xCurrentFrame )
+ nActiveItemId = nItemId;
+
+ Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ if ( pWin && pWin->IsVisible() )
+ {
+ aNewWindowListVector.push_back( pWin->GetText() );
+ ++nItemId;
+ }
+ }
+ }
+ }
+
+ {
+ ResetableGuard aGuard( _rMutex );
+
+ int nItemCount = pMenu->GetItemCount();
+
+ if ( nItemCount > 0 )
+ {
+ // remove all old window list entries from menu
+ sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_WINDOWLIST );
+ for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
+ pMenu->RemoveItem( n );
+
+ if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
+ pMenu->RemoveItem( pMenu->GetItemCount()-1 );
+ }
+
+ if ( !aNewWindowListVector.empty() )
+ {
+ // append new window list entries to menu
+ pMenu->InsertSeparator();
+ nItemId = START_ITEMID_WINDOWLIST;
+ const sal_uInt32 nCount = aNewWindowListVector.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ pMenu->InsertItem( nItemId, aNewWindowListVector.at( i ), MIB_RADIOCHECK );
+ if ( nItemId == nActiveItemId )
+ pMenu->CheckItem( nItemId );
+ ++nItemId;
+ }
+ }
+ }
+}
+
+
+void MenuManager::CreatePicklistArguments( Sequence< PropertyValue >& aArgsList, const MenuItemHandler* pMenuItemHandler )
+{
+ int NUM_OF_PICKLIST_ARGS = 3;
+
+ Any a;
+ aArgsList.realloc( NUM_OF_PICKLIST_ARGS );
+
+ aArgsList[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ));
+ a <<= pMenuItemHandler->aMenuItemURL;
+ aArgsList[0].Value = a;
+
+ aArgsList[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
+ a <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
+ aArgsList[1].Value = a;
+
+ ::rtl::OUString aFilter( pMenuItemHandler->aFilter );
+
+ sal_Int32 nPos = aFilter.indexOf( '|' );
+ if ( nPos >= 0 )
+ {
+ ::rtl::OUString aFilterOptions;
+
+ if ( nPos < ( aFilter.getLength() - 1 ) )
+ aFilterOptions = aFilter.copy( nPos+1 );
+
+ aArgsList[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterOptions" ));
+ a <<= aFilterOptions;
+ aArgsList[2].Value = a;
+
+ aFilter = aFilter.copy( 0, nPos-1 );
+ aArgsList.realloc( ++NUM_OF_PICKLIST_ARGS );
+ }
+
+ aArgsList[NUM_OF_PICKLIST_ARGS-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
+ a <<= aFilter;
+ aArgsList[NUM_OF_PICKLIST_ARGS-1].Value = a;
+}
+
+
+//_________________________________________________________________________________________________________________
+// vcl handler
+//_________________________________________________________________________________________________________________
+
+IMPL_LINK( MenuManager, Activate, Menu *, pMenu )
+{
+ if ( pMenu == m_pVCLMenu )
+ {
+ // set/unset hiding disabled menu entries
+ sal_Bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled();
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus();
+
+ sal_uInt16 nFlag = pMenu->GetMenuFlags();
+ if ( bDontHide )
+ nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
+ else
+ nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES;
+ pMenu->SetMenuFlags( nFlag );
+
+ if ( m_bActive )
+ return 0;
+
+ m_bActive = sal_True;
+
+ ::rtl::OUString aCommand( m_aMenuItemCommand );
+ if ( m_aMenuItemCommand.matchIgnoreAsciiCase( UNO_COMMAND, 0 ))
+ {
+ // Remove protocol part from command so we can use an easier comparision method
+ aCommand = aCommand.copy( UNO_COMMAND.getLength() );
+ }
+
+ if ( m_aMenuItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSpecialFileMenu)) ||
+ m_aMenuItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSlotSpecialFileMenu)) ||
+ aCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSpecialFileCommand)) )
+ UpdateSpecialFileMenu( pMenu );
+ else if ( m_aMenuItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSpecialWindowMenu)) ||
+ m_aMenuItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSlotSpecialWindowMenu)) ||
+ aCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSpecialWindowCommand)) )
+ UpdateSpecialWindowMenu( pMenu,getServiceFactory(),m_aLock );
+
+ // Check if some modes have changed so we have to update our menu images
+ if ( bShowMenuImages != m_bShowMenuImages )
+ {
+ // The mode changed so we have to replace all images
+ m_bShowMenuImages = bShowMenuImages;
+ FillMenuImages( m_xFrame, pMenu, bShowMenuImages );
+ }
+
+ if ( m_bInitialized )
+ return 0;
+ else
+ {
+ URL aTargetURL;
+
+ ResetableGuard aGuard( m_aLock );
+
+ REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( xDispatchProvider.is() )
+ {
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+ if ( pMenuItemHandler &&
+ pMenuItemHandler->pSubMenuManager == 0 &&
+ !pMenuItemHandler->xMenuItemDispatch.is() )
+ {
+ // There is no dispatch mechanism for the special window list menu items,
+ // because they are handled directly through XFrame->activate!!!
+ if ( pMenuItemHandler->nItemId < START_ITEMID_WINDOWLIST ||
+ pMenuItemHandler->nItemId > END_ITEMID_WINDOWLIST )
+ {
+ ::rtl::OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId );
+ if ( !aItemCommand.getLength() )
+ {
+ const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ aItemCommand = aSlotString;
+ aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)pMenuItemHandler->nItemId );
+ pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand );
+ }
+
+ aTargetURL.Complete = aItemCommand;
+
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ REFERENCE< XDISPATCH > xMenuItemDispatch;
+ if ( m_bIsBookmarkMenu )
+ xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 );
+ else
+ xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+
+ if ( xMenuItemDispatch.is() )
+ {
+ pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
+ pMenuItemHandler->aMenuItemURL = aTargetURL.Complete;
+ xMenuItemDispatch->addStatusListener( SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
+ }
+ else
+ pMenu->EnableItem( pMenuItemHandler->nItemId, sal_False );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+
+IMPL_LINK( MenuManager, Deactivate, Menu *, pMenu )
+{
+ if ( pMenu == m_pVCLMenu )
+ m_bActive = sal_False;
+
+ return 1;
+}
+
+
+IMPL_LINK( MenuManager, Select, Menu *, pMenu )
+{
+ URL aTargetURL;
+ Sequence<PropertyValue> aArgs;
+ REFERENCE< XDISPATCH > xDispatch;
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ sal_uInt16 nCurItemId = pMenu->GetCurItemId();
+ if ( pMenu == m_pVCLMenu &&
+ pMenu->GetItemType( nCurItemId ) != MENUITEM_SEPARATOR )
+ {
+ if ( nCurItemId >= START_ITEMID_WINDOWLIST &&
+ nCurItemId <= END_ITEMID_WINDOWLIST )
+ {
+ // window list menu item selected
+
+ Reference< XFramesSupplier > xDesktop( getServiceFactory()->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
+
+ if ( xDesktop.is() )
+ {
+ sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
+ Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY );
+ sal_Int32 nCount = xList->getCount();
+ for ( sal_Int32 i=0; i<nCount; ++i )
+ {
+ Reference< XFrame > xFrame;
+ xList->getByIndex(i) >>= xFrame;
+
+ if ( xFrame.is() && nTaskId == nCurItemId )
+ {
+ Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ pWin->GrabFocus();
+ pWin->ToTop( TOTOP_RESTOREWHENMIN );
+ break;
+ }
+
+ nTaskId++;
+ }
+ }
+ }
+ else
+ {
+ MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId );
+ if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() )
+ {
+ aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ if ( nCurItemId >= START_ITEMID_PICKLIST &&
+ nCurItemId < START_ITEMID_WINDOWLIST )
+ {
+ // picklist menu item selected
+ CreatePicklistArguments( aArgs, pMenuItemHandler );
+ }
+ else if ( m_bIsBookmarkMenu )
+ {
+ // bookmark menu item selected
+ aArgs.realloc( 1 );
+ aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
+ aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
+ }
+
+ xDispatch = pMenuItemHandler->xMenuItemDispatch;
+ }
+ }
+ }
+ }
+
+ if ( xDispatch.is() )
+ xDispatch->dispatch( aTargetURL, aArgs );
+
+ return 1;
+}
+
+
+IMPL_LINK( MenuManager, Highlight, Menu *, EMPTYARG )
+{
+ return 0;
+}
+
+const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& MenuManager::getServiceFactory()
+{
+ return mxServiceFactory;
+}
+
+void MenuManager::AddMenu(PopupMenu* _pPopupMenu,const ::rtl::OUString& _sItemCommand,sal_uInt16 _nItemId,sal_Bool _bDelete,sal_Bool _bDeleteChildren)
+{
+ MenuManager* pSubMenuManager = new MenuManager( getServiceFactory(), m_xFrame, _pPopupMenu, _bDelete, _bDeleteChildren );
+
+ // store menu item command as we later have to know which menu is active (see Activate handler)
+ pSubMenuManager->m_aMenuItemCommand = _sItemCommand;
+
+ REFERENCE< XDISPATCH > aXDispatchRef;
+ MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
+ _nItemId,
+ pSubMenuManager,
+ aXDispatchRef );
+ m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
+}
+
+sal_uInt16 MenuManager::FillItemCommand(::rtl::OUString& _rItemCommand,Menu* _pMenu,sal_uInt16 _nIndex) const
+{
+ sal_uInt16 nItemId = _pMenu->GetItemId( _nIndex );
+
+ _rItemCommand = _pMenu->GetItemCommand( nItemId );
+ if ( !_rItemCommand.getLength() )
+ {
+ const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ _rItemCommand = aSlotString;
+ _rItemCommand += ::rtl::OUString::valueOf( (sal_Int32)nItemId );
+ _pMenu->SetItemCommand( nItemId, _rItemCommand );
+ }
+ return nItemId;
+}
+void MenuManager::FillMenuImages(Reference< XFrame >& _xFrame,Menu* _pMenu,sal_Bool bShowMenuImages)
+{
+ AddonsOptions aAddonOptions;
+
+ for ( sal_uInt16 nPos = 0; nPos < _pMenu->GetItemCount(); nPos++ )
+ {
+ sal_uInt16 nId = _pMenu->GetItemId( nPos );
+ if ( _pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR )
+ {
+ bool bTmpShowMenuImages( bShowMenuImages );
+ // overwrite the show icons on menu option?
+ if (!bTmpShowMenuImages)
+ {
+ MenuItemBits nBits = _pMenu->GetItemBits( nId );
+ bTmpShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
+ }
+
+ if ( bTmpShowMenuImages )
+ {
+ sal_Bool bImageSet = sal_False;
+ ::rtl::OUString aImageId;
+
+ ::framework::MenuConfiguration::Attributes* pMenuAttributes =
+ (::framework::MenuConfiguration::Attributes*)_pMenu->GetUserValue( nId );
+
+ if ( pMenuAttributes )
+ aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes
+
+ if ( aImageId.getLength() > 0 )
+ {
+ Image aImage = GetImageFromURL( _xFrame, aImageId, false );
+ if ( !!aImage )
+ {
+ bImageSet = sal_True;
+ _pMenu->SetItemImage( nId, aImage );
+ }
+ }
+
+ if ( !bImageSet )
+ {
+ rtl::OUString aMenuItemCommand = _pMenu->GetItemCommand( nId );
+ Image aImage = GetImageFromURL( _xFrame, aMenuItemCommand, false );
+ if ( !aImage )
+ aImage = aAddonOptions.GetImageFromURL( aMenuItemCommand, false );
+
+ _pMenu->SetItemImage( nId, aImage );
+ }
+ }
+ else
+ _pMenu->SetItemImage( nId, Image() );
+ }
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/classes/resource.src b/framework/source/classes/resource.src
new file mode 100644
index 000000000000..c1af6eb2c3c9
--- /dev/null
+++ b/framework/source/classes/resource.src
@@ -0,0 +1,360 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "helpid.hrc"
+
+#ifndef __FRAMEWORK_CLASSES_RESOURCE_HRC_
+#include <classes/resource.hrc>
+#endif
+
+String STR_MENU_ADDONS
+{
+ Text [ en-US ] = "Add-Ons" ;
+};
+
+String STR_MENU_ADDONHELP
+{
+ Text [ en-US ] = "Add-~On Help" ;
+};
+
+String STR_MENU_HEADFOOTALL
+{
+ Text [ en-US ] = "All" ;
+};
+
+String STR_UPDATEDOC
+{
+ Text [ en-US ] = "~Update" ;
+};
+
+String STR_CLOSEDOC_ANDRETURN
+{
+ Text [ en-US ] = "~Close & Return to " ;
+};
+
+Menu POPUPMENU_TOOLBAR_QUICKCUSTOMIZATION
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_VISIBLEBUTTON;
+ SubMenu = Menu
+ {
+ };
+ Text[ en-US ] = "Visible ~Buttons";
+ };
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR;
+ Command = ".uno:ConfigureToolboxVisible" ;
+ Text[ en-US ] = "~Customize Toolbar...";
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_DOCKTOOLBAR;
+ Text[ en-US ] = "~Dock Toolbar" ;
+ };
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_DOCKALLTOOLBAR;
+ Text[ en-US ] = "Dock ~All Toolbars" ;
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION;
+ Text[ en-US ] = "~Lock Toolbar Position" ;
+ };
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_CLOSE;
+ Text[ en-US ] = "Close ~Toolbar" ;
+ };
+ };
+};
+
+String STR_SAVECOPYDOC
+{
+ Text [ en-US ] = "Save Copy ~as..." ;
+};
+
+String STR_NODOCUMENT
+{
+ Text [ en-US ] = "No Documents";
+};
+
+String STR_TOOLBAR_TITLE_ADDON
+{
+ Text [ en-US ] = "Add-On %num%";
+};
+
+String STR_STATUSBAR_LOGOTEXT
+{
+ Text [ en-US ] = "A %PRODUCTNAME product by %OOOVENDOR";
+};
+
+// ***********************************************************************
+// License Dialog
+// ***********************************************************************
+#define LICENSE_DIALOG_WIDTH 260
+#define LICENSE_RIGHT_BORDER 7
+#define LICENSE_BOTTOM_BORDER 0
+#define LICENSE_ROW_1 (7)
+#define LICENSE_COL_1 (7)
+
+#define OFFSET 2
+#define COL2_WIDTH 10
+#define OFFSET_IMG 10
+#define FT_HEIGHT 8
+#define PB_HEIGHT 14
+#define PD_WIDTH 40
+
+#define LICENSE_HEIGHT 102
+#define LICENSE_ROW_2 (LICENSE_ROW_1 + OFFSET + LICENSE_HEIGHT)
+#define LICENSE_ROW_3 (LICENSE_ROW_2 + OFFSET + FT_HEIGHT)
+#define LICENSE_ROW_4 (LICENSE_ROW_3 + OFFSET + 3*FT_HEIGHT )
+#define LICENSE_ROW_5 (LICENSE_ROW_4 + FT_HEIGHT+ OFFSET )
+#define LICENSE_ROW_6 (LICENSE_ROW_5 + 2*OFFSET )
+
+#define LICENSE_DIALOG_HEIGTH (LICENSE_ROW_6 + + PB_HEIGHT + 7)
+
+#define LICENSE_COL_2 (LICENSE_COL_1 + OFFSET_IMG)
+#define LICENSE_COL_3 (LICENSE_COL_2 + COL2_WIDTH +1)
+#define LICENSE_COL_4 (LICENSE_DIALOG_WIDTH - LICENSE_RIGHT_BORDER - PD_WIDTH)
+
+#define LICENSE_WIDTH (LICENSE_DIALOG_WIDTH - LICENSE_RIGHT_BORDER - LICENSE_ROW_1)
+#define COL3_WIDTH (LICENSE_COL_4 - LICENSE_COL_3)
+
+
+ModalDialog DLG_LICENSE
+{
+ HelpId = HID_LICENSEDIALOG;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT ( LICENSE_DIALOG_WIDTH , LICENSE_DIALOG_HEIGTH ) ;
+ Text [ en-US ] = "License Agreement";
+
+ MultiLineEdit ML_LICENSE
+ {
+ HelpID = "framework:MultiLineEdit:DLG_LICENSE:ML_LICENSE";
+ PosSize = MAP_APPFONT ( LICENSE_COL_1 , LICENSE_ROW_1 , LICENSE_WIDTH , LICENSE_HEIGHT ) ;
+ Border = TRUE ;
+ VScroll = TRUE ;
+ ReadOnly = TRUE ;
+ };
+
+ FixedText FT_INFO1
+ {
+ WordBreak = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_1 , LICENSE_ROW_2 ) ;
+ Size = MAP_APPFONT ( LICENSE_WIDTH , FT_HEIGHT ) ;
+ Text [ en-US ] = "Please follow these steps to proceed with the installation:" ;
+ };
+
+ FixedImage IMG_ARROW
+ {
+ Pos = MAP_APPFONT ( LICENSE_COL_1 , LICENSE_ROW_3 ) ;
+ Size = MAP_PIXEL ( 16 , 16 ) ;
+ Fixed = Image
+ {
+ ImageBitmap = Bitmap
+ {
+ File = "arrow.bmp" ;
+ };
+ MaskColor = Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
+ };
+ };
+
+ FixedText FT_INFO2_1
+ {
+ WordBreak = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_2 , LICENSE_ROW_3 ) ;
+ Size = MAP_APPFONT ( COL2_WIDTH , FT_HEIGHT ) ;
+ Text [ en-US ] = "1." ;
+ };
+
+ FixedText FT_INFO2
+ {
+ WordBreak = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_3 , LICENSE_ROW_3 ) ;
+ Size = MAP_APPFONT ( COL3_WIDTH, 3*FT_HEIGHT ) ;
+ Text [ en-US ] = "View the complete License Agreement. Please use the scroll bar or the '%PAGEDOWN' button in this dialog to view the entire license text." ;
+ };
+
+ PushButton PB_PAGEDOWN
+ {
+ HelpID = "framework:PushButton:DLG_LICENSE:PB_PAGEDOWN";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_4 , LICENSE_ROW_3 ) ;
+ Size = MAP_APPFONT ( PD_WIDTH , PB_HEIGHT ) ;
+ Text [ en-US ] = "Scroll Down" ;
+ };
+
+ FixedText FT_INFO3_1
+ {
+ WordBreak = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_2 , LICENSE_ROW_4 ) ;
+ Size = MAP_APPFONT ( COL2_WIDTH, FT_HEIGHT ) ;
+ Text [ en-US ] = "2." ;
+ };
+
+ FixedText FT_INFO3
+ {
+ WordBreak = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_3, LICENSE_ROW_4 ) ;
+ Size = MAP_APPFONT ( COL3_WIDTH, FT_HEIGHT ) ;
+ Text [ en-US ] = "Accept the License Agreement." ;
+ };
+
+ String LICENSE_ACCEPT
+ {
+ Text [ en-US ] = "~Accept" ;
+ };
+
+ String LICENSE_NOTACCEPT
+ {
+ Text [ en-US ] = "Decline" ;
+ };
+
+ FixedLine FL_DIVIDE
+ {
+ Pos = MAP_APPFONT ( LICENSE_COL_1, LICENSE_ROW_5 ) ;
+ Size = MAP_APPFONT ( LICENSE_WIDTH, 1 ) ;
+ };
+
+ PushButton PB_ACCEPT
+ {
+ HelpID = "framework:PushButton:DLG_LICENSE:PB_ACCEPT";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_4 - PD_WIDTH - OFFSET_IMG , LICENSE_ROW_6 ) ;
+ Size = MAP_APPFONT ( PD_WIDTH , PB_HEIGHT ) ;
+ };
+
+ PushButton PB_DECLINE
+ {
+ HelpID = "framework:PushButton:DLG_LICENSE:PB_DECLINE";
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_4 , LICENSE_ROW_6 ) ;
+ Size = MAP_APPFONT ( PD_WIDTH , PB_HEIGHT ) ;
+ };
+
+};
+
+Image RID_IMAGE_STATUSBAR_LOGO
+{
+ ImageBitmap = Bitmap { File = "logo.png" ; };
+ MaskColor = Color { Red = 0xFFFF; Green = 0x0000; Blue = 0xFFFF; };
+};
+
+String STR_FULL_DISC_RETRY_BUTTON
+{
+ Text [ en-US ] = "Retry" ;
+};
+
+String STR_FULL_DISC_MSG
+{
+ Text [ en-US ] = "%PRODUCTNAME could not save important internal information due to insufficient free disk space at the following location:\n%PATH\n\nYou will not be able to continue working with %PRODUCTNAME without allocating more free disk space at that location.\n\nPress the 'Retry' button after you have allocated more free disk space to retry saving the data.\n\n" ;
+};
+
+String STR_RESTORE_TOOLBARS
+{
+ Text [ en-US ] = "~Reset" ;
+};
+
+String STR_CORRUPT_UICFG_SHARE
+{
+ Text [ en-US ] = "An error occurred while loading the user interface configuration data. The application will be terminated now.\nPlease try to reinstall the application." ;
+};
+
+String STR_CORRUPT_UICFG_USER
+{
+ Text [ en-US ] = "An error occurred while loading the user interface configuration data. The application will be terminated now.\nPlease try to remove your user profile for the application." ;
+};
+
+String STR_CORRUPT_UICFG_GENERAL
+{
+ Text [ en-US ] = "An error occurred while loading the user interface configuration data. The application will be terminated now.\nPlease try to remove your user profile for the application first or try to reinstall the application." ;
+};
+
+String STR_UNTITLED_DOCUMENT
+{
+ Text [ en-US ] = "Untitled" ;
+};
+
+// for displaying 'Multiple Languages' in the language statusbar control
+String STR_LANGSTATUS_MULTIPLE_LANGUAGES
+{
+ Text [ en-US ] = "Multiple Languages" ;
+ Text [ x-comment ] = " ";
+};
+
+String STR_LANGSTATUS_NONE
+{
+ Text [ en-US ] = "None (Do not check spelling)" ;
+ Text [ x-comment ] = " ";
+};
+
+String STR_RESET_TO_DEFAULT_LANGUAGE
+{
+ Text [ en-US ] = "Reset to Default Language" ;
+ Text [ x-comment ] = " ";
+};
+
+String STR_LANGSTATUS_MORE
+{
+ Text [ en-US ] = "More..." ;
+ Text [ x-comment ] = " ";
+};
+
+String STR_SET_LANGUAGE_FOR_SELECTION
+{
+ Text [ en-US ] = "Set Language for Selection" ;
+ Text [ x-comment ] = " ";
+};
+
+String STR_SET_LANGUAGE_FOR_PARAGRAPH
+{
+ Text [ en-US ] = "Set Language for Paragraph" ;
+ Text [ x-comment ] = " ";
+};
+
+String STR_SET_LANGUAGE_FOR_ALL_TEXT
+{
+ Text [ en-US ] = "Set Language for all Text" ;
+ Text [ x-comment ] = " ";
+};
diff --git a/framework/source/classes/taskcreator.cxx b/framework/source/classes/taskcreator.cxx
new file mode 100644
index 000000000000..6edfc8d192ac
--- /dev/null
+++ b/framework/source/classes/taskcreator.cxx
@@ -0,0 +1,174 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <classes/taskcreator.hxx>
+#include "services/taskcreatorsrv.hxx"
+#include <threadhelp/readguard.hxx>
+#include <loadenv/targethelper.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <comphelper/configurationhelper.hxx>
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// includes of my own project
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+/*-****************************************************************************************************//**
+ @short initialize instance with neccessary informations
+ @descr We need a valid uno service manager to create or instanciate new services.
+ All other informations to create frames or tasks come in on right interface methods.
+
+ @param xSMGR
+ points to the valid uno service manager
+
+ @modified 16.05.2002 09:25, as96863
+*//*-*****************************************************************************************************/
+TaskCreator::TaskCreator( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ : ThreadHelpBase( )
+ , m_xSMGR ( xSMGR )
+{
+}
+
+/*-****************************************************************************************************//**
+ @short deinitialize instance
+ @descr We should release all used ressource which are not needed any longer.
+
+ @modified 16.05.2002 09:33, as96863
+*//*-*****************************************************************************************************/
+TaskCreator::~TaskCreator()
+{
+ m_xSMGR.clear();
+}
+
+/*-****************************************************************************************************//**
+ TODO document me
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > TaskCreator::createTask( const ::rtl::OUString& sName ,
+ sal_Bool bVisible )
+{
+ static ::rtl::OUString PACKAGE(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.TabBrowse"));
+ static ::rtl::OUString RELPATH(RTL_CONSTASCII_USTRINGPARAM("TaskCreatorService"));
+ static ::rtl::OUString KEY(RTL_CONSTASCII_USTRINGPARAM("ImplementationName"));
+
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::lang::XSingleServiceFactory > xCreator;
+ ::rtl::OUString sCreator = IMPLEMENTATIONNAME_FWK_TASKCREATOR;
+
+ try
+ {
+ if (
+ ( TargetHelper::matchSpecialTarget(sName, TargetHelper::E_BLANK ) ) ||
+ ( TargetHelper::matchSpecialTarget(sName, TargetHelper::E_DEFAULT) )
+ )
+ {
+ ::comphelper::ConfigurationHelper::readDirectKey(xSMGR, PACKAGE, RELPATH, KEY, ::comphelper::ConfigurationHelper::E_READONLY) >>= sCreator;
+ }
+
+ xCreator = css::uno::Reference< css::lang::XSingleServiceFactory >(
+ xSMGR->createInstance(sCreator), css::uno::UNO_QUERY_THROW);
+ }
+ catch(const css::uno::Exception&)
+ {}
+
+ // no catch here ... without an task creator service we cant open ANY document window within the office.
+ // Thats IMHO not a good idea. Then we should accept the stacktrace showing us the real problem.
+ // BTW: The used fallback creator service (IMPLEMENTATIONNAME_FWK_TASKCREATOR) is implemented in the same
+ // library then these class here ... Why we should not be able to create it ?
+ if ( ! xCreator.is())
+ xCreator = css::uno::Reference< css::lang::XSingleServiceFactory >(
+ xSMGR->createInstance(IMPLEMENTATIONNAME_FWK_TASKCREATOR), css::uno::UNO_QUERY_THROW);
+
+ css::uno::Sequence< css::uno::Any > lArgs(5);
+ css::beans::NamedValue aArg ;
+
+ aArg.Name = TaskCreatorService::ARGUMENT_PARENTFRAME;
+ aArg.Value <<= css::uno::Reference< css::frame::XFrame >(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
+ lArgs[0] <<= aArg;
+
+ aArg.Name = TaskCreatorService::ARGUMENT_CREATETOPWINDOW;
+ aArg.Value <<= sal_True;
+ lArgs[1] <<= aArg;
+
+ aArg.Name = TaskCreatorService::ARGUMENT_MAKEVISIBLE;
+ aArg.Value <<= bVisible;
+ lArgs[2] <<= aArg;
+
+ aArg.Name = TaskCreatorService::ARGUMENT_SUPPORTPERSISTENTWINDOWSTATE;
+ aArg.Value <<= sal_True;
+ lArgs[3] <<= aArg;
+
+ aArg.Name = TaskCreatorService::ARGUMENT_FRAMENAME;
+ aArg.Value <<= sName;
+ lArgs[4] <<= aArg;
+
+ css::uno::Reference< css::frame::XFrame > xTask(xCreator->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
+ return xTask;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/constant/containerquery.cxx b/framework/source/constant/containerquery.cxx
new file mode 100644
index 000000000000..a0082aabe394
--- /dev/null
+++ b/framework/source/constant/containerquery.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <constant/containerquery.hxx>
+
+namespace framework{
+ namespace constant{
+
+const sal_Unicode ContainerQuery::SEPERATOR_PARAM = (sal_Unicode)':';
+const sal_Unicode ContainerQuery::SEPERATOR_VALUE = (sal_Unicode)'=';
+
+ } // namespace constant
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/constant/contenthandler.cxx b/framework/source/constant/contenthandler.cxx
new file mode 100644
index 000000000000..0db196ed1eb7
--- /dev/null
+++ b/framework/source/constant/contenthandler.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <constant/contenthandler.hxx>
+
+namespace framework{
+ namespace constant{
+
+const ::rtl::OUString ContentHandler::PROP_NAME = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name" ));
+const ::rtl::OUString ContentHandler::PROP_TYPES = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Types"));
+
+ } // namespace constant
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/constant/frameloader.cxx b/framework/source/constant/frameloader.cxx
new file mode 100644
index 000000000000..3f4addd34ca1
--- /dev/null
+++ b/framework/source/constant/frameloader.cxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <constant/frameloader.hxx>
+
+namespace framework{
+ namespace constant{
+
+const ::rtl::OUString FrameLoader::PROP_NAME = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name" ));
+const ::rtl::OUString FrameLoader::PROP_TYPES = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Types"));
+
+ } // namespace constant
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/closedispatcher.cxx b/framework/source/dispatch/closedispatcher.cxx
new file mode 100644
index 000000000000..ab9664f01bd3
--- /dev/null
+++ b/framework/source/dispatch/closedispatcher.cxx
@@ -0,0 +1,655 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// my own includes
+#include <dispatch/closedispatcher.hxx>
+#include <pattern/frame.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <framework/framelistanalyzer.hxx>
+#include <services.h>
+#include <general.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/CommandGroup.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+#include "com/sun/star/beans/XFastPropertySet.hpp"
+#include <toolkit/helper/vclunohelper.hxx>
+
+//_______________________________________________
+// includes of other projects
+
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+#include <unotools/moduleoptions.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+#ifdef fpf
+ #error "Who uses \"fpf\" as define. It will overwrite my namespace alias ..."
+#endif
+namespace fpf = ::framework::pattern::frame;
+
+//_______________________________________________
+// non exported const
+
+static ::rtl::OUString URL_CLOSEDOC = DECLARE_ASCII(".uno:CloseDoc" );
+static ::rtl::OUString URL_CLOSEWIN = DECLARE_ASCII(".uno:CloseWin" );
+static ::rtl::OUString URL_CLOSEFRAME = DECLARE_ASCII(".uno:CloseFrame");
+
+//_______________________________________________
+// declarations
+
+DEFINE_XINTERFACE_4(CloseDispatcher ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::frame::XNotifyingDispatch ),
+ DIRECT_INTERFACE(css::frame::XDispatch ),
+ DIRECT_INTERFACE(css::frame::XDispatchInformationProvider))
+
+// Note: XStatusListener is an implementation detail. Hide it for scripting!
+DEFINE_XTYPEPROVIDER_4(CloseDispatcher ,
+ css::lang::XTypeProvider ,
+ css::frame::XDispatchInformationProvider,
+ css::frame::XNotifyingDispatch ,
+ css::frame::XDispatch )
+
+//-----------------------------------------------
+CloseDispatcher::CloseDispatcher(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xFrame ,
+ const ::rtl::OUString& sTarget)
+ : ThreadHelpBase (&Application::GetSolarMutex() )
+ , ::cppu::OWeakObject( )
+ , m_xSMGR (xSMGR )
+ , m_aAsyncCallback (LINK( this, CloseDispatcher, impl_asyncCallback))
+ , m_lStatusListener (m_aLock.getShareableOslMutex() )
+{
+ m_xCloseFrame = CloseDispatcher::static_impl_searchRightTargetFrame(xFrame, sTarget);
+}
+
+//-----------------------------------------------
+CloseDispatcher::~CloseDispatcher()
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL CloseDispatcher::dispatch(const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
+ throw(css::uno::RuntimeException)
+{
+ dispatchWithNotification(aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >());
+}
+
+//-----------------------------------------------
+css::uno::Sequence< sal_Int16 > SAL_CALL CloseDispatcher::getSupportedCommandGroups()
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Sequence< sal_Int16 > lGroups(2);
+ lGroups[0] = css::frame::CommandGroup::VIEW;
+ lGroups[1] = css::frame::CommandGroup::DOCUMENT;
+ return lGroups;
+}
+
+//-----------------------------------------------
+css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL CloseDispatcher::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
+ throw(css::uno::RuntimeException)
+{
+ if (nCommandGroup == css::frame::CommandGroup::VIEW)
+ {
+ /* Attention: Dont add .uno:CloseFrame here. Because its not realy
+ a configurable feature ... and further it does not have
+ a valid UIName entry inside the GenericCommands.xcu ... */
+ css::uno::Sequence< css::frame::DispatchInformation > lViewInfos(1);
+ lViewInfos[0].Command = URL_CLOSEWIN;
+ lViewInfos[0].GroupId = css::frame::CommandGroup::VIEW;
+ return lViewInfos;
+ }
+ else
+ if (nCommandGroup == css::frame::CommandGroup::DOCUMENT)
+ {
+ css::uno::Sequence< css::frame::DispatchInformation > lDocInfos(1);
+ lDocInfos[0].Command = URL_CLOSEDOC;
+ lDocInfos[0].GroupId = css::frame::CommandGroup::DOCUMENT;
+ return lDocInfos;
+ }
+
+ return css::uno::Sequence< css::frame::DispatchInformation >();
+}
+
+//-----------------------------------------------
+void SAL_CALL CloseDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
+ const css::util::URL& /*aURL*/ )
+ throw(css::uno::RuntimeException)
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL CloseDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
+ const css::util::URL& /*aURL*/ )
+ throw(css::uno::RuntimeException)
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL CloseDispatcher::dispatchWithNotification(const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
+ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // This reference indicates, that we was already called before and
+ // our asynchronous process was not finished yet.
+ // We have to reject double calls. Otherwhise we risk,
+ // that we try to close an already closed resource ...
+ // And its no problem to do nothing then. The UI user will try it again, if
+ // non of these jobs was successfully.
+ if (m_xSelfHold.is())
+ {
+ aWriteLock.unlock();
+ // <- SAFE ------------------------------
+
+ implts_notifyResultListener(
+ xListener,
+ css::frame::DispatchResultState::DONTKNOW,
+ css::uno::Any());
+ return;
+ }
+
+ // First we have to check, if this dispatcher is used right. Means if valid URLs are used.
+ // If not - we have to break this operation. But an optional listener must be informed.
+ // BTW: We save the information about the requested operation. Because
+ // we need it later.
+ if (aURL.Complete.equals(URL_CLOSEDOC))
+ m_eOperation = E_CLOSE_DOC;
+ else
+ if (aURL.Complete.equals(URL_CLOSEWIN))
+ m_eOperation = E_CLOSE_WIN;
+ else
+ if (aURL.Complete.equals(URL_CLOSEFRAME))
+ m_eOperation = E_CLOSE_FRAME;
+ else
+ {
+ aWriteLock.unlock();
+ // <- SAFE ------------------------------
+
+ implts_notifyResultListener(
+ xListener,
+ css::frame::DispatchResultState::FAILURE,
+ css::uno::Any());
+ return;
+ }
+
+ // OK - URLs are the right ones.
+ // But we cant execute synchronously :-)
+ // May we are called from a generic key-input handler,
+ // which isnt aware that this call kill its own environment ...
+ // Do it asynchronous everytimes!
+
+ // But dont forget to hold usself alive.
+ // We are called back from an environment, which doesnt know an uno reference.
+ // They call us back by using our c++ interface.
+
+ m_xResultListener = xListener;
+ m_xSelfHold = css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ sal_Bool bIsSynchron = sal_False;
+ for (sal_Int32 nArgs=0; nArgs<lArguments.getLength(); nArgs++ )
+ {
+ if ( lArguments[nArgs].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SynchronMode")) )
+ {
+ lArguments[nArgs].Value >>= bIsSynchron;
+ break;
+ }
+ }
+
+ if ( bIsSynchron )
+ impl_asyncCallback(0);
+ else
+ m_aAsyncCallback.Post(0);
+}
+
+//-----------------------------------------------
+/**
+ @short asynchronous callback
+ @descr We start all actions inside this object asnychronoue.
+ (see comments there).
+ Now we do the following:
+ - close all views to the same document, if needed and possible
+ - make the current frame empty
+ ! This step is neccessary to handle errors during closing the
+ document inside the frame. May the document shows a dialog and
+ the user ignore it. Then the state of the office can be changed
+ during we try to close frame and document.
+ - check the environment (menas count open frames - exlcuding our
+ current one)
+ - decide then, if we must close this frame only, establish the backing mode
+ or shutdown the whole application.
+*/
+IMPL_LINK( CloseDispatcher, impl_asyncCallback, void*, EMPTYARG )
+{
+ try
+ {
+
+ // Allow calling of XController->suspend() everytimes.
+ // Dispatch is an UI functionality. We implement such dispatch object here.
+ // And further XController->suspend() was designed to bring an UI ...
+ sal_Bool bAllowSuspend = sal_True;
+ sal_Bool bControllerSuspended = sal_False;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ // Closing of all views, related to the same document, is allowed
+ // only if the dispatched URL was ".uno:CloseDoc"!
+ sal_Bool bCloseAllViewsToo = (m_eOperation == E_CLOSE_DOC);
+
+ // BTW: Make some copies, which are needed later ...
+ EOperation eOperation = m_eOperation;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ css::uno::Reference< css::frame::XFrame > xCloseFrame (m_xCloseFrame.get(), css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XDispatchResultListener > xListener = m_xResultListener;
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // frame already dead ?!
+ // Nothing to do !
+ if (! xCloseFrame.is())
+ return 0;
+
+ sal_Bool bCloseFrame = sal_False;
+ sal_Bool bEstablishBackingMode = sal_False;
+ sal_Bool bTerminateApp = sal_False;
+
+ // Analyze the environment a first time.
+ // If we found some special cases, we can
+ // make some decisions erliar!
+ css::uno::Reference< css::frame::XFramesSupplier > xDesktop(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
+ FrameListAnalyzer aCheck1(xDesktop, xCloseFrame, FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT);
+
+ // a) If the curent frame (where the close dispatch was requested for) does not have
+ // any parent frame ... it will close this frame only. Such frame isnt part of the
+ // global desktop tree ... and such frames are used as "implementation details" only.
+ // E.g. the live previews of our wizards doing such things. And then the owner of the frame
+ // is responsible for closing the application or accepting closing of the application
+ // by others.
+ if ( ! xCloseFrame->getCreator().is())
+ bCloseFrame = sal_True;
+ else
+
+ // b) The help window cant disagree with any request.
+ // Because it doesnt implement a controller - it uses a window only.
+ // Further t cant be the last open frame - if we do all other things
+ // right inside this CloseDispatcher implementation.
+ // => close it!
+ if (aCheck1.m_bReferenceIsHelp)
+ bCloseFrame = sal_True;
+ else
+
+ // c) If we are already in "backing mode", we have to terminate
+ // the application, if this special frame is closed.
+ // It doesnt matter, how many other frames (can be the help or hidden frames only)
+ // are open then.
+ // => terminate the application!
+ if (aCheck1.m_bReferenceIsBacking)
+ bTerminateApp = sal_True;
+ else
+
+ // d) Otherwhise we have to: close all views to the same document, close the
+ // document inside our own frame and decide then again, what has to be done!
+ {
+ if (implts_prepareFrameForClosing(m_xCloseFrame, bAllowSuspend, bCloseAllViewsToo, bControllerSuspended))
+ {
+ // OK; this frame is empty now.
+ // Check the environment again to decide, what is the next step.
+ FrameListAnalyzer aCheck2(xDesktop, xCloseFrame, FrameListAnalyzer::E_ALL);
+
+ // c1) there is as minimum 1 frame open, which is visible and contains a document
+ // different from our one. And its not the help!
+ // => close our frame only - nothing else.
+ if (aCheck2.m_lOtherVisibleFrames.getLength()>0)
+ bCloseFrame = sal_True;
+ else
+
+ // c2) if we close the current view ... but not all other views
+ // to the same document, we must close the current frame only!
+ // Because implts_closeView() suspended this view only - does not
+ // close the frame.
+ if (
+ (!bCloseAllViewsToo ) &&
+ (aCheck2.m_lModelFrames.getLength() > 0)
+ )
+ bCloseFrame = sal_True;
+
+ else
+ // c3) there is no other (visible) frame open ...
+ // The help module will be ignored everytimes!
+ // But we have to decide if we must terminate the
+ // application or establish the backing mode now.
+ // And that depends from the dispatched URL ...
+ {
+ if (eOperation == E_CLOSE_FRAME)
+ bTerminateApp = sal_True;
+ else if( SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE) )
+ bEstablishBackingMode = sal_True;
+ else
+ bTerminateApp = sal_True;
+ }
+ }
+ }
+
+ // Do it now ...
+ sal_Bool bSuccess = sal_False;
+ if (bCloseFrame)
+ bSuccess = implts_closeFrame();
+ else
+ if (bEstablishBackingMode)
+ #if defined QUARTZ
+ {
+ // on mac close down, quickstarter keeps the process alive
+ // however if someone has shut down the quickstarter
+ // behave as any other platform
+
+ bool bQuickstarterRunning = false;
+ // get quickstart service
+ try
+ {
+ css::uno::Reference< css::beans::XFastPropertySet > xSet( xSMGR->createInstance(IMPLEMENTATIONNAME_QUICKLAUNCHER), css::uno::UNO_QUERY_THROW );
+ if( xSet.is() )
+ {
+ css::uno::Any aVal( xSet->getFastPropertyValue( 0 ) );
+ sal_Bool bState = sal_False;
+ if( aVal >>= bState )
+ bQuickstarterRunning = bState;
+ }
+ }
+ catch( css::uno::Exception& )
+ {
+ }
+ bSuccess = bQuickstarterRunning ? implts_terminateApplication() : implts_establishBackingMode();
+ }
+ #else
+ bSuccess = implts_establishBackingMode();
+ #endif
+ else
+ if (bTerminateApp)
+ bSuccess = implts_terminateApplication();
+
+ if (
+ ( ! bSuccess ) &&
+ ( bControllerSuspended )
+ )
+ {
+ css::uno::Reference< css::frame::XController > xController = xCloseFrame->getController();
+ if (xController.is())
+ xController->suspend(sal_False);
+ }
+
+ // inform listener
+ sal_Int16 nState = css::frame::DispatchResultState::FAILURE;
+ if (bSuccess)
+ nState = css::frame::DispatchResultState::SUCCESS;
+ implts_notifyResultListener(xListener, nState, css::uno::Any());
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // This method was called asynchronous from our main thread by using a pointer.
+ // We reached this method only, by using a reference to ourself :-)
+ // Further this member is used to detect still running and not yet finished
+ // ansynchronous operations. So its time now to release this reference.
+ // But hold it temp alive. Otherwhise we die before we can finish this method realy :-))
+ css::uno::Reference< css::uno::XInterface > xTempHold = m_xSelfHold;
+ m_xSelfHold.clear();
+ m_xResultListener.clear();
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ }
+ catch(const css::lang::DisposedException&)
+ {
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------
+sal_Bool CloseDispatcher::implts_prepareFrameForClosing(const css::uno::Reference< css::frame::XFrame >& xFrame ,
+ sal_Bool bAllowSuspend ,
+ sal_Bool bCloseAllOtherViewsToo,
+ sal_Bool& bControllerSuspended )
+{
+ // Frame already dead ... so this view is closed ... is closed ... is ... .-)
+ if (! xFrame.is())
+ return sal_True;
+
+ // Close all views to the same document ... if forced to do so.
+ // But dont touch our own frame here!
+ // We must do so ... because the may be following controller->suspend()
+ // will show the "save/discard/cancel" dialog for the last view only!
+ if (bCloseAllOtherViewsToo)
+ {
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::frame::XFramesSupplier > xDesktop(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
+ FrameListAnalyzer aCheck(xDesktop, xFrame, FrameListAnalyzer::E_ALL);
+
+ sal_Int32 c = aCheck.m_lModelFrames.getLength();
+ sal_Int32 i = 0;
+ for (i=0; i<c; ++i)
+ {
+ if (!fpf::closeIt(aCheck.m_lModelFrames[i], sal_False))
+ return sal_False;
+ }
+ }
+
+ // If allowed - inform user about modified documents or
+ // still running jobs (e.g. printing).
+ if (bAllowSuspend)
+ {
+ css::uno::Reference< css::frame::XController > xController = xFrame->getController();
+ if (xController.is()) // some views dont uses a controller .-( (e.g. the help window)
+ {
+ bControllerSuspended = xController->suspend(sal_True);
+ if (! bControllerSuspended)
+ return sal_False;
+ }
+ }
+
+ // dont remove the component realy by e.g. calling setComponent(null, null).
+ // It's enough to suspend the controller.
+ // If we close the frame later this controller doesnt show the same dialog again.
+ return sal_True;
+}
+
+//-----------------------------------------------
+sal_Bool CloseDispatcher::implts_closeFrame()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XFrame > xFrame (m_xCloseFrame.get(), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // frame already dead ? => so it's closed ... it's closed ...
+ if ( ! xFrame.is() )
+ return sal_True;
+
+ // dont deliver owner ship; our "UI user" will try it again if it failed.
+ // OK - he will get an empty frame then. But normaly an empty frame
+ // should be closeable always :-)
+ if (!fpf::closeIt(xFrame, sal_False))
+ return sal_False;
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xCloseFrame = css::uno::WeakReference< css::frame::XFrame >();
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return sal_True;
+}
+
+//-----------------------------------------------
+sal_Bool CloseDispatcher::implts_establishBackingMode()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ css::uno::Reference< css::frame::XFrame > xFrame (m_xCloseFrame.get(), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (!xFrame.is())
+ return sal_False;
+
+ css::uno::Reference < css::document::XActionLockable > xLock( xFrame, css::uno::UNO_QUERY );
+ if ( xLock.is() && xLock->isActionLocked() )
+ return sal_False;
+
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = xFrame->getContainerWindow();
+ css::uno::Sequence< css::uno::Any > lArgs(1);
+ lArgs[0] <<= xContainerWindow;
+
+ css::uno::Reference< css::frame::XController > xBackingComp(
+ xSMGR->createInstanceWithArguments(SERVICENAME_STARTMODULE, lArgs),
+ css::uno::UNO_QUERY_THROW);
+
+ // Attention: You MUST(!) call setComponent() before you call attachFrame().
+ css::uno::Reference< css::awt::XWindow > xBackingWin(xBackingComp, css::uno::UNO_QUERY);
+ xFrame->setComponent(xBackingWin, xBackingComp);
+ xBackingComp->attachFrame(xFrame);
+ xContainerWindow->setVisible(sal_True);
+
+ return sal_True;
+}
+
+//-----------------------------------------------
+sal_Bool CloseDispatcher::implts_terminateApplication()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::frame::XDesktop > xDesktop(
+ xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
+
+ return xDesktop->terminate();
+}
+
+//-----------------------------------------------
+void CloseDispatcher::implts_notifyResultListener(const css::uno::Reference< css::frame::XDispatchResultListener >& xListener,
+ sal_Int16 nState ,
+ const css::uno::Any& aResult )
+{
+ if (!xListener.is())
+ return;
+
+ css::frame::DispatchResultEvent aEvent(
+ css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY),
+ nState,
+ aResult);
+
+ xListener->dispatchFinished(aEvent);
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::frame::XFrame > CloseDispatcher::static_impl_searchRightTargetFrame(const css::uno::Reference< css::frame::XFrame >& xFrame ,
+ const ::rtl::OUString& sTarget)
+{
+ if (sTarget.equalsIgnoreAsciiCaseAscii("_self"))
+ return xFrame;
+
+ OSL_ENSURE((sTarget.getLength() < 1), "CloseDispatch used for unexpected target. Magic things will happen now .-)");
+
+ css::uno::Reference< css::frame::XFrame > xTarget = xFrame;
+ while(sal_True)
+ {
+ // a) top frames wil be closed
+ if (xTarget->isTop())
+ return xTarget;
+
+ // b) even child frame containing top level windows (e.g. query designer of database) will be closed
+ css::uno::Reference< css::awt::XWindow > xWindow = xTarget->getContainerWindow();
+ css::uno::Reference< css::awt::XTopWindow > xTopWindowCheck(xWindow, css::uno::UNO_QUERY);
+ if (xTopWindowCheck.is())
+ {
+ // b1) Note: Toolkit interface XTopWindow sometimes is used by real VCL-child-windows also .-)
+ // Be sure that these window is realy a "top system window".
+ // Attention ! Checking Window->GetParent() isnt the right approach here.
+ // Because sometimes VCL create "implicit border windows" as parents even we created
+ // a simple XWindow using the toolkit only .-(
+ SolarMutexGuard aSolarLock;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if (
+ (pWindow ) &&
+ (pWindow->IsSystemWindow())
+ )
+ return xTarget;
+ }
+
+ // c) try to find better results on parent frame
+ // If no parent frame exists (because this frame is used outside the desktop tree)
+ // the given frame must be used directly.
+ css::uno::Reference< css::frame::XFrame > xParent(xTarget->getCreator(), css::uno::UNO_QUERY);
+ if ( ! xParent.is())
+ return xTarget;
+
+ // c1) check parent frame inside next loop ...
+ xTarget = xParent;
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/dispatchinformationprovider.cxx b/framework/source/dispatch/dispatchinformationprovider.cxx
new file mode 100644
index 000000000000..bef585ed6ab5
--- /dev/null
+++ b/framework/source/dispatch/dispatchinformationprovider.cxx
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <dispatch/dispatchinformationprovider.hxx>
+#include <dispatch/closedispatcher.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <stdtypes.h>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/CommandGroup.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <comphelper/sequenceasvector.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+namespace css = ::com::sun::star;
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+DEFINE_XINTERFACE_1(DispatchInformationProvider ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::frame::XDispatchInformationProvider))
+
+//_________________________________________________________________________________________________________________
+DispatchInformationProvider::DispatchInformationProvider(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xFrame)
+ : ThreadHelpBase(&Application::GetSolarMutex())
+ , m_xSMGR (xSMGR )
+ , m_xFrame (xFrame )
+{
+}
+
+//_________________________________________________________________________________________________________________
+DispatchInformationProvider::~DispatchInformationProvider()
+{
+}
+
+//_________________________________________________________________________________________________________________
+css::uno::Sequence< sal_Int16 > SAL_CALL DispatchInformationProvider::getSupportedCommandGroups()
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatchInformationProvider > > lProvider = implts_getAllSubProvider();
+ sal_Int32 c1 = lProvider.getLength();
+ sal_Int32 i1 = 0;
+
+ ::comphelper::SequenceAsVector< sal_Int16 > lGroups;
+
+ for (i1=0; i1<c1; ++i1)
+ {
+ // ignore controller, which doesnt implement the right interface
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider = lProvider[i1];
+ if (!xProvider.is())
+ continue;
+
+ const css::uno::Sequence< sal_Int16 > lProviderGroups = xProvider->getSupportedCommandGroups();
+ sal_Int32 c2 = lProviderGroups.getLength();
+ sal_Int32 i2 = 0;
+ for (i2=0; i2<c2; ++i2)
+ {
+ const sal_Int16& rGroup = lProviderGroups[i2];
+ ::comphelper::SequenceAsVector< sal_Int16 >::const_iterator pGroup = ::std::find(lGroups.begin(), lGroups.end(), rGroup);
+ if (pGroup == lGroups.end())
+ lGroups.push_back(rGroup);
+ }
+ }
+
+ return lGroups.getAsConstList();
+}
+
+//_________________________________________________________________________________________________________________
+css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL DispatchInformationProvider::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatchInformationProvider > > lProvider = implts_getAllSubProvider();
+ sal_Int32 c1 = lProvider.getLength();
+ sal_Int32 i1 = 0;
+
+ BaseHash< css::frame::DispatchInformation > lInfos;
+
+ for (i1=0; i1<c1; ++i1)
+ {
+ try
+ {
+ // ignore controller, which doesnt implement the right interface
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider = lProvider[i1];
+ if (!xProvider.is())
+ continue;
+
+ const css::uno::Sequence< css::frame::DispatchInformation > lProviderInfos = xProvider->getConfigurableDispatchInformation(nCommandGroup);
+ sal_Int32 c2 = lProviderInfos.getLength();
+ sal_Int32 i2 = 0;
+ for (i2=0; i2<c2; ++i2)
+ {
+ const css::frame::DispatchInformation& rInfo = lProviderInfos[i2];
+ BaseHash< css::frame::DispatchInformation >::const_iterator pInfo = lInfos.find(rInfo.Command);
+ if (pInfo == lInfos.end())
+ lInfos[rInfo.Command] = rInfo;
+ }
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { continue; }
+ }
+
+ c1 = (sal_Int32)lInfos.size();
+ i1 = 0;
+
+ css::uno::Sequence< css::frame::DispatchInformation > lReturn(c1);
+ BaseHash< css::frame::DispatchInformation >::const_iterator pStepp ;
+ for ( pStepp = lInfos.begin() ;
+ pStepp != lInfos.end () && i1<c1 ;
+ ++pStepp, ++i1 )
+ {
+ lReturn[i1] = pStepp->second;
+ }
+ return lReturn;
+}
+
+//_________________________________________________________________________________________________________________
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatchInformationProvider > > DispatchInformationProvider::implts_getAllSubProvider()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (!xFrame.is())
+ return css::uno::Sequence< css::uno::Reference< css::frame::XDispatchInformationProvider > >();
+
+ CloseDispatcher* pCloser = new CloseDispatcher(xSMGR, xFrame, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self"))); // explicit "_self" ... not "" ... see implementation of close dispatcher itself!
+ css::uno::Reference< css::uno::XInterface > xCloser(static_cast< css::frame::XDispatch* >(pCloser), css::uno::UNO_QUERY);
+
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xCloseDispatch(xCloser , css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xController (xFrame->getController() , css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xAppDispatcher(xSMGR->createInstance(IMPLEMENTATIONNAME_APPDISPATCHPROVIDER), css::uno::UNO_QUERY);
+
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatchInformationProvider > > lProvider(3);
+ lProvider[0] = xController ;
+ lProvider[1] = xCloseDispatch;
+ lProvider[2] = xAppDispatcher;
+
+ return lProvider;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/dispatchprovider.cxx b/framework/source/dispatch/dispatchprovider.cxx
new file mode 100644
index 000000000000..4a7c1d1ec799
--- /dev/null
+++ b/framework/source/dispatch/dispatchprovider.cxx
@@ -0,0 +1,798 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <stdio.h>
+#include <dispatch/dispatchprovider.hxx>
+#include <loadenv/loadenv.hxx>
+#include <dispatch/loaddispatcher.hxx>
+#include <dispatch/closedispatcher.hxx>
+#include <dispatch/menudispatcher.hxx>
+#include <dispatch/helpagentdispatcher.hxx>
+#include <dispatch/startmoduledispatcher.hxx>
+
+#include <pattern/window.hxx>
+#include <threadhelp/transactionguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <dispatchcommands.h>
+#include <protocols.h>
+#include <services.h>
+#include <targets.h>
+#include <general.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/ucb/XContentProviderManager.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <osl/diagnose.h>
+#include <rtl/string.h>
+#include <rtl/ustring.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_2( DispatchProvider ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::frame::XDispatchProvider)
+ )
+
+DEFINE_XTYPEPROVIDER_2( DispatchProvider ,
+ css::lang::XTypeProvider ,
+ css::frame::XDispatchProvider
+ )
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short standard ctor/dtor
+ @descr These initialize a new instance of tihs class with needed informations for work.
+ We hold a weakreference to our owner frame which start dispatches at us.
+ We can't use a normal reference because he hold a reference of us too ...
+ nobody can die so ...!
+
+ @seealso using at owner
+
+ @param xFactory
+ reference to servicemanager to create new services.
+ @param xFrame
+ reference to our owner frame.
+
+ @modified 17.05.2002 10:07, as96863
+*/
+DispatchProvider::DispatchProvider( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory ,
+ const css::uno::Reference< css::frame::XFrame >& xFrame )
+ // Init baseclasses first
+ : ThreadHelpBase( &Application::GetSolarMutex() )
+ , OWeakObject ( )
+ // Init member
+ , m_xFactory ( xFactory )
+ , m_xFrame ( xFrame )
+{
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short protected(!) dtor for deinitializing
+ @descr We made it protected to prevent using of us as base class instead as a member.
+
+ @modified 17.05.2002 10:05, as96863
+ */
+DispatchProvider::~DispatchProvider()
+{
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @interface XDispatchProvider
+ @short search a dispatcher for given URL
+ @descr If no interceptor is set on owner, we search for right frame and dispatch URL to it.
+ If no frame was found, we do nothing.
+ But we doesn't do it directly here. We detect the type of our owner frame and calls
+ specialized queryDispatch() helper dependen from that. Because a Desktop handle some
+ requests in another way then a normal frame.
+
+ @param aURL
+ URL to dispatch.
+ @param sTargetFrameName
+ name of searched frame.
+ @param nSearchFlags
+ flags for searching.
+ @return A reference to a dispatch object for this URL (if someone was found!).
+
+ @threadsafe yes
+ @modified 17.05.2002 10:59, as96863
+*/
+css::uno::Reference< css::frame::XDispatch > SAL_CALL DispatchProvider::queryDispatch( const css::util::URL& aURL ,
+ const ::rtl::OUString& sTargetFrameName ,
+ sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatcher;
+
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::frame::XFrame > xOwner( m_xFrame.get(), css::uno::UNO_QUERY );
+ aReadLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::frame::XDesktop > xDesktopCheck( xOwner, css::uno::UNO_QUERY );
+
+ if (xDesktopCheck.is())
+ xDispatcher = implts_queryDesktopDispatch(xOwner, aURL, sTargetFrameName, nSearchFlags);
+ else
+ xDispatcher = implts_queryFrameDispatch(xOwner, aURL, sTargetFrameName, nSearchFlags);
+
+ return xDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @interface XDispatchProvider
+ @short do the same like queryDispatch() ... but handle multiple dispatches at the same time
+ @descr It's an optimism. User give us a list of queries ... and we return a list of dispatcher.
+ If one of given queries couldn't be solved to a real existing dispatcher ...
+ we return a list with empty references in it! Order of both lists will be retained!
+
+ @seealso method queryDispatch()
+
+ @param lDescriptions
+ a list of all dispatch parameters for multiple requests
+ @return A reference a list of dispatch objects for these URLs - may with some <NULL/> values inside.
+
+ @threadsafe yes
+ @modified 17.05.2002 09:55, as96863
+*/
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL DispatchProvider::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptions ) throw( css::uno::RuntimeException )
+{
+ // Create return list - which must have same size then the given descriptor
+ // It's not allowed to pack it!
+ sal_Int32 nCount = lDescriptions.getLength();
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
+
+ // Step over all descriptors and try to get any dispatcher for it.
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ lDispatcher[i] = queryDispatch( lDescriptions[i].FeatureURL ,
+ lDescriptions[i].FrameName ,
+ lDescriptions[i].SearchFlags );
+ }
+
+ return lDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+::sal_Bool lcl_isStartModuleDispatch (const css::util::URL& aURL)
+{
+ return (aURL.Complete.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(CMD_UNO_SHOWSTARTMODULE)));
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short helper for queryDispatch()
+ @descr Every member of the frame tree (frame, desktop) must handle such request
+ in another way. So we implement different specialized metods for every one.
+
+ @threadsafe yes
+ @modified 20.08.2003 08:32, as96863
+ */
+css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_queryDesktopDispatch( const css::uno::Reference< css::frame::XFrame > xDesktop ,
+ const css::util::URL& aURL ,
+ const ::rtl::OUString& sTargetFrameName ,
+ sal_Int32 nSearchFlags )
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatcher;
+
+ // ignore wrong requests which are not supported
+ if (
+ (sTargetFrameName==SPECIALTARGET_MENUBAR ) || // valid for frame dispatches - not for desktop
+ (sTargetFrameName==SPECIALTARGET_HELPAGENT) || // valid for frame dispatches - not for desktop
+ (sTargetFrameName==SPECIALTARGET_PARENT ) || // we have no parent by definition
+ (sTargetFrameName==SPECIALTARGET_BEAMER ) // beamer frames are allowed as child of tasks only -
+ // and they exist more then ones. We have no idea which our sub tasks is the right one
+ )
+ {
+ return NULL;
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I) handle special cases which not right for using findFrame() first
+ //-----------------------------------------------------------------------------------------------------
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.I) "_blank"
+ // It's not the right place to create a new task here - because we are queried for a dispatch object
+ // only, which can handle such request. Such dispatcher should create the required task on demand.
+ // Normaly the functionality for "_blank" is provided by findFrame() - but that would create it directly
+ // here. Thats why we must "intercept" here.
+ //-----------------------------------------------------------------------------------------------------
+ if (sTargetFrameName==SPECIALTARGET_BLANK)
+ {
+ if (implts_isLoadableContent(aURL))
+ xDispatcher = implts_getOrCreateDispatchHelper( E_BLANKDISPATCHER, xDesktop );
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.II) "_default"
+ // This is a combination of search an empty task for recycling - or create a new one.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (sTargetFrameName==SPECIALTARGET_DEFAULT)
+ {
+ if (implts_isLoadableContent(aURL))
+ xDispatcher = implts_getOrCreateDispatchHelper( E_DEFAULTDISPATCHER, xDesktop );
+
+ if (lcl_isStartModuleDispatch(aURL))
+ xDispatcher = implts_getOrCreateDispatchHelper( E_STARTMODULEDISPATCHER, xDesktop );
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.III) "_self", "", "_top"
+ // The desktop can't load any document - but he can handle some special protocols like "uno", "slot" ...
+ // Why is "top" here handled too? Because the desktop is the topest frame. Normaly it's superflous
+ // to use this target - but we can handle it in the same manner then "_self".
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (
+ (sTargetFrameName==SPECIALTARGET_SELF) ||
+ (sTargetFrameName==SPECIALTARGET_TOP ) ||
+ (sTargetFrameName.getLength()<1 )
+ )
+ {
+ xDispatcher = implts_searchProtocolHandler(aURL);
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.IV) no further special targets exist
+ // Now we have to search for the right target frame by calling findFrame() - but should provide our code
+ // against creation of a new task if no frame could be found.
+ // I said it b efore - it's allowed for dispatch() only.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ {
+ sal_Int32 nRightFlags = nSearchFlags;
+ nRightFlags &= ~css::frame::FrameSearchFlag::CREATE;
+
+ // try to find any existing target and ask him for his dispatcher
+ css::uno::Reference< css::frame::XFrame > xFoundFrame = xDesktop->findFrame(sTargetFrameName, nRightFlags);
+ if (xFoundFrame.is())
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider( xFoundFrame, css::uno::UNO_QUERY );
+ xDispatcher = xProvider->queryDispatch(aURL,SPECIALTARGET_SELF,0);
+ }
+ else
+ // if it couldn't be found - but creation was allowed
+ // use special dispatcher for creatio or froward it to the browser
+ if (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
+ xDispatcher = implts_getOrCreateDispatchHelper( E_CREATEDISPATCHER, xDesktop, sTargetFrameName, nSearchFlags );
+ }
+
+ return xDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_queryFrameDispatch( const css::uno::Reference< css::frame::XFrame > xFrame ,
+ const css::util::URL& aURL ,
+ const ::rtl::OUString& sTargetFrameName ,
+ sal_Int32 nSearchFlags )
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatcher;
+
+ //-----------------------------------------------------------------------------------------------------
+ // 0) Some URLs are dispatched in a generic way (e.g. by the menu) using the default target "".
+ // But they are specified to use her own fix target. Detect such URLs here and use the correct target.
+ //-----------------------------------------------------------------------------------------------------
+
+ ::rtl::OUString sTargetName = sTargetFrameName;
+
+ //-----------------------------------------------------------------------------------------------------
+ // I) handle special cases which not right for using findFrame() first
+ //-----------------------------------------------------------------------------------------------------
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.I) "_blank", "_default"
+ // It's not the right place to create a new task here. Only the desktop can do that.
+ // Normaly the functionality for "_blank" is provided by findFrame() - but that would create it directly
+ // here. Thats why we must "intercept" here.
+ //-----------------------------------------------------------------------------------------------------
+ if (
+ (sTargetName==SPECIALTARGET_BLANK ) ||
+ (sTargetName==SPECIALTARGET_DEFAULT)
+ )
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
+ if (xParent.is())
+ xDispatcher = xParent->queryDispatch(aURL, sTargetName, 0); // its a special target - ignore search flags
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.II) "_menubar"
+ // Special mode on frame or task to receive the local menu. Not supported by findFrame()
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (sTargetName==SPECIALTARGET_MENUBAR)
+ {
+ xDispatcher = implts_getOrCreateDispatchHelper( E_MENUDISPATCHER, xFrame );
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.III) "_helpagent"
+ // Special mode on frame or task to start the help agent.
+ // It's defined for top level frames only.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (sTargetName==SPECIALTARGET_HELPAGENT)
+ {
+ if (WindowHelper::isTopWindow(xFrame->getContainerWindow()))
+ xDispatcher = implts_getOrCreateDispatchHelper( E_HELPAGENTDISPATCHER, xFrame );
+ else
+ {
+ // Don''t use findFrame() here - because it's not possible to find
+ // a top lebel frame without knowing his name. And a frame with name
+ // "" can't be realy searched! That's why forward query to any parent
+ // explicitly.
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider( xFrame->getCreator(), css::uno::UNO_QUERY );
+ if (xProvider.is())
+ xDispatcher = xProvider->queryDispatch(aURL,SPECIALTARGET_HELPAGENT,0);
+ }
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.IV) "_helpagent"
+ // Special sub frame of a top frame only. Search or create it. ... OK it's currently a little bit HACKI.
+ // Only the sfx (means the controller) can create it it.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (sTargetName==SPECIALTARGET_BEAMER)
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xBeamer( xFrame->findFrame( SPECIALTARGET_BEAMER, css::frame::FrameSearchFlag::CHILDREN | css::frame::FrameSearchFlag::SELF ), css::uno::UNO_QUERY );
+ if (xBeamer.is())
+ {
+ xDispatcher = xBeamer->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
+ }
+ else
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xController( xFrame->getController(), css::uno::UNO_QUERY );
+ if (xController.is())
+ // force using of special target - but use original search flags
+ // May the caller used the CREATE flag or not!
+ xDispatcher = xController->queryDispatch(aURL, SPECIALTARGET_BEAMER, nSearchFlags);
+ }
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.V) "_parent"
+ // Our parent frame (if it exist) should handle this URL.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (sTargetName==SPECIALTARGET_PARENT)
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
+ if (xParent.is())
+ // SELF => we must adress the parent directly... and not his parent or any other parent!
+ xDispatcher = xParent->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.VI) "_top"
+ // This request must be forwarded to any parent frame, till we reach a top frame.
+ // If no parent exist, we can handle itself.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (sTargetName==SPECIALTARGET_TOP)
+ {
+ if (xFrame->isTop())
+ {
+ // If we are this top frame itself (means our owner frame)
+ // we should call ourself recursiv with a better target "_self".
+ // So we can share the same code! (see reaction for "_self" inside this method too.)
+ xDispatcher = this->queryDispatch(aURL,SPECIALTARGET_SELF,0);
+ }
+ else
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
+ // Normaly if isTop() returned sal_False ... the parent frame MUST(!) exist ...
+ // But it seams to be better to check that here to prevent us against an access violation.
+ if (xParent.is())
+ xDispatcher = xParent->queryDispatch(aURL, SPECIALTARGET_TOP, 0);
+ }
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.VII) "_self", ""
+ // Our owner frame should handle this URL. But we can't do it for all of them.
+ // So we ask the internal setted controller first. If he disagree we try to find a registered
+ // protocol handler. If this failed too - we check for a loadable content and in case of true
+ // we load it into the frame by returning specilized dispatch object.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (
+ (sTargetName==SPECIALTARGET_SELF) ||
+ (sTargetName.getLength()<1 )
+ )
+ {
+ // There exist a hard coded interception for special URLs.
+ if (
+ (aURL.Complete.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".uno:CloseDoc"))) ||
+ (aURL.Complete.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".uno:CloseWin")))
+ )
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
+ // In case the frame is not a top one, is not based on system window and has a parent,
+ // the parent frame should to be queried for the correct dispatcher.
+ // See i93473
+ if (
+ !WindowHelper::isTopWindow(xFrame->getContainerWindow()) &&
+ !VCLUnoHelper::GetWindow(xFrame->getContainerWindow())->IsSystemWindow() &&
+ xParent.is()
+ )
+ xDispatcher = xParent->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
+ else
+ xDispatcher = implts_getOrCreateDispatchHelper( E_CLOSEDISPATCHER, xFrame );
+ }
+ else if (aURL.Complete.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".uno:CloseFrame")))
+ xDispatcher = implts_getOrCreateDispatchHelper( E_CLOSEDISPATCHER, xFrame );
+
+ if ( ! xDispatcher.is())
+ {
+ // Ask our controller for his agreement for these dispatched URL ...
+ // because some URLs are internal and can be handled faster by SFX - which most is the current controller!
+ // But in case of e.g. the bibliography not all queries will be handled successfully here.
+ css::uno::Reference< css::frame::XDispatchProvider > xController( xFrame->getController(), css::uno::UNO_QUERY );
+ if (xController.is())
+ xDispatcher = xController->queryDispatch(aURL, SPECIALTARGET_SELF, 0);
+ }
+
+ // If controller has no fun to dispatch these URL - we must search another right dispatcher.
+ // Search for any registered protocol handler first.
+ if (!xDispatcher.is())
+ xDispatcher = implts_searchProtocolHandler(aURL);
+
+ // Not for controller - not for protocol handler
+ // It should be a loadable content - may be a file. Check it ...
+ // This check is neccessary to found out, that
+ // support for some protocols isn't installed by user. May be
+ // "ftp" isn't available. So we suppress creation of our self dispatcher.
+ // The result will be clear. He can't handle it - but he would try it.
+ if (
+ ( ! xDispatcher.is() ) &&
+ ( implts_isLoadableContent(aURL) )
+ )
+ {
+ xDispatcher = implts_getOrCreateDispatchHelper( E_SELFDISPATCHER, xFrame );
+ }
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.VI) no further special handlings exist
+ // Now we have to search for the right target frame by calling findFrame() - but should provide our code
+ // against creation of a new task if no frame could be found.
+ // I said it before - it's allowed for dispatch() only.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ {
+ sal_Int32 nRightFlags = nSearchFlags;
+ nRightFlags &= ~css::frame::FrameSearchFlag::CREATE;
+
+ // try to find any existing target and ask him for his dispatcher
+ css::uno::Reference< css::frame::XFrame > xFoundFrame = xFrame->findFrame(sTargetName, nRightFlags);
+ if (xFoundFrame.is())
+ {
+ // Attention: Found target is our own owner frame!
+ // Don't ask him for his dispatcher. We know it already - it's our self dispatch helper.
+ // Otherwhise we can start a never ending recursiv call. Why?
+ // Somewere called our owner frame - he called some interceptor objects - and may by this dispatch provider
+ // is called. If wa use queryDispatch() on our owner frame again - we start this call stack again ... and again.
+ if (xFoundFrame==xFrame)
+ xDispatcher = implts_getOrCreateDispatchHelper( E_SELFDISPATCHER, xFrame );
+ else
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider( xFoundFrame, css::uno::UNO_QUERY );
+ xDispatcher = xProvider->queryDispatch(aURL,SPECIALTARGET_SELF,0);
+ }
+ }
+ else
+ // if it couldn't be found - but creation was allowed
+ // forward request to the desktop.
+ // Note: The given target name must be used to set the name on new created task!
+ // Don't forward request by changing it to a special one e.g _blank.
+ // Use the CREATE flag only to prevent call against further searches.
+ // We already know it - the target must be created new.
+ if (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xParent( xFrame->getCreator(), css::uno::UNO_QUERY );
+ if (xParent.is())
+ xDispatcher = xParent->queryDispatch(aURL, sTargetName, css::frame::FrameSearchFlag::CREATE);
+ }
+ }
+
+ return xDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short search for a registered protocol handler and ask him for a dispatch object
+ @descr Wes earch a suitable handler inside our cfg package org.openoffice.Office.ProtocolHandler.
+ If we found anyone, we create and initialize it. Initialize means: we set our owner frame on it
+ as context information. He can use it or leave it. Of course - we are aware of handler implementations,
+ which doesn't support initialization. It's an optional feature.
+
+ @param aURL
+ the dispatch URL for which may a handler is registered
+
+ @return A dispatch object if a handler was found and agree with the given URL or <NULL/> otherwhise.
+
+ @threadsafe yes
+ @modified 05.09.2002 13:43, as96863
+*/
+css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_searchProtocolHandler( const css::util::URL& aURL )
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatcher;
+ ProtocolHandler aHandler ;
+
+ // This member is threadsafe by himself and lives if we live - we doesn't need any mutex here.
+ if (m_aProtocolHandlerCache.search(aURL,&aHandler))
+ {
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+
+ // create it
+ css::uno::Reference< css::frame::XDispatchProvider > xHandler;
+ try
+ {
+ xHandler = css::uno::Reference< css::frame::XDispatchProvider >(
+ m_xFactory->createInstance(aHandler.m_sUNOName),
+ css::uno::UNO_QUERY);
+ }
+ catch(css::uno::Exception&) {}
+
+ // look if initialization is neccessary
+ css::uno::Reference< css::lang::XInitialization > xInit( xHandler, css::uno::UNO_QUERY );
+ if (xInit.is())
+ {
+ css::uno::Reference< css::frame::XFrame > xOwner( m_xFrame.get(), css::uno::UNO_QUERY );
+ LOG_ASSERT(xOwner.is(), "DispatchProvider::implts_searchProtocolHandler()\nCouldn't get reference to my owner frame. So I can't set may needed context information for this protocol handler.")
+ if (xOwner.is())
+ {
+ try
+ {
+ // but do it only, if all context informations are OK
+ css::uno::Sequence< css::uno::Any > lContext(1);
+ lContext[0] <<= xOwner;
+ xInit->initialize(lContext);
+ }
+ catch(css::uno::Exception&) {}
+ }
+ }
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ // ask for his (sub)dispatcher for the given URL
+ if (xHandler.is())
+ xDispatcher = xHandler->queryDispatch(aURL,SPECIALTARGET_SELF,0);
+ }
+
+ return xDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short get or create new dispatch helper
+ @descr Sometimes we need some helper implementations to support dispatching of special URLs or commands.
+ But it's not a good idea to hold these services for the whole life time of this provider instance.
+ We should create it on demand ...
+ Thats why we implement this method. It return an already existing helper or create a new one otherwise.
+
+ @attention The parameter sTarget and nSearchFlags are defaulted to "" and 0!
+ Please use it only, if you can be shure, that the realy given by the outside calli!
+ Mostly it depends from the parameter eHelper is they are required or not.
+
+ @param eHelper
+ specify the requested dispatch helper
+ @param xOwner
+ the target of possible dispatch() call on created dispatch helper
+ @param sTarget
+ the target parameter of the original queryDispatch() request
+ @param nSearchFlags
+ the flags parameter of the original queryDispatch() request
+ @return A reference to a dispatch helper.
+
+ @threadsafe yes
+ @modified 20.08.2003 10:22, as96863
+*/
+css::uno::Reference< css::frame::XDispatch > DispatchProvider::implts_getOrCreateDispatchHelper( EDispatchHelper eHelper ,
+ const css::uno::Reference< css::frame::XFrame >& xOwner ,
+ const ::rtl::OUString& sTarget ,
+ sal_Int32 nSearchFlags)
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatchHelper;
+
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ switch (eHelper)
+ {
+ case E_MENUDISPATCHER :
+ {
+ // Attention: Such menue dispatcher must be a singleton for this frame - means our owner frame.
+ // Otherwhise he can make some trouble.
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ if ( ! m_xMenuDispatcher.is() )
+ {
+ MenuDispatcher* pDispatcher = new MenuDispatcher( xFactory, xOwner );
+ m_xMenuDispatcher = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
+ }
+ xDispatchHelper = m_xMenuDispatcher;
+ aWriteLock.unlock();
+ /* } SAFE */
+ }
+ break;
+
+ case E_HELPAGENTDISPATCHER :
+ {
+ // Attention: It's not a good idea to create this help agent twice for the same frame (window)
+ // May it will be shown twice too - and user activate the first one. Then he get the corresponding
+ // help window ... but there exist another help agent window on bottom side of the frame window.
+ // It's superflous. Create it on demand - but hold it alive till this provider dies.
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ if ( ! m_xHelpAgentDispatcher.is() )
+ {
+ HelpAgentDispatcher* pDispatcher = new HelpAgentDispatcher( xOwner );
+ m_xHelpAgentDispatcher = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
+ }
+ xDispatchHelper = m_xHelpAgentDispatcher;
+ aWriteLock.unlock();
+ /* } SAFE */
+ }
+ break;
+
+ case E_CREATEDISPATCHER :
+ {
+ LoadDispatcher* pDispatcher = new LoadDispatcher(xFactory, xOwner, sTarget, nSearchFlags);
+ xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
+ }
+ break;
+
+ case E_BLANKDISPATCHER :
+ {
+ css::uno::Reference< css::frame::XFrame > xDesktop( xOwner, css::uno::UNO_QUERY );
+ if (xDesktop.is())
+ {
+ LoadDispatcher* pDispatcher = new LoadDispatcher(xFactory, xOwner, SPECIALTARGET_BLANK, 0);
+ xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
+ }
+ }
+ break;
+
+ case E_DEFAULTDISPATCHER :
+ {
+ css::uno::Reference< css::frame::XFrame > xDesktop( xOwner, css::uno::UNO_QUERY );
+ if (xDesktop.is())
+ {
+ LoadDispatcher* pDispatcher = new LoadDispatcher(xFactory, xOwner, SPECIALTARGET_DEFAULT, 0);
+ xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
+ }
+ }
+ break;
+
+ case E_SELFDISPATCHER :
+ {
+ LoadDispatcher* pDispatcher = new LoadDispatcher(xFactory, xOwner, SPECIALTARGET_SELF, 0);
+ xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
+ }
+ break;
+
+ case E_CLOSEDISPATCHER :
+ {
+ CloseDispatcher* pDispatcher = new CloseDispatcher( xFactory, xOwner, sTarget );
+ xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
+ }
+ break;
+
+ case E_STARTMODULEDISPATCHER :
+ {
+ StartModuleDispatcher* pDispatcher = new StartModuleDispatcher( xFactory, xOwner, sTarget );
+ xDispatchHelper = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(pDispatcher), css::uno::UNO_QUERY );
+ }
+ break;
+ }
+
+ return xDispatchHelper;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short check URL for support by our used loader or handler
+ @descr If we must return our own dispatch helper implementations (self, blank, create dispatcher!)
+ we should be shure, that URL describe any loadable content. Otherwise slot/uno URLs
+ will be detected ... but there exist nothing for ral loading into a target frame!
+
+ @param aURL
+ URL which should be "detected"
+ @return <TRUE/> if somewhere could handle that - <FALSE/> otherwise.
+
+ @threadsafe yes
+ @modified 17.05.2002 09:47, as96863
+*/
+sal_Bool DispatchProvider::implts_isLoadableContent( const css::util::URL& aURL )
+{
+ LoadEnv::EContentType eType = LoadEnv::classifyContent(aURL.Complete, css::uno::Sequence< css::beans::PropertyValue >());
+ return ( eType == LoadEnv::E_CAN_BE_LOADED );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/helpagentdispatcher.cxx b/framework/source/dispatch/helpagentdispatcher.cxx
new file mode 100644
index 000000000000..4ae8ac15ee6f
--- /dev/null
+++ b/framework/source/dispatch/helpagentdispatcher.cxx
@@ -0,0 +1,446 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <dispatch/helpagentdispatcher.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svtools/helpopt.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/help.hxx>
+
+namespace css = ::com::sun::star;
+
+//........................................................................
+namespace framework
+{
+
+//-----------------------------------------------
+DEFINE_XINTERFACE_4(HelpAgentDispatcher ,
+ OWeakObject ,
+ DIRECT_INTERFACE (css::lang::XTypeProvider ),
+ DIRECT_INTERFACE (css::frame::XDispatch ),
+ DIRECT_INTERFACE (css::awt::XWindowListener),
+ DIRECT_INTERFACE (css::lang::XEventListener))
+
+//-----------------------------------------------
+DEFINE_XTYPEPROVIDER_2(HelpAgentDispatcher ,
+ css::lang::XTypeProvider,
+ css::frame::XDispatch )
+
+//--------------------------------------------------------------------
+HelpAgentDispatcher::HelpAgentDispatcher( const css::uno::Reference< css::frame::XFrame >& xParentFrame)
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , m_sCurrentURL ( )
+ , m_xContainerWindow( )
+ , m_xAgentWindow ( )
+ , m_aTimer ( )
+ , m_xSelfHold ( )
+{
+ // It's required that this class has to be contructed with a valid frame.
+ // And "valid" means: the frame must already bound to a valid container window.
+ m_xContainerWindow = xParentFrame->getContainerWindow();
+}
+
+//--------------------------------------------------------------------
+HelpAgentDispatcher::~HelpAgentDispatcher()
+{
+ implts_stopTimer();
+ implts_ignoreCurrentURL();
+
+ // Needed ... because it was create as "new VCLWindow()" ! Such windows must be disposed explicitly.
+ css::uno::Reference< css::lang::XComponent > xAgentWindow(m_xAgentWindow, css::uno::UNO_QUERY);
+ if (xAgentWindow.is())
+ xAgentWindow->dispose();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL HelpAgentDispatcher::dispatch(const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >&)
+ throw(css::uno::RuntimeException)
+{
+ // silently drop the request if the new URL was marked to be ignored next time.
+ sal_Int32 nAllowedToIgnore = SvtHelpOptions().getAgentIgnoreURLCounter(aURL.Complete);
+ if (nAllowedToIgnore < 1)
+ return;
+
+ // stop the expiration timer for the old URL
+ // The timer will add the old URL to the list of ignorable URLs.
+ // So m_sCurrentURL must be set AFTER the timer was stopped !!!
+ implts_stopTimer();
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ m_sCurrentURL = aURL.Complete;
+ aWriteLock.unlock();
+ // <- SAFE
+
+ // start the expiration timer for the new URL
+ implts_startTimer();
+
+ // make sure the agent window is shown
+ implts_showAgentWindow();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL HelpAgentDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&,
+ const css::util::URL&)
+ throw(css::uno::RuntimeException)
+{
+ // no status available
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL HelpAgentDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&,
+ const css::util::URL&)
+ throw(css::uno::RuntimeException)
+{
+ // no status available
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL HelpAgentDispatcher::windowResized(const css::awt::WindowEvent&)
+ throw(css::uno::RuntimeException)
+{
+ implts_positionAgentWindow();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL HelpAgentDispatcher::windowMoved(const css::awt::WindowEvent&)
+ throw(css::uno::RuntimeException)
+{
+ implts_positionAgentWindow();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL HelpAgentDispatcher::windowShown(const css::lang::EventObject&)
+ throw(css::uno::RuntimeException)
+{
+ implts_showAgentWindow();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL HelpAgentDispatcher::windowHidden(const css::lang::EventObject&)
+ throw(css::uno::RuntimeException)
+{
+ implts_hideAgentWindow();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL HelpAgentDispatcher::disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+
+ // Already disposed ?!
+ if (! m_xContainerWindow.is())
+ return;
+ // Wrong broadcaster ?!
+ if (aEvent.Source != m_xContainerWindow)
+ return;
+
+ css::uno::Reference< css::uno::XInterface > xSelfHoldUntilMethodEnds(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW);
+ m_xSelfHold.clear();
+
+ aWriteLock.unlock();
+ // <- SAFE
+
+ implts_stopTimer();
+ implts_hideAgentWindow();
+ implts_ignoreCurrentURL();
+
+ // SAFE ->
+ aWriteLock.lock();
+ m_xContainerWindow.clear();
+ css::uno::Reference< css::lang::XComponent > xAgentWindow(m_xAgentWindow, css::uno::UNO_QUERY);
+ m_xAgentWindow.clear();
+ aWriteLock.unlock();
+ // <- SAFE
+
+ // Needed ... because it was create as "new VCLWindow()" ! Such windows must be disposed explicitly.
+ if (xAgentWindow.is())
+ xAgentWindow->dispose();
+}
+
+//--------------------------------------------------------------------
+void HelpAgentDispatcher::helpRequested()
+{
+ implts_stopTimer();
+ implts_hideAgentWindow();
+ implts_acceptCurrentURL();
+}
+
+//-----------------------------------------------
+void HelpAgentDispatcher::closeAgent()
+{
+ implts_stopTimer();
+ implts_hideAgentWindow();
+ implts_ignoreCurrentURL();
+}
+
+//--------------------------------------------------------------------
+void HelpAgentDispatcher::implts_acceptCurrentURL()
+{
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+
+ ::rtl::OUString sAcceptedURL = m_sCurrentURL;
+ m_sCurrentURL = ::rtl::OUString();
+
+ aWriteLock.unlock();
+ // <- SAFE
+
+ // We must make sure that this URL isnt marked as ignored by the user.
+ // Otherwhise the user wont see the corresponding help content in the future.
+ SvtHelpOptions().resetAgentIgnoreURLCounter(sAcceptedURL);
+
+ // show the right help content
+ // SOLAR SAFE ->
+ {
+ SolarMutexGuard aSolarLock;
+ Help* pHelp = Application::GetHelp();
+ if (pHelp)
+ pHelp->Start(sAcceptedURL, NULL);
+ }
+ // <- SOLAR SAFE
+}
+
+//--------------------------------------------------------------------
+void HelpAgentDispatcher::implts_ignoreCurrentURL()
+{
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+
+ ::rtl::OUString sIgnoredURL = m_sCurrentURL;
+ m_sCurrentURL = ::rtl::OUString();
+
+ aWriteLock.unlock();
+ // <- SAFE
+
+ if (sIgnoredURL.getLength())
+ SvtHelpOptions().decAgentIgnoreURLCounter(sIgnoredURL);
+}
+
+//--------------------------------------------------------------------
+void HelpAgentDispatcher::implts_stopTimer()
+{
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ m_xSelfHold.clear();
+ aWriteLock.unlock();
+ // <- SAFE
+
+ // SOLAR SAFE ->
+ // Timer access needs no "own lock" ! It lives if we live ...
+ // But it requires locking of the solar mutex ... because it's a vcl based timer.
+ {
+ SolarMutexGuard aSolarLock;
+ if (! m_aTimer.IsActive())
+ return;
+ m_aTimer.Stop();
+ }
+ // <- SOLAR SAFE
+}
+
+//--------------------------------------------------------------------
+void HelpAgentDispatcher::implts_startTimer()
+{
+ // SOLAR SAFE ->
+ // Timer access needs no "own lock" ! It lives if we live ...
+ // But it requires locking of the solar mutex ... because it's a vcl based timer.
+ {
+ SolarMutexGuard aSolarLock;
+ if (m_aTimer.IsActive())
+ return;
+ }
+ // <- SOLAR SAFE
+
+ // SAFE ->
+ // Timer uses pointer to this help agent dispatcher ...
+ // But normaly we are ref counted. So we must make sure that this
+ // dispatcher isnt killed during the timer runs .-)
+ WriteGuard aWriteLock(m_aLock);
+ m_xSelfHold = css::uno::Reference< css::uno::XInterface >(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW);
+ aWriteLock.unlock();
+ // <- SAFE
+
+ sal_Int32 nTime = SvtHelpOptions().GetHelpAgentTimeoutPeriod();
+
+ // SOLAR SAFE ->
+ // Timer access needs no "own lock" ! It lives if we live ...
+ // But it requires locking of the solar mutex ... because it's a vcl based timer.
+ {
+ SolarMutexGuard aSolarLock;
+ m_aTimer.SetTimeout(nTime*1000); // sec => ms !
+ m_aTimer.Start();
+ }
+}
+
+//-----------------------------------------------
+IMPL_LINK(HelpAgentDispatcher, implts_timerExpired, void*,)
+{
+ // This method is called by using a pointer to us.
+ // But we must be aware that we can be destroyed hardly
+ // if our uno reference will be gone!
+ // => Hold this object alive till this method finish its work.
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ css::uno::Reference< css::uno::XInterface > xSelfHoldUntilMethodEnds(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW);
+ m_xSelfHold.clear();
+ aWriteLock.unlock();
+ // <- SAFE
+
+ implts_hideAgentWindow();
+ implts_ignoreCurrentURL();
+
+ return 0;
+}
+
+//--------------------------------------------------------------------
+void HelpAgentDispatcher::implts_showAgentWindow()
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::awt::XWindow2 > xContainerWindow(m_xContainerWindow, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow();
+
+ if (
+ (xContainerWindow.is() ) &&
+ (xAgentWindow.is() ) &&
+ (xContainerWindow->isVisible())
+ )
+ {
+ // make sure that agent window resists at the right place .-)
+ implts_positionAgentWindow();
+ xAgentWindow->setVisible(sal_True);
+ }
+}
+
+//--------------------------------------------------------------------
+void HelpAgentDispatcher::implts_hideAgentWindow()
+{
+ css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow();
+ if (xAgentWindow.is())
+ xAgentWindow->setVisible(sal_False);
+}
+
+//--------------------------------------------------------------------
+void HelpAgentDispatcher::implts_positionAgentWindow()
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
+ aReadLock.unlock();
+ // <- SAFE
+
+ css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow();
+ if (
+ (! xContainerWindow.is()) ||
+ (! xAgentWindow.is() )
+ )
+ return;
+
+ ::svt::HelpAgentWindow* pAgentWindow = (::svt::HelpAgentWindow*)VCLUnoHelper::GetWindow(xAgentWindow);
+ const css::awt::Rectangle aContainerSize = xContainerWindow->getPosSize();
+ const Size aAgentSize = pAgentWindow->getPreferredSizePixel();
+
+ sal_Int32 nW = aAgentSize.Width() ;
+ sal_Int32 nH = aAgentSize.Height();
+
+ if (nW < 1)
+ nW = 100;
+ if (nH < 1)
+ nH = 100;
+
+ sal_Int32 nX = aContainerSize.Width - nW;
+ sal_Int32 nY = aContainerSize.Height - nH;
+
+ // TODO: use a surrogate if the container window is too small to contain the full-sized agent window
+ xAgentWindow->setPosSize(nX, nY, nW, nH, css::awt::PosSize::POSSIZE);
+}
+
+//--------------------------------------------------------------------
+css::uno::Reference< css::awt::XWindow > HelpAgentDispatcher::implts_ensureAgentWindow()
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ if (m_xAgentWindow.is())
+ return m_xAgentWindow;
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
+ aReadLock.unlock();
+ // <- SAFE
+
+ if (!xContainerWindow.is())
+ return css::uno::Reference< css::awt::XWindow >();
+
+ ::svt::HelpAgentWindow* pAgentWindow = 0;
+ // SOLAR SAFE ->
+ {
+ SolarMutexGuard aSolarLock;
+ // create the agent window
+ Window* pContainerWindow = VCLUnoHelper::GetWindow(xContainerWindow);
+ pAgentWindow = new ::svt::HelpAgentWindow(pContainerWindow);
+ pAgentWindow->setCallback(this);
+ }
+ // <- SOLAR SAFE
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ m_xAgentWindow = VCLUnoHelper::GetInterface(pAgentWindow);
+ css::uno::Reference< css::awt::XWindow > xAgentWindow = m_xAgentWindow;
+ aWriteLock.unlock();
+ // <- SAFE
+
+ // add as window listener to the container window so we can maintain the property position of the agent window
+ xContainerWindow->addWindowListener(this);
+
+ // SOLAR SAFE ->
+ {
+ SolarMutexGuard aSolarLock;
+ // establish callback for our internal used timer.
+ // Note: Its only active, if the timer will be started ...
+ m_aTimer.SetTimeoutHdl(LINK(this, HelpAgentDispatcher, implts_timerExpired));
+ }
+ // <- SOLAR SAFE
+
+ return xAgentWindow;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/interceptionhelper.cxx b/framework/source/dispatch/interceptionhelper.cxx
new file mode 100644
index 000000000000..c9db19b8ac5e
--- /dev/null
+++ b/framework/source/dispatch/interceptionhelper.cxx
@@ -0,0 +1,343 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// my own includes
+
+#include <dispatch/interceptionhelper.hxx>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/frame/XInterceptorInfo.hpp>
+
+//_______________________________________________
+// includes of other projects
+#include <vcl/svapp.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//_______________________________________________
+// non exported const
+
+sal_Bool InterceptionHelper::m_bPreferrFirstInterceptor = sal_True;
+
+//_______________________________________________
+// non exported definitions
+
+//_______________________________________________
+// declarations
+
+/*-----------------------------------------------------------------------------
+ 31.03.2003 09:02
+-----------------------------------------------------------------------------*/
+DEFINE_XINTERFACE_3(InterceptionHelper ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::frame::XDispatchProvider ),
+ DIRECT_INTERFACE(css::frame::XDispatchProviderInterception),
+ DIRECT_INTERFACE(css::lang::XEventListener ))
+
+/*-----------------------------------------------------------------------------
+ 31.03.2003 09:02
+-----------------------------------------------------------------------------*/
+InterceptionHelper::InterceptionHelper(const css::uno::Reference< css::frame::XFrame >& xOwner,
+ const css::uno::Reference< css::frame::XDispatchProvider >& xSlave)
+ // Init baseclasses first
+ : ThreadHelpBase(&Application::GetSolarMutex())
+ , OWeakObject ( )
+ // Init member
+ , m_xOwnerWeak (xOwner )
+ , m_xSlave (xSlave )
+{
+}
+
+/*-----------------------------------------------------------------------------
+ 31.03.2003 09:02
+-----------------------------------------------------------------------------*/
+InterceptionHelper::~InterceptionHelper()
+{
+}
+
+/*-----------------------------------------------------------------------------
+ 31.03.2003 09:09
+-----------------------------------------------------------------------------*/
+css::uno::Reference< css::frame::XDispatch > SAL_CALL InterceptionHelper::queryDispatch(const css::util::URL& aURL ,
+ const ::rtl::OUString& sTargetFrameName,
+ sal_Int32 nSearchFlags )
+ throw(css::uno::RuntimeException)
+{
+ // SAFE {
+ ReadGuard aReadLock(m_aLock);
+
+ // a) first search an interceptor, which match to this URL by it's URL pattern registration
+ // Note: if it return NULL - it does not mean an empty interceptor list automaticly!
+ css::uno::Reference< css::frame::XDispatchProvider > xInterceptor;
+ InterceptorList::const_iterator pIt = m_lInterceptionRegs.findByPattern(aURL.Complete);
+ if (pIt != m_lInterceptionRegs.end())
+ xInterceptor = pIt->xInterceptor;
+
+ // b) No match by registration - but a valid interceptor list.
+ // Use first interceptor everytimes.
+ // Note: it doesn't matter, which direction this helper implementation use to ask interceptor objects.
+ // Using of member m_aInterceptorList will starts at the beginning everytimes.
+ // It depends from the filling operation, in which direction it works realy!
+ if (!xInterceptor.is() && m_lInterceptionRegs.size()>0)
+ {
+ pIt = m_lInterceptionRegs.begin();
+ xInterceptor = pIt->xInterceptor;
+ }
+
+ // c) No registered interceptor => use our direct slave.
+ // This helper exist by design and must be valid everytimes ...
+ // But to be more feature proof - we should check that .-)
+ if (!xInterceptor.is() && m_xSlave.is())
+ xInterceptor = m_xSlave;
+
+ aReadLock.unlock();
+ // } SAFE
+
+ css::uno::Reference< css::frame::XDispatch > xReturn;
+ if (xInterceptor.is())
+ xReturn = xInterceptor->queryDispatch(aURL, sTargetFrameName, nSearchFlags);
+ return xReturn;
+}
+
+/*-----------------------------------------------------------------------------
+ 31.03.2003 07:58
+-----------------------------------------------------------------------------*/
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL InterceptionHelper::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor )
+ throw(css::uno::RuntimeException)
+{
+ sal_Int32 c = lDescriptor.getLength();
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatches (c);
+ css::uno::Reference< css::frame::XDispatch >* pDispatches = lDispatches.getArray();
+ const css::frame::DispatchDescriptor* pDescriptor = lDescriptor.getConstArray();
+
+ for (sal_Int32 i=0; i<c; ++i)
+ pDispatches[i] = queryDispatch(pDescriptor[i].FeatureURL, pDescriptor[i].FrameName, pDescriptor[i].SearchFlags);
+
+ return lDispatches;
+}
+
+/*-----------------------------------------------------------------------------
+ 31.03.2003 10:20
+-----------------------------------------------------------------------------*/
+void SAL_CALL InterceptionHelper::registerDispatchProviderInterceptor(const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
+ throw(css::uno::RuntimeException)
+{
+ // reject wrong calling of this interface method
+ css::uno::Reference< css::frame::XDispatchProvider > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ if (!xInterceptor.is())
+ throw css::uno::RuntimeException(DECLARE_ASCII("NULL references not allowed as in parameter"), xThis);
+
+ // Fill a new info structure for new interceptor.
+ // Save his reference and try to get an additional URL/pattern list from him.
+ // If no list exist register these interceptor for all dispatch events with "*"!
+ InterceptorInfo aInfo;
+
+ aInfo.xInterceptor = css::uno::Reference< css::frame::XDispatchProvider >(xInterceptor, css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XInterceptorInfo > xInfo(xInterceptor, css::uno::UNO_QUERY);
+ if (xInfo.is())
+ aInfo.lURLPattern = xInfo->getInterceptedURLs();
+ else
+ {
+ aInfo.lURLPattern.realloc(1);
+ aInfo.lURLPattern[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*"));
+ }
+
+ // SAFE {
+ WriteGuard aWriteLock(m_aLock);
+
+ // a) no interceptor at all - set this instance as master for given interceptor
+ // and set our slave as it's slave - and put this interceptor to the list.
+ // It's place there doesn matter. Because this list is currently empty.
+ if (m_lInterceptionRegs.empty())
+ {
+ xInterceptor->setMasterDispatchProvider(xThis );
+ xInterceptor->setSlaveDispatchProvider (m_xSlave);
+ m_lInterceptionRegs.push_back(aInfo);
+ }
+
+ // b) OK - there is at least one interceptor already registered.
+ // It's slave and it's master must be valid references ...
+ // because we created it. But we have to look for the static bool which
+ // regulate direction of using of interceptor objects!
+
+ // b1) If "m_bPreferrFirstInterceptor" is set to true, we have to
+ // insert it behind any other existing interceptor - means at the end of our list.
+ else if (m_bPreferrFirstInterceptor)
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xMasterD = m_lInterceptionRegs.rbegin()->xInterceptor;
+ css::uno::Reference< css::frame::XDispatchProviderInterceptor > xMasterI (xMasterD, css::uno::UNO_QUERY);
+
+ xInterceptor->setMasterDispatchProvider(xMasterD );
+ xInterceptor->setSlaveDispatchProvider (m_xSlave );
+ xMasterI->setSlaveDispatchProvider (aInfo.xInterceptor);
+
+ m_lInterceptionRegs.push_back(aInfo);
+ }
+
+ // b2) If "m_bPreferrFirstInterceptor" is set to false, we have to
+ // insert it before any other existing interceptor - means at the beginning of our list.
+ else
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xSlaveD = m_lInterceptionRegs.begin()->xInterceptor;
+ css::uno::Reference< css::frame::XDispatchProviderInterceptor > xSlaveI (xSlaveD , css::uno::UNO_QUERY);
+
+ xInterceptor->setMasterDispatchProvider(xThis );
+ xInterceptor->setSlaveDispatchProvider (xSlaveD );
+ xSlaveI->setMasterDispatchProvider (aInfo.xInterceptor);
+
+ m_lInterceptionRegs.push_front(aInfo);
+ }
+
+ css::uno::Reference< css::frame::XFrame > xOwner(m_xOwnerWeak.get(), css::uno::UNO_QUERY);
+
+ aWriteLock.unlock();
+ // } SAFE
+
+ // Don't forget to send a frame action event "context changed".
+ // Any cached dispatch objects must be validated now!
+ if (xOwner.is())
+ xOwner->contextChanged();
+}
+
+/*-----------------------------------------------------------------------------
+ 31.03.2003 10:27
+-----------------------------------------------------------------------------*/
+void SAL_CALL InterceptionHelper::releaseDispatchProviderInterceptor(const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
+ throw(css::uno::RuntimeException)
+{
+ // reject wrong calling of this interface method
+ css::uno::Reference< css::frame::XDispatchProvider > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ if (!xInterceptor.is())
+ throw css::uno::RuntimeException(DECLARE_ASCII("NULL references not allowed as in parameter"), xThis);
+
+ // SAFE {
+ WriteGuard aWriteLock(m_aLock);
+
+ // search this interceptor ...
+ // If it could be located inside cache -
+ // use it's slave/master relations to update the interception list;
+ // set empty references for it as new master and slave;
+ // and relase it from out cache.
+ InterceptorList::iterator pIt = m_lInterceptionRegs.findByReference(xInterceptor);
+ if (pIt != m_lInterceptionRegs.end())
+ {
+ css::uno::Reference< css::frame::XDispatchProvider > xSlaveD (xInterceptor->getSlaveDispatchProvider() , css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XDispatchProvider > xMasterD (xInterceptor->getMasterDispatchProvider(), css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XDispatchProviderInterceptor > xSlaveI (xSlaveD , css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XDispatchProviderInterceptor > xMasterI (xMasterD , css::uno::UNO_QUERY);
+
+ if (xMasterI.is())
+ xMasterI->setSlaveDispatchProvider(xSlaveD);
+
+ if (xSlaveI.is())
+ xSlaveI->setMasterDispatchProvider(xMasterD);
+
+ xInterceptor->setSlaveDispatchProvider (css::uno::Reference< css::frame::XDispatchProvider >());
+ xInterceptor->setMasterDispatchProvider(css::uno::Reference< css::frame::XDispatchProvider >());
+
+ m_lInterceptionRegs.erase(pIt);
+ }
+
+ css::uno::Reference< css::frame::XFrame > xOwner(m_xOwnerWeak.get(), css::uno::UNO_QUERY);
+
+ aWriteLock.unlock();
+ // } SAFE
+
+ // Don't forget to send a frame action event "context changed".
+ // Any cached dispatch objects must be validated now!
+ if (xOwner.is())
+ xOwner->contextChanged();
+}
+
+/*-----------------------------------------------------------------------------
+ 31.03.2003 10:31
+-----------------------------------------------------------------------------*/
+#define FORCE_DESTRUCTION_OF_INTERCEPTION_CHAIN
+void SAL_CALL InterceptionHelper::disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ #ifdef FORCE_DESTRUCTION_OF_INTERCEPTION_CHAIN
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ // check calli ... we accept such disposing call's only from our onwer frame.
+ css::uno::Reference< css::frame::XFrame > xOwner(m_xOwnerWeak.get(), css::uno::UNO_QUERY);
+ if (aEvent.Source != xOwner)
+ return;
+
+ // Because every interceptor hold at least one reference to us ... and we destruct this list
+ // of interception objects ... we should hold ourself alive .-)
+ css::uno::Reference< css::frame::XDispatchProvider > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY_THROW);
+
+ // We need a full copy of all currently registered interceptor objects.
+ // Otherwhise we cant iterate over this vector without the risk, that our iterator will be invalid.
+ // Because this vetor will be influenced by every deregistered interceptor.
+ InterceptionHelper::InterceptorList aCopy = m_lInterceptionRegs;
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ InterceptionHelper::InterceptorList::iterator pIt;
+ for ( pIt = aCopy.begin();
+ pIt != aCopy.end() ;
+ ++pIt )
+ {
+ InterceptionHelper::InterceptorInfo& rInfo = *pIt;
+ if (rInfo.xInterceptor.is())
+ {
+ css::uno::Reference< css::frame::XDispatchProviderInterceptor > xInterceptor(rInfo.xInterceptor, css::uno::UNO_QUERY_THROW);
+ releaseDispatchProviderInterceptor(xInterceptor);
+ rInfo.xInterceptor.clear();
+ }
+ }
+
+ aCopy.clear();
+
+ #if OSL_DEBUG_LEVEL > 0
+ // SAFE ->
+ aReadLock.lock();
+ if (!m_lInterceptionRegs.empty() )
+ OSL_FAIL("There are some pending interceptor objects, which seams to be registered during (!) the destruction of a frame.");
+ aReadLock.unlock();
+ // <- SAFE
+ #endif // ODL_DEBUG_LEVEL>0
+
+ #endif // FORCE_DESTRUCTION_OF_INTERCEPTION_CHAIN
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/loaddispatcher.cxx b/framework/source/dispatch/loaddispatcher.cxx
new file mode 100644
index 000000000000..31accd649aa7
--- /dev/null
+++ b/framework/source/dispatch/loaddispatcher.cxx
@@ -0,0 +1,201 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// my own includes
+#include <dispatch/loaddispatcher.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/frame/DispatchResultState.hpp>
+
+//_______________________________________________
+// includes of other projects
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// declarations
+
+/*-----------------------------------------------
+ 20.08.2003 09:52
+-----------------------------------------------*/
+LoadDispatcher::LoadDispatcher(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xOwnerFrame ,
+ const ::rtl::OUString sTargetName ,
+ sal_Int32 nSearchFlags)
+ : ThreadHelpBase( )
+ , m_xSMGR (xSMGR )
+ , m_xOwnerFrame (xOwnerFrame )
+ , m_sTarget (sTargetName )
+ , m_nSearchFlags(nSearchFlags)
+ , m_aLoader (xSMGR )
+{
+}
+
+/*-----------------------------------------------
+ 20.08.2003 09:12
+-----------------------------------------------*/
+LoadDispatcher::~LoadDispatcher()
+{
+ m_xSMGR.clear();
+}
+
+/*-----------------------------------------------
+ 20.08.2003 09:58
+-----------------------------------------------*/
+void SAL_CALL LoadDispatcher::dispatchWithNotification(const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
+ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
+ throw(css::uno::RuntimeException)
+{
+ impl_dispatch( aURL, lArguments, xListener );
+}
+
+/*-----------------------------------------------
+ 20.08.2003 09:16
+-----------------------------------------------*/
+void SAL_CALL LoadDispatcher::dispatch(const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
+ throw(css::uno::RuntimeException)
+{
+ impl_dispatch( aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >() );
+}
+
+/*-----------------------------------------------
+ 14.04.2008
+-----------------------------------------------*/
+css::uno::Any SAL_CALL LoadDispatcher::dispatchWithReturnValue( const css::util::URL& rURL,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
+ throw( css::uno::RuntimeException )
+{
+ return impl_dispatch( rURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >());
+}
+
+/*-----------------------------------------------
+ 20.08.2003 10:48
+-----------------------------------------------*/
+void SAL_CALL LoadDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
+ const css::util::URL& /*aURL*/ )
+ throw(css::uno::RuntimeException)
+{
+}
+
+/*-----------------------------------------------
+ 20.08.2003 10:49
+-----------------------------------------------*/
+void SAL_CALL LoadDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
+ const css::util::URL& /*aURL*/ )
+ throw(css::uno::RuntimeException)
+{
+}
+
+/*-----------------------------------------------
+ 20.08.2003 09:58
+-----------------------------------------------*/
+css::uno::Any LoadDispatcher::impl_dispatch( const css::util::URL& rURL,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
+ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
+{
+ // Attention: May be nobody outside hold such temp. dispatch object alive (because
+ // the container in which we resists isnt implemented threadsafe but updated by a timer
+ // and clear our reference ...) we should hold us self alive!
+ css::uno::Reference< css::uno::XInterface > xThis(static_cast< css::frame::XNotifyingDispatch* >(this), css::uno::UNO_QUERY);
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ // We are the only client of this load env object ... but
+ // may a dispatch request before is still in progress (?!).
+ // Then we should wait a little bit and block this new request.
+ // In case we run into the timeout, we should reject this new request
+ // and return "FAILED" as result. Otherwhise we can start this new operation.
+ if (!m_aLoader.waitWhileLoading(2000)) // => 2 sec.
+ {
+ if (xListener.is())
+ xListener->dispatchFinished(
+ css::frame::DispatchResultEvent(xThis, css::frame::DispatchResultState::DONTKNOW, css::uno::Any())); // DONTKNOW? ... not realy started ... not realy failed :-)
+ }
+
+ css::uno::Reference< css::frame::XFrame > xBaseFrame(m_xOwnerFrame.get(), css::uno::UNO_QUERY);
+ if (!xBaseFrame.is())
+ {
+ if (xListener.is())
+ xListener->dispatchFinished(
+ css::frame::DispatchResultEvent(xThis, css::frame::DispatchResultState::FAILURE, css::uno::Any()));
+ }
+
+ // OK ... now the internal loader seems to be useable for new requests
+ // and our owner frame seems to be valid for such operations.
+ // Initialize it with all new but needed properties and start the loading.
+ css::uno::Reference< css::lang::XComponent > xComponent;
+ try
+ {
+ m_aLoader.initializeLoading( rURL.Complete, lArguments, xBaseFrame, m_sTarget, m_nSearchFlags, (LoadEnv::EFeature)(LoadEnv::E_ALLOW_CONTENTHANDLER | LoadEnv::E_WORK_WITH_UI));
+ m_aLoader.startLoading();
+ m_aLoader.waitWhileLoading(); // wait for ever!
+ xComponent = m_aLoader.getTargetComponent();
+
+ // TODO thinking about asynchronous operations and listener support
+ }
+ catch(const LoadEnvException&)
+ { xComponent.clear(); }
+
+ if (xListener.is())
+ {
+ if (xComponent.is())
+ xListener->dispatchFinished(
+ css::frame::DispatchResultEvent(xThis, css::frame::DispatchResultState::SUCCESS, css::uno::Any()));
+ else
+ xListener->dispatchFinished(
+ css::frame::DispatchResultEvent(xThis, css::frame::DispatchResultState::FAILURE, css::uno::Any()));
+ }
+
+ // return the model - like loadComponentFromURL()
+ css::uno::Any aRet;
+ if ( xComponent.is () )
+ aRet = css::uno::makeAny( xComponent );
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+ return aRet;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/mailtodispatcher.cxx b/framework/source/dispatch/mailtodispatcher.cxx
new file mode 100644
index 000000000000..3c505540ae33
--- /dev/null
+++ b/framework/source/dispatch/mailtodispatcher.cxx
@@ -0,0 +1,333 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <dispatch/mailtodispatcher.hxx>
+#include <threadhelp/readguard.hxx>
+#include <general.h>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/system/XSystemShellExecute.hpp>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+#define PROTOCOL_VALUE "mailto:"
+#define PROTOCOL_LENGTH 7
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// XInterface, XTypeProvider, XServiceInfo
+
+DEFINE_XINTERFACE_5(MailToDispatcher ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::frame::XDispatchProvider ),
+ DIRECT_INTERFACE(css::frame::XNotifyingDispatch),
+ DIRECT_INTERFACE(css::frame::XDispatch ))
+
+DEFINE_XTYPEPROVIDER_5(MailToDispatcher ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::frame::XDispatchProvider ,
+ css::frame::XNotifyingDispatch,
+ css::frame::XDispatch )
+
+DEFINE_XSERVICEINFO_MULTISERVICE(MailToDispatcher ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_PROTOCOLHANDLER ,
+ IMPLEMENTATIONNAME_MAILTODISPATCHER)
+
+DEFINE_INIT_SERVICE(MailToDispatcher,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+ )
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short standard ctor
+ @descr These initialize a new instance of ths class with needed informations for work.
+
+ @param xFactory
+ reference to uno servicemanager for creation of new services
+
+ @modified 30.04.2002 14:10, as96863
+*/
+MailToDispatcher::MailToDispatcher( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+ // Init baseclasses first
+ : ThreadHelpBase( &Application::GetSolarMutex() )
+ , OWeakObject ( )
+ // Init member
+ , m_xFactory ( xFactory )
+{
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short standard dtor
+ @descr -
+
+ @modified 30.04.2002 14:10, as96863
+*/
+MailToDispatcher::~MailToDispatcher()
+{
+ m_xFactory = NULL;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short decide if this dispatch implementation can be used for requested URL or not
+ @descr A protocol handler is registerd for an URL pattern inside configuration and will
+ be asked by the generic dispatch mechanism inside framework, if he can handle this
+ special URL wich match his registration. He can agree by returning of a valid dispatch
+ instance or disagree by returning <NULL/>.
+ We don't create new dispatch instances here realy - we return THIS as result to handle it
+ at the same implementation.
+
+ @modified 02.05.2002 15:25, as96863
+*/
+css::uno::Reference< css::frame::XDispatch > SAL_CALL MailToDispatcher::queryDispatch( const css::util::URL& aURL ,
+ const ::rtl::OUString& /*sTarget*/ ,
+ sal_Int32 /*nFlags*/ ) throw( css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatcher;
+ if (aURL.Complete.compareToAscii(PROTOCOL_VALUE,PROTOCOL_LENGTH)==0)
+ xDispatcher = this;
+ return xDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short do the same like dispatch() but for multiple requests at the same time
+ @descr -
+
+ @modified 02.05.2002 15:27, as96863
+*/
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL MailToDispatcher::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException )
+{
+ sal_Int32 nCount = lDescriptor.getLength();
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ lDispatcher[i] = this->queryDispatch(
+ lDescriptor[i].FeatureURL,
+ lDescriptor[i].FrameName,
+ lDescriptor[i].SearchFlags);
+ }
+ return lDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short dispatch URL with arguments
+ @descr We use threadsafe internal method to do so. It returns a state value - but we ignore it.
+ Because we doesn't support status listener notifications here. Status events are not guaranteed -
+ and we call another service internaly which doesn't return any notifications too.
+
+ @param aURL
+ mail URL which should be executed
+ @param lArguments
+ list of optional arguments for this mail request
+
+ @modified 30.04.2002 14:15, as96863
+*/
+void SAL_CALL MailToDispatcher::dispatch( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException )
+{
+ // dispatch() is an [oneway] call ... and may our user release his reference to us immediatly.
+ // So we should hold us self alive till this call ends.
+ css::uno::Reference< css::frame::XNotifyingDispatch > xSelfHold(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ implts_dispatch(aURL,lArguments);
+ // No notification for status listener!
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short dispatch with guaranteed notifications about success
+ @descr We use threadsafe internal method to do so. Return state of this function will be used
+ for notification if an optional listener is given.
+
+ @param aURL
+ mail URL which should be executed
+ @param lArguments
+ list of optional arguments for this mail request
+ @param xListener
+ reference to a valid listener for state events
+
+ @modified 30.04.2002 14:49, as96863
+*/
+void SAL_CALL MailToDispatcher::dispatchWithNotification( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
+ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ // This class was designed to die by reference. And if user release his reference to us immediatly after calling this method
+ // we can run into some problems. So we hold us self alive till this method ends.
+ // Another reason: We can use this reference as source of sending event at the end too.
+ css::uno::Reference< css::frame::XNotifyingDispatch > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+
+ sal_Bool bState = implts_dispatch(aURL,lArguments);
+ if (xListener.is())
+ {
+ css::frame::DispatchResultEvent aEvent;
+ if (bState)
+ aEvent.State = css::frame::DispatchResultState::SUCCESS;
+ else
+ aEvent.State = css::frame::DispatchResultState::FAILURE;
+ aEvent.Source = xThis;
+
+ xListener->dispatchFinished( aEvent );
+ }
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short threadsafe helper for dispatch calls
+ @descr We support two interfaces for the same process - dispatch URLs. That the reason for this internal
+ function. It implements the real dispatch operation and returns a state value which inform caller
+ about success. He can notify listener then by using this return value.
+
+ @param aURL
+ mail URL which should be executed
+ @param lArguments
+ list of optional arguments for this mail request
+
+ @return <TRUE/> if dispatch could be started successfully
+ Note: Our internal used shell executor doesn't return any state value - so we must
+ belive that call was successfully.
+ <FALSE/> if neccessary ressource couldn't be created or an exception was thrown.
+
+ @modified 30.04.2002 14:49, as96863
+*/
+sal_Bool MailToDispatcher::implts_dispatch( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/ ) throw( css::uno::RuntimeException )
+{
+ sal_Bool bSuccess = sal_False;
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory;
+ /* SAFE */{
+ ReadGuard aReadLock( m_aLock );
+ xFactory = m_xFactory;
+ /* SAFE */}
+
+ css::uno::Reference< css::system::XSystemShellExecute > xSystemShellExecute( xFactory->createInstance(SERVICENAME_SYSTEMSHELLEXECUTE), css::uno::UNO_QUERY );
+ if (xSystemShellExecute.is())
+ {
+ try
+ {
+ // start mail client
+ // Because there is no notofocation about success - we use case of
+ // no detected exception as SUCCESS - FAILED otherwhise.
+ xSystemShellExecute->execute( aURL.Complete, ::rtl::OUString(), css::system::SystemShellExecuteFlags::DEFAULTS );
+ bSuccess = sal_True;
+ }
+ catch (css::lang::IllegalArgumentException&)
+ {
+ }
+ catch (css::system::SystemShellExecuteException&)
+ {
+ }
+ }
+
+ return bSuccess;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short add/remove listener for state events
+ @descr Because we use an external process to forward such mail URLs, and this process doesn't
+ return any notifications about success or failed state - we doesn't support such status
+ listener. We have no status to send.
+
+ @param xListener
+ reference to a valid listener for state events
+ @param aURL
+ URL about listener will be informed, if something occurred
+
+ @modified 30.04.2002 14:49, as96863
+*/
+void SAL_CALL MailToDispatcher::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ ,
+ const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException )
+{
+ // not suported yet
+}
+
+//_________________________________________________________________________________________________________________
+
+void SAL_CALL MailToDispatcher::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ ,
+ const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException )
+{
+ // not suported yet
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/menudispatcher.cxx b/framework/source/dispatch/menudispatcher.cxx
new file mode 100644
index 000000000000..ce8f9c374a21
--- /dev/null
+++ b/framework/source/dispatch/menudispatcher.cxx
@@ -0,0 +1,480 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <dispatch/menudispatcher.hxx>
+#include <general.h>
+#include <framework/menuconfiguration.hxx>
+#include <framework/addonmenu.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/awt/XToolkit.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/awt/WindowDescriptor.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+#include <vcl/window.hxx>
+#include <vcl/syswin.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/rcid.h>
+#include <osl/mutex.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <ucbhelper/content.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+using namespace ::com::sun::star ;
+using namespace ::com::sun::star::awt ;
+using namespace ::com::sun::star::beans ;
+using namespace ::com::sun::star::container ;
+using namespace ::com::sun::star::frame ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star::util ;
+using namespace ::cppu ;
+ using ::rtl::OUString;
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+const sal_uInt16 SLOTID_MDIWINDOWLIST = 5610;
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+MenuDispatcher::MenuDispatcher( const uno::Reference< XMultiServiceFactory >& xFactory ,
+ const uno::Reference< XFrame >& xOwner )
+ // Init baseclasses first
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , OWeakObject ( )
+ // Init member
+ , m_xOwnerWeak ( xOwner )
+ , m_xFactory ( xFactory )
+ , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
+ , m_bAlreadyDisposed ( sal_False )
+ , m_bActivateListener ( sal_False )
+ , m_pMenuManager ( NULL )
+{
+ // Safe impossible cases
+ // We need valid informations about ouer ownerfor work.
+ LOG_ASSERT( impldbg_checkParameter_MenuDispatcher( xFactory, xOwner ), "MenuDispatcher::MenuDispatcher()\nInvalid parameter detected!\n" )
+
+ m_bActivateListener = sal_True;
+ xOwner->addFrameActionListener( uno::Reference< XFrameActionListener >( (OWeakObject *)this, UNO_QUERY ));
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+MenuDispatcher::~MenuDispatcher()
+{
+ // Warn programmer if he forgot to dispose this instance.
+ // We must release all our references ...
+ // and a dtor isn't the best place to do that!
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_4 ( MenuDispatcher ,
+ OWeakObject ,
+ DIRECT_INTERFACE( XTypeProvider ),
+ DIRECT_INTERFACE( XDispatch ),
+ DIRECT_INTERFACE( XEventListener ),
+ DERIVED_INTERFACE( XFrameActionListener, XEventListener )
+ )
+
+DEFINE_XTYPEPROVIDER_4 ( MenuDispatcher ,
+ XTypeProvider ,
+ XDispatch ,
+ XEventListener ,
+ XFrameActionListener
+ )
+
+
+//*****************************************************************************************************************
+// XDispatch
+//*****************************************************************************************************************
+void SAL_CALL MenuDispatcher::dispatch( const URL& /*aURL*/ ,
+ const Sequence< PropertyValue >& /*seqProperties*/ ) throw( RuntimeException )
+{
+}
+
+//*****************************************************************************************************************
+// XDispatch
+//*****************************************************************************************************************
+void SAL_CALL MenuDispatcher::addStatusListener( const uno::Reference< XStatusListener >& xControl,
+ const URL& aURL ) throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+ // Safe impossible cases
+ // Method not defined for all incoming parameter
+ LOG_ASSERT( impldbg_checkParameter_addStatusListener( xControl, aURL ), "MenuDispatcher::addStatusListener()\nInvalid parameter detected.\n" )
+ // Add listener to container.
+ m_aListenerContainer.addInterface( aURL.Complete, xControl );
+}
+
+//*****************************************************************************************************************
+// XDispatch
+//*****************************************************************************************************************
+void SAL_CALL MenuDispatcher::removeStatusListener( const uno::Reference< XStatusListener >& xControl,
+ const URL& aURL ) throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+ // Safe impossible cases
+ // Method not defined for all incoming parameter
+ LOG_ASSERT( impldbg_checkParameter_removeStatusListener( xControl, aURL ), "MenuDispatcher::removeStatusListener()\nInvalid parameter detected.\n" )
+ // Add listener to container.
+ m_aListenerContainer.removeInterface( aURL.Complete, xControl );
+}
+
+//*****************************************************************************************************************
+// XFrameActionListener
+//*****************************************************************************************************************
+
+void SAL_CALL MenuDispatcher::frameAction( const FrameActionEvent& aEvent ) throw ( RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_pMenuManager && aEvent.Action == FrameAction_FRAME_UI_ACTIVATED )
+ {
+ MenuBar* pMenuBar = (MenuBar *)m_pMenuManager->GetMenu();
+ uno::Reference< XFrame > xFrame( m_xOwnerWeak.get(), UNO_QUERY );
+ aGuard.unlock();
+
+ if ( xFrame.is() && pMenuBar )
+ {
+ uno::Reference< ::com::sun::star::awt::XWindow >xContainerWindow = xFrame->getContainerWindow();
+
+ SolarMutexGuard aSolarGuard;
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ while ( pWindow && !pWindow->IsSystemWindow() )
+ pWindow = pWindow->GetParent();
+
+ if ( pWindow )
+ {
+ SystemWindow* pSysWindow = (SystemWindow *)pWindow;
+ pSysWindow->SetMenuBar( pMenuBar );
+ }
+ }
+ }
+ }
+ else if ( m_pMenuManager && aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING )
+ {
+ if ( m_pMenuManager )
+ impl_setMenuBar( NULL );
+ }
+}
+
+//*****************************************************************************************************************
+// XEventListener
+//*****************************************************************************************************************
+void SAL_CALL MenuDispatcher::disposing( const EventObject& ) throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+ // Safe impossible cases
+ LOG_ASSERT( !(m_bAlreadyDisposed==sal_True), "MenuDispatcher::disposing()\nObject already disposed .. don't call it again!\n" )
+
+ if( m_bAlreadyDisposed == sal_False )
+ {
+ m_bAlreadyDisposed = sal_True;
+
+ if ( m_bActivateListener )
+ {
+ uno::Reference< XFrame > xFrame( m_xOwnerWeak.get(), UNO_QUERY );
+ if ( xFrame.is() )
+ {
+ xFrame->removeFrameActionListener( uno::Reference< XFrameActionListener >( (OWeakObject *)this, UNO_QUERY ));
+ m_bActivateListener = sal_False;
+ if ( m_pMenuManager )
+ {
+ EventObject aEventObj;
+ aEventObj.Source = xFrame;
+ m_pMenuManager->disposing( aEventObj );
+ }
+ }
+ }
+
+ // Forget our factory.
+ m_xFactory = uno::Reference< XMultiServiceFactory >();
+
+ // Remove our menu from system window if it is still there!
+ if ( m_pMenuManager )
+ impl_setMenuBar( NULL );
+ }
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void MenuDispatcher::impl_setAccelerators( Menu* pMenu, const Accelerator& aAccel )
+{
+ for ( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); ++nPos )
+ {
+ sal_uInt16 nId = pMenu->GetItemId(nPos);
+ PopupMenu* pPopup = pMenu->GetPopupMenu(nId);
+ if ( pPopup )
+ impl_setAccelerators( (Menu *)pPopup, aAccel );
+ else if ( nId && !pMenu->GetPopupMenu(nId))
+ {
+ KeyCode aCode = aAccel.GetKeyCode( nId );
+ if ( aCode.GetCode() )
+ pMenu->SetAccelKey( nId, aCode );
+ }
+ }
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool MenuDispatcher::impl_setMenuBar( MenuBar* pMenuBar, sal_Bool bMenuFromResource )
+{
+ uno::Reference< XFrame > xFrame( m_xOwnerWeak.get(), UNO_QUERY );
+ if ( xFrame.is() )
+ {
+ uno::Reference< ::com::sun::star::awt::XWindow >xContainerWindow = xFrame->getContainerWindow();
+ Window* pWindow = NULL;
+
+ // Use SolarMutex for threadsafe code too!
+ SolarMutexGuard aSolarGuard;
+ {
+ pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ while ( pWindow && !pWindow->IsSystemWindow() )
+ pWindow = pWindow->GetParent();
+ }
+
+ if ( pWindow )
+ {
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ SystemWindow* pSysWindow = (SystemWindow *)pWindow;
+
+ if ( m_pMenuManager )
+ {
+ // remove old menu from our system window if it was set before
+ if ( m_pMenuManager->GetMenu() == (Menu *)pSysWindow->GetMenuBar() )
+ pSysWindow->SetMenuBar( NULL );
+
+ // remove listener before we destruct ourself, so we cannot be called back afterwards
+ m_pMenuManager->RemoveListener();
+
+ SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)m_pMenuManager )->release();
+
+ m_pMenuManager = 0;
+ }
+
+ if ( pMenuBar != NULL )
+ {
+ sal_uInt16 nPos = pMenuBar->GetItemPos( SLOTID_MDIWINDOWLIST );
+ if ( nPos != MENU_ITEM_NOTFOUND )
+ {
+ OUString aNoContext;
+
+ uno::Reference< XModel > xModel;
+ uno::Reference< XController > xController( xFrame->getController(), UNO_QUERY );
+
+ if ( xController.is() )
+ xModel = uno::Reference< XModel >( xController->getModel(), UNO_QUERY );
+
+ // retrieve addon popup menus and add them to our menu bar
+ AddonMenuManager::MergeAddonPopupMenus( xFrame, xModel, nPos, pMenuBar );
+
+ // retrieve addon help menu items and add them to our help menu
+ AddonMenuManager::MergeAddonHelpMenu( xFrame, pMenuBar );
+ }
+
+ // set new menu on our system window and create new menu manager
+ if ( bMenuFromResource )
+ {
+ m_pMenuManager = new MenuManager( m_xFactory, xFrame, pMenuBar, sal_True, sal_False );
+ }
+ else
+ {
+ m_pMenuManager = new MenuManager( m_xFactory, xFrame, pMenuBar, sal_True, sal_True );
+ }
+
+ pSysWindow->SetMenuBar( pMenuBar );
+ }
+
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+IMPL_LINK( MenuDispatcher, Close_Impl, void*, EMPTYARG )
+{
+ css::uno::Reference < css::frame::XFrame > xFrame( m_xOwnerWeak.get(), css::uno::UNO_QUERY );
+ if ( !xFrame.is() )
+ return 0;
+
+ css::util::URL aURL;
+ aURL.Complete = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin"));
+ css::uno::Reference< css::util::XURLTransformer > xTrans ( m_xFactory->createInstance(
+ SERVICENAME_URLTRANSFORMER ), css::uno::UNO_QUERY );
+ if( xTrans.is() )
+ {
+ // Datei laden
+ xTrans->parseStrict( aURL );
+ uno::Reference< XDispatchProvider > xProv( xFrame, UNO_QUERY );
+ if ( xProv.is() )
+ {
+ css::uno::Reference < css::frame::XDispatch > aDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 );
+ if ( aDisp.is() )
+ aDisp->dispatch( aURL, css::uno::Sequence < css::beans::PropertyValue>() );
+ }
+ }
+
+ return 0;
+}
+
+
+//_________________________________________________________________________________________________________________
+// debug methods
+//_________________________________________________________________________________________________________________
+
+/*-----------------------------------------------------------------------------------------------------------------
+ The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
+ we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT!
+
+ ATTENTION
+
+ If you miss a test for one of this parameters, contact the autor or add it himself !(?)
+ But ... look for right testing! See using of this methods!
+-----------------------------------------------------------------------------------------------------------------*/
+
+#ifdef ENABLE_ASSERTIONS
+
+//*****************************************************************************************************************
+sal_Bool MenuDispatcher::impldbg_checkParameter_MenuDispatcher( const uno::Reference< XMultiServiceFactory >& xFactory ,
+ const uno::Reference< XFrame >& xOwner )
+{
+ // Set default return value.
+ sal_Bool bOK = sal_True;
+ // Check parameter.
+ if (
+ ( &xFactory == NULL ) ||
+ ( &xOwner == NULL ) ||
+ ( xFactory.is() == sal_False ) ||
+ ( xOwner.is() == sal_False )
+ )
+ {
+ bOK = sal_False ;
+ }
+ // Return result of check.
+ return bOK ;
+}
+
+//*****************************************************************************************************************
+// We need a valid URL. What is meaning with "register for nothing"?!
+// xControl must correct to - nobody can advised otherwise!
+sal_Bool MenuDispatcher::impldbg_checkParameter_addStatusListener( const uno::Reference< XStatusListener >& xControl,
+ const URL& aURL )
+{
+ // Set default return value.
+ sal_Bool bOK = sal_True;
+ // Check parameter.
+ if (
+ ( &xControl == NULL ) ||
+ ( &aURL == NULL ) ||
+ ( aURL.Complete.getLength() < 1 )
+ )
+ {
+ bOK = sal_False ;
+ }
+ // Return result of check.
+ return bOK ;
+}
+
+//*****************************************************************************************************************
+// The same goes for these case! We have added valid listener for correct URL only.
+// We can't remove invalid listener for nothing!
+sal_Bool MenuDispatcher::impldbg_checkParameter_removeStatusListener( const uno::Reference< XStatusListener >& xControl,
+ const URL& aURL )
+{
+ // Set default return value.
+ sal_Bool bOK = sal_True;
+ // Check parameter.
+ if (
+ ( &xControl == NULL ) ||
+ ( &aURL == NULL ) ||
+ ( aURL.Complete.getLength() < 1 )
+ )
+ {
+ bOK = sal_False ;
+ }
+ // Return result of check.
+ return bOK ;
+}
+
+#endif // #ifdef ENABLE_ASSERTIONS
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/oxt_handler.cxx b/framework/source/dispatch/oxt_handler.cxx
new file mode 100644
index 000000000000..f1b5edd86691
--- /dev/null
+++ b/framework/source/dispatch/oxt_handler.cxx
@@ -0,0 +1,272 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <dispatch/oxt_handler.hxx>
+
+#include <threadhelp/transactionguard.hxx>
+
+#include <threadhelp/writeguard.hxx>
+
+#include <threadhelp/readguard.hxx>
+
+#include <macros/debug.hxx>
+
+#include <services.h>
+
+#include <comphelper/mediadescriptor.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <comphelper/sequenceashashmap.hxx>
+
+#include <rtl/ustrbuf.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_5 ( Oxt_Handler ,
+ OWeakObject ,
+ DIRECT_INTERFACE( css::lang::XTypeProvider ),
+ DIRECT_INTERFACE( css::lang::XServiceInfo ),
+ DIRECT_INTERFACE( css::frame::XNotifyingDispatch ),
+ DIRECT_INTERFACE( css::frame::XDispatch ),
+ DIRECT_INTERFACE( css::document::XExtendedFilterDetection )
+ )
+
+DEFINE_XTYPEPROVIDER_5 ( Oxt_Handler ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::frame::XNotifyingDispatch ,
+ css::frame::XDispatch ,
+ css::document::XExtendedFilterDetection
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( Oxt_Handler ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_CONTENTHANDLER ,
+ IMPLEMENTATIONNAME_OXT_HANDLER
+ )
+
+DEFINE_INIT_SERVICE ( Oxt_Handler,
+ {
+ }
+ )
+
+/*-************************************************************************************************************//**
+ @short standard ctor
+ @descr These initialize a new instance of this class with needed informations for work.
+
+ @seealso using at owner
+
+ @param "xFactory", reference to service manager for creation of new services
+ @return -
+
+ @onerror Show an assertion and do nothing else.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+Oxt_Handler::Oxt_Handler( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+ // Init baseclasses first
+ : ThreadHelpBase ( )
+ , ::cppu::OWeakObject ( )
+ // Init member
+ , m_xFactory ( xFactory )
+{
+}
+
+/*-************************************************************************************************************//**
+ @short standard dtor
+ @descr -
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ @threadsafe -
+*//*-*************************************************************************************************************/
+Oxt_Handler::~Oxt_Handler()
+{
+ if ( m_xListener.is() )
+ {
+ css::frame::DispatchResultEvent aEvent;
+ aEvent.State = css::frame::DispatchResultState::FAILURE;
+ m_xListener->dispatchFinished( aEvent );
+ m_xListener = css::uno::Reference< css::frame::XDispatchResultListener >();
+ }
+}
+
+/*-************************************************************************************************************//**
+ @interface ::com::sun::star::frame::XDispatch
+
+ @short try to load audio file
+ @descr This method try to load given audio file by URL and play it. We use vcl/Sound class to do that.
+ Playing of sound is asynchron everytime.
+
+ @attention We must hold us alive by ourself ... because we use async. vcl sound player ... but playing is started
+ in async interface call "dispatch()" too. And caller forget us imediatly. But then our uno ref count
+ will decreased to 0 and will die. The only solution is to use own reference to our implementation.
+ But we do it for realy started jobs only and release it during call back of vcl.
+
+ @seealso class vcl/Sound
+ @seealso method implts_PlayerNotify()
+
+ @param "aURL" , URL to dispatch.
+ @param "lArguments", list of optional arguments.
+ @return -
+
+ @onerror We do nothing.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+void SAL_CALL Oxt_Handler::dispatchWithNotification( const css::util::URL& aURL,
+ const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/,
+ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
+ throw( css::uno::RuntimeException )
+{
+ // SAFE {
+ ResetableGuard aLock( m_aLock );
+
+ rtl::OUString sServiceName = UNISTRING( "com.sun.star.deployment.ui.PackageManagerDialog" );
+ css::uno::Sequence< css::uno::Any > lParams(1);
+ lParams[0] <<= aURL.Main;
+
+ css::uno::Reference< css::uno::XInterface > xService;
+
+ xService = m_xFactory->createInstanceWithArguments( sServiceName, lParams );
+ css::uno::Reference< css::task::XJobExecutor > xExecuteable( xService, css::uno::UNO_QUERY );
+ if ( xExecuteable.is() )
+ xExecuteable->trigger( rtl::OUString() );
+
+ if ( xListener.is() )
+ {
+ css::frame::DispatchResultEvent aEvent;
+ aEvent.State = css::frame::DispatchResultState::SUCCESS;
+ xListener->dispatchFinished( aEvent );
+ }
+
+ // } SAFE
+ aLock.unlock();
+}
+
+void SAL_CALL Oxt_Handler::dispatch( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
+ throw( css::uno::RuntimeException )
+{
+ dispatchWithNotification( aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >() );
+}
+
+/*-************************************************************************************************************//**
+ @interface ::com::sun::star::document::XExtendedFilterDetection
+
+ @short try to detect file (given as argument included in "lDescriptor")
+ @descr We try to detect, if given file could be handled by this class and is a well known one.
+ If it is - we return right internal type name - otherwise we return nothing!
+ So call can search for another detect service and ask him too.
+
+ @attention a) We don't need any mutex here ... because we don't use any member!
+ b) Dont' use internal player instance "m_pPlayer" to detect given sound file!
+ It's not neccessary to do that ... and we can use temp. variable to do the same.
+ This way is easy - we don't must synchronize it with currently played sounds!
+ Another reason to do so ... We are a listener on our internal ma_Player object.
+ If you would call "IsSoundFile()" on this instance, he would call us back and
+ we make some uneccssary things ...
+
+ @seealso -
+
+ @param "lDescriptor", description of file to detect
+ @return Internal type name which match this file ... or nothing if it is unknown.
+
+ @onerror We return nothing.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+::rtl::OUString SAL_CALL Oxt_Handler::detect( css::uno::Sequence< css::beans::PropertyValue >& lDescriptor )
+ throw( css::uno::RuntimeException )
+{
+ // Our default is "nothing". So we can return it, if detection failed or fily type is realy unknown.
+ ::rtl::OUString sTypeName;
+
+ // Analyze given descriptor to find filename or input stream or ...
+ ::comphelper::MediaDescriptor aDescriptor( lDescriptor );
+ ::rtl::OUString sURL = aDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_URL(), ::rtl::OUString() );
+
+ long nLength = sURL.getLength();
+ if ( ( nLength > 4 ) && sURL.matchIgnoreAsciiCase( UNISTRING(".oxt"), nLength-4 ) )
+ {
+ // "IsSoundFile" idffer between different "wav" and "au" file versions ...
+ // couldn't return this information ... because: He use the OS to detect it!
+ // I think we can the following ones:
+ // a) look for given extension of url to map our type decision HARD CODED!!!
+ // b) return preferred type every time... it's easy :-)
+ sTypeName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("oxt_OpenOffice_Extension"));
+ aDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sTypeName;
+ aDescriptor >> lDescriptor;
+ }
+
+ // Return our decision.
+ return sTypeName;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/popupmenudispatcher.cxx b/framework/source/dispatch/popupmenudispatcher.cxx
new file mode 100644
index 000000000000..babc0dbb76ec
--- /dev/null
+++ b/framework/source/dispatch/popupmenudispatcher.cxx
@@ -0,0 +1,422 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <dispatch/popupmenudispatcher.hxx>
+#include <general.h>
+#include <framework/menuconfiguration.hxx>
+#include <framework/addonmenu.hxx>
+#include <services.h>
+#include <properties.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/awt/XToolkit.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/awt/WindowDescriptor.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <ucbhelper/content.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+using namespace ::com::sun::star ;
+using namespace ::com::sun::star::awt ;
+using namespace ::com::sun::star::beans ;
+using namespace ::com::sun::star::container ;
+using namespace ::com::sun::star::frame ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star::util ;
+using namespace ::cppu ;
+using namespace ::osl ;
+using namespace ::rtl ;
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+const char* PROTOCOL_VALUE = "vnd.sun.star.popup:";
+const sal_Int32 PROTOCOL_LENGTH = 19;
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+PopupMenuDispatcher::PopupMenuDispatcher(
+ const uno::Reference< XMultiServiceFactory >& xFactory )
+ // Init baseclasses first
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , OWeakObject ( )
+ // Init member
+ , m_xFactory ( xFactory )
+ , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
+ , m_bAlreadyDisposed ( sal_False )
+ , m_bActivateListener ( sal_False )
+{
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+PopupMenuDispatcher::~PopupMenuDispatcher()
+{
+ // Warn programmer if he forgot to dispose this instance.
+ // We must release all our references ...
+ // and a dtor isn't the best place to do that!
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_7 ( PopupMenuDispatcher ,
+ ::cppu::OWeakObject ,
+ DIRECT_INTERFACE( XTypeProvider ),
+ DIRECT_INTERFACE( XServiceInfo ),
+ DIRECT_INTERFACE( XDispatchProvider ),
+ DIRECT_INTERFACE( XDispatch ),
+ DIRECT_INTERFACE( XEventListener ),
+ DIRECT_INTERFACE( XInitialization ),
+ DERIVED_INTERFACE( XFrameActionListener, XEventListener )
+ )
+
+DEFINE_XTYPEPROVIDER_7 ( PopupMenuDispatcher ,
+ XTypeProvider ,
+ XServiceInfo ,
+ XDispatchProvider ,
+ XDispatch ,
+ XEventListener ,
+ XInitialization ,
+ XFrameActionListener
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE( PopupMenuDispatcher ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_PROTOCOLHANDLER ,
+ IMPLEMENTATIONNAME_POPUPMENUDISPATCHER )
+
+DEFINE_INIT_SERVICE(PopupMenuDispatcher,
+{
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+}
+)
+
+//*****************************************************************************************************************
+// XInitialization
+//*****************************************************************************************************************
+void SAL_CALL PopupMenuDispatcher::initialize(
+ const css::uno::Sequence< css::uno::Any >& lArguments )
+throw( css::uno::Exception, css::uno::RuntimeException)
+{
+ css::uno::Reference< css::frame::XFrame > xFrame;
+
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ for (int a=0; a<lArguments.getLength(); ++a)
+ {
+ if (a==0)
+ {
+ lArguments[a] >>= xFrame;
+ m_xWeakFrame = xFrame;
+
+ m_bActivateListener = sal_True;
+ uno::Reference< css::frame::XFrameActionListener > xFrameActionListener(
+ (OWeakObject *)this, css::uno::UNO_QUERY );
+ xFrame->addFrameActionListener( xFrameActionListener );
+ }
+ }
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//*****************************************************************************************************************
+// XDispatchProvider
+//*****************************************************************************************************************
+css::uno::Reference< css::frame::XDispatch >
+SAL_CALL PopupMenuDispatcher::queryDispatch(
+ const css::util::URL& rURL ,
+ const ::rtl::OUString& sTarget ,
+ sal_Int32 nFlags )
+throw( css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatch;
+
+ if ( rURL.Complete.compareToAscii( PROTOCOL_VALUE, PROTOCOL_LENGTH ) == 0 )
+ {
+ // --- SAFE ---
+ ResetableGuard aGuard( m_aLock );
+ impl_RetrievePopupControllerQuery();
+ impl_CreateUriRefFactory();
+
+ css::uno::Reference< css::container::XNameAccess > xPopupCtrlQuery( m_xPopupCtrlQuery );
+ css::uno::Reference< css::uri::XUriReferenceFactory > xUriRefFactory( m_xUriRefFactory );
+ aGuard.unlock();
+ // --- SAFE ---
+
+ if ( xPopupCtrlQuery.is() )
+ {
+ try
+ {
+ // Just use the main part of the URL for popup menu controllers
+ sal_Int32 nQueryPart( 0 );
+ sal_Int32 nSchemePart( 0 );
+ rtl::OUString aBaseURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" ));
+ rtl::OUString aURL( rURL.Complete );
+
+ nSchemePart = aURL.indexOf( ':' );
+ if (( nSchemePart > 0 ) &&
+ ( aURL.getLength() > ( nSchemePart+1 )))
+ {
+ nQueryPart = aURL.indexOf( '?', nSchemePart );
+ if ( nQueryPart > 0 )
+ aBaseURL += aURL.copy( nSchemePart+1, nQueryPart-(nSchemePart+1) );
+ else if ( nQueryPart == -1 )
+ aBaseURL += aURL.copy( nSchemePart+1 );
+ }
+
+ css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider;
+
+ // Find popup menu controller using the base URL
+ xPopupCtrlQuery->getByName( aBaseURL ) >>= xDispatchProvider;
+ aGuard.unlock();
+
+ // Ask popup menu dispatch provider for dispatch object
+ if ( xDispatchProvider.is() )
+ xDispatch = xDispatchProvider->queryDispatch( rURL, sTarget, nFlags );
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+ return xDispatch;
+}
+
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL
+PopupMenuDispatcher::queryDispatches(
+ const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor )
+throw( css::uno::RuntimeException )
+{
+ sal_Int32 nCount = lDescriptor.getLength();
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ lDispatcher[i] = this->queryDispatch(
+ lDescriptor[i].FeatureURL,
+ lDescriptor[i].FrameName,
+ lDescriptor[i].SearchFlags);
+ }
+ return lDispatcher;
+}
+
+//*****************************************************************************************************************
+// XDispatch
+//*****************************************************************************************************************
+void
+SAL_CALL PopupMenuDispatcher::dispatch(
+ const URL& /*aURL*/ ,
+ const Sequence< PropertyValue >& /*seqProperties*/ )
+throw( RuntimeException )
+{
+}
+
+//*****************************************************************************************************************
+// XDispatch
+//*****************************************************************************************************************
+void
+SAL_CALL PopupMenuDispatcher::addStatusListener(
+ const uno::Reference< XStatusListener >& xControl,
+ const URL& aURL )
+throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+ // Safe impossible cases
+ // Add listener to container.
+ m_aListenerContainer.addInterface( aURL.Complete, xControl );
+}
+
+//*****************************************************************************************************************
+// XDispatch
+//*****************************************************************************************************************
+void
+SAL_CALL PopupMenuDispatcher::removeStatusListener(
+ const uno::Reference< XStatusListener >& xControl,
+ const URL& aURL )
+throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+ // Safe impossible cases
+ // Add listener to container.
+ m_aListenerContainer.removeInterface( aURL.Complete, xControl );
+}
+
+//*****************************************************************************************************************
+// XFrameActionListener
+//*****************************************************************************************************************
+
+void
+SAL_CALL PopupMenuDispatcher::frameAction(
+ const FrameActionEvent& aEvent )
+throw ( RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if (( aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING ) ||
+ ( aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ))
+ {
+ // Reset query reference to requery it again next time
+ m_xPopupCtrlQuery.clear();
+ }
+}
+
+//*****************************************************************************************************************
+// XEventListener
+//*****************************************************************************************************************
+void
+SAL_CALL PopupMenuDispatcher::disposing( const EventObject& ) throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+ // Safe impossible cases
+ LOG_ASSERT( !(m_bAlreadyDisposed==sal_True), "MenuDispatcher::disposing()\nObject already disposed .. don't call it again!\n" )
+
+ if( m_bAlreadyDisposed == sal_False )
+ {
+ m_bAlreadyDisposed = sal_True;
+
+ if ( m_bActivateListener )
+ {
+ uno::Reference< XFrame > xFrame( m_xWeakFrame.get(), UNO_QUERY );
+ if ( xFrame.is() )
+ {
+ xFrame->removeFrameActionListener( uno::Reference< XFrameActionListener >( (OWeakObject *)this, UNO_QUERY ));
+ m_bActivateListener = sal_False;
+ }
+ }
+
+ // Forget our factory.
+ m_xFactory = uno::Reference< XMultiServiceFactory >();
+ }
+}
+
+void PopupMenuDispatcher::impl_RetrievePopupControllerQuery()
+{
+ if ( !m_xPopupCtrlQuery.is() )
+ {
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ css::uno::Reference< css::frame::XFrame > xFrame( m_xWeakFrame );
+
+ if ( xFrame.is() )
+ {
+ css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ xPropSet->getPropertyValue( FRAME_PROPNAME_LAYOUTMANAGER ) >>= xLayoutManager;
+
+ if ( xLayoutManager.is() )
+ {
+ css::uno::Reference< css::ui::XUIElement > xMenuBar;
+ rtl::OUString aMenuBar( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ));
+ xMenuBar = xLayoutManager->getElement( aMenuBar );
+
+ m_xPopupCtrlQuery = css::uno::Reference< css::container::XNameAccess >(
+ xMenuBar, css::uno::UNO_QUERY );
+ }
+ }
+ catch ( css::uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+}
+
+void PopupMenuDispatcher::impl_CreateUriRefFactory()
+{
+ if ( !m_xUriRefFactory.is() )
+ {
+ rtl::OUString aUriRefFactoryService(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.uri.UriReferenceFactory" ));
+
+ m_xUriRefFactory = css::uno::Reference< css::uri::XUriReferenceFactory >(
+ m_xFactory->createInstance( aUriRefFactoryService ),
+ css::uno::UNO_QUERY);
+
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/servicehandler.cxx b/framework/source/dispatch/servicehandler.cxx
new file mode 100644
index 000000000000..6f019f247775
--- /dev/null
+++ b/framework/source/dispatch/servicehandler.cxx
@@ -0,0 +1,354 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <dispatch/servicehandler.hxx>
+#include <threadhelp/readguard.hxx>
+#include <general.h>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/DispatchResultState.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+#define PROTOCOL_VALUE "service:"
+#define PROTOCOL_LENGTH 8
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// XInterface, XTypeProvider, XServiceInfo
+
+DEFINE_XINTERFACE_5(ServiceHandler ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::frame::XDispatchProvider ),
+ DIRECT_INTERFACE(css::frame::XNotifyingDispatch),
+ DIRECT_INTERFACE(css::frame::XDispatch ))
+
+DEFINE_XTYPEPROVIDER_5(ServiceHandler ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::frame::XDispatchProvider ,
+ css::frame::XNotifyingDispatch,
+ css::frame::XDispatch )
+
+DEFINE_XSERVICEINFO_MULTISERVICE(ServiceHandler ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_PROTOCOLHANDLER ,
+ IMPLEMENTATIONNAME_SERVICEHANDLER)
+
+DEFINE_INIT_SERVICE(ServiceHandler,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+ )
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short standard ctor
+ @descr These initialize a new instance of ths class with needed informations for work.
+
+ @param xFactory
+ reference to uno servicemanager for creation of new services
+
+ @modified 02.05.2002 08:16, as96863
+*/
+ServiceHandler::ServiceHandler( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+ // Init baseclasses first
+ : ThreadHelpBase( &Application::GetSolarMutex() )
+ , OWeakObject ( )
+ // Init member
+ , m_xFactory ( xFactory )
+{
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short standard dtor
+ @descr -
+
+ @modified 02.05.2002 08:16, as96863
+*/
+ServiceHandler::~ServiceHandler()
+{
+ m_xFactory = NULL;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short decide if this dispatch implementation can be used for requested URL or not
+ @descr A protocol handler is registerd for an URL pattern inside configuration and will
+ be asked by the generic dispatch mechanism inside framework, if he can handle this
+ special URL wich match his registration. He can agree by returning of a valid dispatch
+ instance or disagree by returning <NULL/>.
+ We don't create new dispatch instances here realy - we return THIS as result to handle it
+ at the same implementation.
+
+ @modified 02.05.2002 15:25, as96863
+*/
+css::uno::Reference< css::frame::XDispatch > SAL_CALL ServiceHandler::queryDispatch( const css::util::URL& aURL ,
+ const ::rtl::OUString& /*sTarget*/ ,
+ sal_Int32 /*nFlags*/ ) throw( css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatcher;
+ if (aURL.Complete.compareToAscii(PROTOCOL_VALUE,PROTOCOL_LENGTH)==0)
+ xDispatcher = this;
+ return xDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short do the same like dispatch() but for multiple requests at the same time
+ @descr -
+
+ @modified 02.05.2002 15:27, as96863
+*/
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL ServiceHandler::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException )
+{
+ sal_Int32 nCount = lDescriptor.getLength();
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ lDispatcher[i] = this->queryDispatch(
+ lDescriptor[i].FeatureURL,
+ lDescriptor[i].FrameName,
+ lDescriptor[i].SearchFlags);
+ }
+ return lDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short dispatch URL with arguments
+ @descr We use threadsafe internal method to do so. It returns a state value - but we ignore it.
+ Because we doesn't support status listener notifications here.
+
+ @param aURL
+ uno URL which should be executed
+ @param lArguments
+ list of optional arguments for this request
+
+ @modified 02.05.2002 08:19, as96863
+*/
+void SAL_CALL ServiceHandler::dispatch( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException )
+{
+ // dispatch() is an [oneway] call ... and may our user release his reference to us immediatly.
+ // So we should hold us self alive till this call ends.
+ css::uno::Reference< css::frame::XNotifyingDispatch > xSelfHold(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ implts_dispatch(aURL,lArguments);
+ // No notification for status listener!
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short dispatch with guaranteed notifications about success
+ @descr We use threadsafe internal method to do so. Return state of this function will be used
+ for notification if an optional listener is given.
+
+ @param aURL
+ uno URL which should be executed
+ @param lArguments
+ list of optional arguments for this request
+ @param xListener
+ optional listener for state events
+
+ @modified 30.04.2002 14:49, as96863
+*/
+void SAL_CALL ServiceHandler::dispatchWithNotification( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
+ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ // This class was designed to die by reference. And if user release his reference to us immediatly after calling this method
+ // we can run into some problems. So we hold us self alive till this method ends.
+ // Another reason: We can use this reference as source of sending event at the end too.
+ css::uno::Reference< css::frame::XNotifyingDispatch > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+
+ css::uno::Reference< css::uno::XInterface > xService = implts_dispatch(aURL,lArguments);
+ if (xListener.is())
+ {
+ css::frame::DispatchResultEvent aEvent;
+ if (xService.is())
+ aEvent.State = css::frame::DispatchResultState::SUCCESS;
+ else
+ aEvent.State = css::frame::DispatchResultState::FAILURE;
+ aEvent.Result <<= xService; // may NULL for state=FAILED!
+ aEvent.Source = xThis;
+
+ xListener->dispatchFinished( aEvent );
+ }
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short threadsafe helper for dispatch calls
+ @descr We support two interfaces for the same process - dispatch URLs. That the reason for this internal
+ function. It implements the real dispatch operation and returns a state value which inform caller
+ about success. He can notify listener then by using this return value.
+
+ @param aURL
+ uno URL which should be executed
+ @param lArguments
+ list of optional arguments for this request
+
+ @return <NULL/> if requested service couldn't be created successullfy;
+ a valid reference otherwise. This return value can be used to indicate,
+ if dispatch was successfully or not.
+
+ @modified 02.05.2002 10:51, as96863
+*/
+css::uno::Reference< css::uno::XInterface > ServiceHandler::implts_dispatch( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/ ) throw( css::uno::RuntimeException )
+{
+ /* SAFE */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
+ aReadLock.unlock();
+ /* SAFE */
+
+ if (!xFactory.is())
+ return css::uno::Reference< css::uno::XInterface >();
+
+ // extract service name and may optional given parameters from given URL
+ // and use it to create and start the component
+ ::rtl::OUString sServiceAndArguments = aURL.Complete.copy(PROTOCOL_LENGTH);
+ ::rtl::OUString sServiceName;
+ ::rtl::OUString sArguments ;
+
+ sal_Int32 nArgStart = sServiceAndArguments.indexOf('?',0);
+ if (nArgStart!=-1)
+ {
+ sServiceName = sServiceAndArguments.copy(0,nArgStart);
+ ++nArgStart; // ignore '?'!
+ sArguments = sServiceAndArguments.copy(nArgStart);
+ }
+ else
+ {
+ sServiceName = sServiceAndArguments;
+ }
+
+ if (!sServiceName.getLength())
+ return css::uno::Reference< css::uno::XInterface >();
+
+ // If a service doesnt support an optional job executor interface - he can't get
+ // any given parameters!
+ // Because we can't know if we must call createInstanceWithArguments() or XJobExecutor::trigger() ...
+
+ css::uno::Reference< css::uno::XInterface > xService;
+ try
+ {
+ // => a) a service starts running inside his own ctor and we create it only
+ xService = xFactory->createInstance(sServiceName);
+ // or b) he implements the right interface and starts there (may with optional parameters)
+ css::uno::Reference< css::task::XJobExecutor > xExecuteable(xService, css::uno::UNO_QUERY);
+ if (xExecuteable.is())
+ xExecuteable->trigger(sArguments);
+ }
+ // ignore all errors - inclusive runtime errors!
+ // E.g. a script based service (written in phyton) could not be executed
+ // because it contains syntax errors, which was detected at runtime ...
+ catch(const css::uno::Exception&)
+ { xService.clear(); }
+
+ return xService;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short add/remove listener for state events
+ @descr We use an internal container to hold such registered listener. This container lives if we live.
+ And if call pas registration as non breakable transaction - we can accept the request without
+ any explicit lock. Because we share our mutex with this container.
+
+ @param xListener
+ reference to a valid listener for state events
+ @param aURL
+ URL about listener will be informed, if something occurred
+
+ @modified 30.04.2002 14:49, as96863
+*/
+void SAL_CALL ServiceHandler::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ ,
+ const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException )
+{
+ // not suported yet
+}
+
+//_________________________________________________________________________________________________________________
+
+void SAL_CALL ServiceHandler::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ ,
+ const css::util::URL& /*aURL*/ ) throw( css::uno::RuntimeException )
+{
+ // not suported yet
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/startmoduledispatcher.cxx b/framework/source/dispatch/startmoduledispatcher.cxx
new file mode 100644
index 000000000000..d84e8fe3cb5c
--- /dev/null
+++ b/framework/source/dispatch/startmoduledispatcher.cxx
@@ -0,0 +1,244 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <dispatch/startmoduledispatcher.hxx>
+
+//_______________________________________________
+// my own includes
+
+#include <pattern/frame.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <framework/framelistanalyzer.hxx>
+#include <dispatchcommands.h>
+#include <targets.h>
+#include <services.h>
+#include <general.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/CommandGroup.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include "com/sun/star/beans/XFastPropertySet.hpp"
+#include <com/sun/star/frame/XModuleManager.hpp>
+
+//_______________________________________________
+// includes of other projects
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+#include <unotools/moduleoptions.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+#ifdef fpf
+ #error "Who uses \"fpf\" as define. It will overwrite my namespace alias ..."
+#endif
+namespace fpf = ::framework::pattern::frame;
+
+//_______________________________________________
+// declarations
+
+DEFINE_XINTERFACE_4(StartModuleDispatcher ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::frame::XNotifyingDispatch ),
+ DIRECT_INTERFACE(css::frame::XDispatch ),
+ DIRECT_INTERFACE(css::frame::XDispatchInformationProvider))
+
+// Note: XStatusListener is an implementation detail. Hide it for scripting!
+DEFINE_XTYPEPROVIDER_4(StartModuleDispatcher ,
+ css::lang::XTypeProvider ,
+ css::frame::XDispatchInformationProvider,
+ css::frame::XNotifyingDispatch ,
+ css::frame::XDispatch )
+
+//-----------------------------------------------
+StartModuleDispatcher::StartModuleDispatcher(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xFrame ,
+ const ::rtl::OUString& sTarget)
+ : ThreadHelpBase (&Application::GetSolarMutex() )
+ , ::cppu::OWeakObject( )
+ , m_xSMGR (xSMGR )
+ , m_xOwner (xFrame )
+ , m_sDispatchTarget (sTarget )
+ , m_lStatusListener (m_aLock.getShareableOslMutex())
+{
+}
+
+//-----------------------------------------------
+StartModuleDispatcher::~StartModuleDispatcher()
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL StartModuleDispatcher::dispatch(const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
+ throw(css::uno::RuntimeException)
+{
+ dispatchWithNotification(aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >());
+}
+
+//-----------------------------------------------
+void SAL_CALL StartModuleDispatcher::dispatchWithNotification(const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/,
+ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
+ throw(css::uno::RuntimeException)
+{
+ ::sal_Int16 nResult = css::frame::DispatchResultState::DONTKNOW;
+ if (aURL.Complete.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(CMD_UNO_SHOWSTARTMODULE)))
+ {
+ nResult = css::frame::DispatchResultState::FAILURE;
+ if (implts_isBackingModePossible ())
+ {
+ if (implts_establishBackingMode ())
+ nResult = css::frame::DispatchResultState::SUCCESS;
+ }
+ }
+
+ implts_notifyResultListener(xListener, nResult, css::uno::Any());
+}
+
+//-----------------------------------------------
+css::uno::Sequence< ::sal_Int16 > SAL_CALL StartModuleDispatcher::getSupportedCommandGroups()
+ throw(css::uno::RuntimeException)
+{
+ return css::uno::Sequence< ::sal_Int16 >();
+}
+
+//-----------------------------------------------
+css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL StartModuleDispatcher::getConfigurableDispatchInformation(::sal_Int16 /*nCommandGroup*/)
+ throw(css::uno::RuntimeException)
+{
+ return css::uno::Sequence< css::frame::DispatchInformation >();
+}
+
+//-----------------------------------------------
+void SAL_CALL StartModuleDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
+ const css::util::URL& /*aURL*/ )
+ throw(css::uno::RuntimeException)
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL StartModuleDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
+ const css::util::URL& /*aURL*/ )
+ throw(css::uno::RuntimeException)
+{
+}
+
+//-----------------------------------------------
+::sal_Bool StartModuleDispatcher::implts_isBackingModePossible ()
+{
+ if ( ! SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE))
+ return sal_False;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
+ xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
+
+ FrameListAnalyzer aCheck(
+ xDesktop,
+ css::uno::Reference< css::frame::XFrame >(),
+ FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT);
+
+ ::sal_Bool bIsPossible = sal_False;
+ ::sal_Int32 nVisibleFrames = aCheck.m_lOtherVisibleFrames.getLength ();
+
+ if (
+ ( ! aCheck.m_xBackingComponent.is ()) &&
+ ( nVisibleFrames < 1 )
+ )
+ {
+ bIsPossible = sal_True;
+ }
+
+ return bIsPossible;
+}
+
+//-----------------------------------------------
+::sal_Bool StartModuleDispatcher::implts_establishBackingMode()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::frame::XFrame > xDesktop (xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XFrame > xFrame = xDesktop->findFrame (SPECIALTARGET_BLANK, 0);
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = xFrame->getContainerWindow ();
+
+ css::uno::Sequence< css::uno::Any > lArgs(1);
+ lArgs[0] <<= xContainerWindow;
+
+ css::uno::Reference< css::frame::XController > xStartModule(
+ xSMGR->createInstanceWithArguments(SERVICENAME_STARTMODULE, lArgs),
+ css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::awt::XWindow > xComponentWindow(xStartModule, css::uno::UNO_QUERY);
+ xFrame->setComponent(xComponentWindow, xStartModule);
+ xStartModule->attachFrame(xFrame);
+ xContainerWindow->setVisible(sal_True);
+
+ return sal_True;
+}
+
+//-----------------------------------------------
+void StartModuleDispatcher::implts_notifyResultListener(const css::uno::Reference< css::frame::XDispatchResultListener >& xListener,
+ ::sal_Int16 nState ,
+ const css::uno::Any& aResult )
+{
+ if ( ! xListener.is())
+ return;
+
+ css::frame::DispatchResultEvent aEvent(
+ css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY),
+ nState,
+ aResult);
+
+ xListener->dispatchFinished(aEvent);
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/systemexec.cxx b/framework/source/dispatch/systemexec.cxx
new file mode 100644
index 000000000000..8f20919ecdb0
--- /dev/null
+++ b/framework/source/dispatch/systemexec.cxx
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <dispatch/systemexec.hxx>
+#include <threadhelp/readguard.hxx>
+#include <general.h>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/system/XSystemShellExecute.hpp>
+#include <com/sun/star/util/XStringSubstitution.hpp>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+#define PROTOCOL_VALUE "systemexecute:"
+#define PROTOCOL_LENGTH 14
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// XInterface, XTypeProvider, XServiceInfo
+
+DEFINE_XINTERFACE_5(SystemExec ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::frame::XDispatchProvider ),
+ DIRECT_INTERFACE(css::frame::XNotifyingDispatch),
+ DIRECT_INTERFACE(css::frame::XDispatch ))
+
+DEFINE_XTYPEPROVIDER_5(SystemExec ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::frame::XDispatchProvider ,
+ css::frame::XNotifyingDispatch,
+ css::frame::XDispatch )
+
+DEFINE_XSERVICEINFO_MULTISERVICE(SystemExec ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_PROTOCOLHANDLER ,
+ IMPLEMENTATIONNAME_SYSTEMEXEC)
+
+DEFINE_INIT_SERVICE(SystemExec,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+ )
+
+//_________________________________________________________________________________________________________________
+
+SystemExec::SystemExec( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+ // Init baseclasses first
+ : ThreadHelpBase( &Application::GetSolarMutex() )
+ , OWeakObject ( )
+ // Init member
+ , m_xFactory ( xFactory )
+{
+}
+
+//_________________________________________________________________________________________________________________
+
+SystemExec::~SystemExec()
+{
+ m_xFactory = NULL;
+}
+
+//_________________________________________________________________________________________________________________
+
+css::uno::Reference< css::frame::XDispatch > SAL_CALL SystemExec::queryDispatch( const css::util::URL& aURL ,
+ const ::rtl::OUString&,
+ sal_Int32 ) throw( css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatcher;
+ if (aURL.Complete.compareToAscii(PROTOCOL_VALUE,PROTOCOL_LENGTH)==0)
+ xDispatcher = this;
+ return xDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL SystemExec::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException )
+{
+ sal_Int32 nCount = lDescriptor.getLength();
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ lDispatcher[i] = this->queryDispatch(
+ lDescriptor[i].FeatureURL,
+ lDescriptor[i].FrameName,
+ lDescriptor[i].SearchFlags);
+ }
+ return lDispatcher;
+}
+
+//_________________________________________________________________________________________________________________
+
+void SAL_CALL SystemExec::dispatch( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException )
+{
+ dispatchWithNotification(aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >());
+}
+
+//_________________________________________________________________________________________________________________
+
+void SAL_CALL SystemExec::dispatchWithNotification( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >&,
+ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ // convert "systemexec:file:///c:/temp/test.html" => "file:///c:/temp/test.html"
+ sal_Int32 c = aURL.Complete.getLength()-PROTOCOL_LENGTH;
+ if (c<1) // we dont check for valid URLs here! The system will show an error message ...
+ {
+ impl_notifyResultListener(xListener, css::frame::DispatchResultState::FAILURE);
+ return;
+ }
+ ::rtl::OUString sSystemURLWithVariables = aURL.Complete.copy(PROTOCOL_LENGTH, c);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
+ aReadLock.unlock();
+ // <- SAFE
+
+ // TODO check security settings ...
+
+ try
+ {
+ css::uno::Reference< css::util::XStringSubstitution > xPathSubst(
+ xFactory->createInstance(SERVICENAME_SUBSTITUTEPATHVARIABLES),
+ css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString sSystemURL = xPathSubst->substituteVariables(sSystemURLWithVariables, sal_True); // sal_True force an exception if unknown variables exists !
+
+ css::uno::Reference< css::system::XSystemShellExecute > xShell(
+ xFactory->createInstance(SERVICENAME_SYSTEMSHELLEXECUTE),
+ css::uno::UNO_QUERY_THROW);
+
+ xShell->execute(sSystemURL, ::rtl::OUString(), css::system::SystemShellExecuteFlags::DEFAULTS);
+ impl_notifyResultListener(xListener, css::frame::DispatchResultState::SUCCESS);
+ }
+ catch(const css::uno::Exception&)
+ {
+ impl_notifyResultListener(xListener, css::frame::DispatchResultState::FAILURE);
+ }
+}
+
+//_________________________________________________________________________________________________________________
+
+void SAL_CALL SystemExec::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >&,
+ const css::util::URL& ) throw( css::uno::RuntimeException )
+{
+ // not suported yet
+}
+
+//_________________________________________________________________________________________________________________
+
+void SAL_CALL SystemExec::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >&,
+ const css::util::URL& ) throw( css::uno::RuntimeException )
+{
+ // not suported yet
+}
+
+//_________________________________________________________________________________________________________________
+
+void SystemExec::impl_notifyResultListener(const css::uno::Reference< css::frame::XDispatchResultListener >& xListener,
+ const sal_Int16 nState )
+{
+ if (xListener.is())
+ {
+ css::frame::DispatchResultEvent aEvent;
+ aEvent.State = nState;
+ xListener->dispatchFinished(aEvent);
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/dispatch/windowcommanddispatch.cxx b/framework/source/dispatch/windowcommanddispatch.cxx
new file mode 100644
index 000000000000..32361382b0a4
--- /dev/null
+++ b/framework/source/dispatch/windowcommanddispatch.cxx
@@ -0,0 +1,211 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// my own includes
+
+#include <dispatch/windowcommanddispatch.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <targets.h>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+//_______________________________________________
+// includes of other projects
+
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/cmdevt.hxx>
+#include <osl/mutex.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <rtl/logfile.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// declarations
+
+const ::rtl::OUString WindowCommandDispatch::COMMAND_PREFERENCES(RTL_CONSTASCII_USTRINGPARAM(".uno:OptionsTreeDialog"));
+const ::rtl::OUString WindowCommandDispatch::COMMAND_ABOUTBOX(RTL_CONSTASCII_USTRINGPARAM(".uno:About"));
+
+//-----------------------------------------------
+WindowCommandDispatch::WindowCommandDispatch(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xFrame)
+ : ThreadHelpBase( )
+ , m_xSMGR (xSMGR )
+ , m_xFrame (xFrame )
+ , m_xWindow (xFrame->getContainerWindow())
+{
+ impl_startListening();
+}
+
+//-----------------------------------------------
+WindowCommandDispatch::~WindowCommandDispatch()
+{
+ impl_stopListening();
+ m_xSMGR.clear();
+}
+
+//-----------------------------------------------
+void WindowCommandDispatch::impl_startListening()
+{
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::awt::XWindow > xWindow( m_xWindow.get(), css::uno::UNO_QUERY );
+ aReadLock.unlock();
+
+ if ( ! xWindow.is())
+ return;
+
+ {
+ SolarMutexGuard aSolarLock;
+
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ if ( ! pWindow)
+ return;
+
+ pWindow->AddEventListener( LINK(this, WindowCommandDispatch, impl_notifyCommand) );
+ }
+}
+
+void WindowCommandDispatch::impl_stopListening()
+{
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::awt::XWindow > xWindow( m_xWindow.get(), css::uno::UNO_QUERY );
+ aReadLock.unlock();
+
+ if (!xWindow.is())
+ return;
+
+ {
+ SolarMutexGuard aSolarLock;
+
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ if (!pWindow)
+ return;
+
+ pWindow->RemoveEventListener( LINK(this, WindowCommandDispatch, impl_notifyCommand) );
+
+ m_xWindow.clear();
+ }
+}
+
+
+//-----------------------------------------------
+IMPL_LINK(WindowCommandDispatch, impl_notifyCommand, void*, pParam)
+{
+ if ( ! pParam)
+ return 0L;
+
+ const VclWindowEvent* pEvent = (VclWindowEvent*)pParam;
+ if (pEvent->GetId() == VCLEVENT_OBJECT_DYING)
+ {
+ impl_stopListening();
+ return 0L;
+ }
+ if (pEvent->GetId() != VCLEVENT_WINDOW_COMMAND)
+ return 0L;
+
+ const CommandEvent* pCommand = (CommandEvent*)pEvent->GetData();
+ if (pCommand->GetCommand() != COMMAND_SHOWDIALOG)
+ return 0L;
+
+ const CommandDialogData* pData = pCommand->GetDialogData();
+ if ( ! pData)
+ return 0L;
+
+ const int nCommand = pData->GetDialogId();
+ ::rtl::OUString sCommand;
+
+ switch (nCommand)
+ {
+ case SHOWDIALOG_ID_PREFERENCES :
+ sCommand = WindowCommandDispatch::COMMAND_PREFERENCES;
+ break;
+
+ case SHOWDIALOG_ID_ABOUT :
+ sCommand = WindowCommandDispatch::COMMAND_ABOUTBOX;
+ break;
+
+ default :
+ return 0L;
+ }
+
+ impl_dispatchCommand(sCommand);
+
+ return 0L;
+}
+
+//-----------------------------------------------
+void WindowCommandDispatch::impl_dispatchCommand(const ::rtl::OUString& sCommand)
+{
+ // ignore all errors here. It's clicking a menu entry only ...
+ // The user will try it again, in case nothing happens .-)
+ try
+ {
+ // SYNCHRONIZED ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider(m_xFrame.get(), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SYNCHRONIZED
+
+ // check provider ... we know it's weak reference only
+ if ( ! xProvider.is())
+ return;
+
+ css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
+ css::util::URL aCommand;
+ aCommand.Complete = sCommand;
+ xParser->parseStrict(aCommand);
+
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aCommand, SPECIALTARGET_SELF, 0);
+ if (xDispatch.is())
+ xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
+ }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/actiontriggercontainer.cxx b/framework/source/fwe/classes/actiontriggercontainer.cxx
new file mode 100644
index 000000000000..00bd461e2f8b
--- /dev/null
+++ b/framework/source/fwe/classes/actiontriggercontainer.cxx
@@ -0,0 +1,205 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <classes/actiontriggercontainer.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+#include <classes/actiontriggerpropertyset.hxx>
+#include <classes/actiontriggerseparatorpropertyset.hxx>
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+
+namespace framework
+{
+
+ActionTriggerContainer::ActionTriggerContainer( const Reference< XMultiServiceFactory >& rServiceManager ) :
+ PropertySetContainer( rServiceManager )
+{
+}
+
+
+ActionTriggerContainer::~ActionTriggerContainer()
+{
+}
+
+// XInterface
+Any SAL_CALL ActionTriggerContainer::queryInterface( const Type& aType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ aType ,
+ SAL_STATIC_CAST( XMultiServiceFactory*, this ),
+ SAL_STATIC_CAST( XServiceInfo* , this ));
+
+ if( a.hasValue() )
+ {
+ return a;
+ }
+
+ return PropertySetContainer::queryInterface( aType );
+}
+
+void ActionTriggerContainer::acquire() throw()
+{
+ PropertySetContainer::acquire();
+}
+
+void ActionTriggerContainer::release() throw()
+{
+ PropertySetContainer::release();
+}
+
+
+// XMultiServiceFactory
+Reference< XInterface > SAL_CALL ActionTriggerContainer::createInstance( const ::rtl::OUString& aServiceSpecifier )
+throw ( ::com::sun::star::uno::Exception, RuntimeException)
+{
+ if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGER ))
+ return (OWeakObject *)( new ActionTriggerPropertySet( m_xServiceManager ));
+ else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER ))
+ return (OWeakObject *)( new ActionTriggerContainer( m_xServiceManager ));
+ else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERSEPARATOR ))
+ return (OWeakObject *)( new ActionTriggerSeparatorPropertySet( m_xServiceManager ));
+ else
+ throw com::sun::star::uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown service specifier!" )), (OWeakObject *)this );
+}
+
+
+Reference< XInterface > SAL_CALL ActionTriggerContainer::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/ )
+throw ( Exception, RuntimeException)
+{
+ return createInstance( ServiceSpecifier );
+}
+
+
+Sequence< ::rtl::OUString > SAL_CALL ActionTriggerContainer::getAvailableServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > aSeq( 3 );
+
+ aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGER ));
+ aSeq[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER ));
+ aSeq[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERSEPARATOR ));
+
+ return aSeq;
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL ActionTriggerContainer::getImplementationName()
+throw ( RuntimeException )
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATIONNAME_ACTIONTRIGGERCONTAINER ));
+}
+
+sal_Bool SAL_CALL ActionTriggerContainer::supportsService( const ::rtl::OUString& ServiceName )
+throw ( RuntimeException )
+{
+ if ( ServiceName.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER ))
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ActionTriggerContainer::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > seqServiceNames( 1 );
+
+ seqServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER ));
+ return seqServiceNames;
+}
+
+// XTypeProvider
+Sequence< Type > SAL_CALL ActionTriggerContainer::getTypes() throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ if ( pTypeCollection == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pTypeCollection == NULL )
+ {
+ // Create a static typecollection ...
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType(( const Reference< XMultiServiceFactory >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexContainer >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexAccess >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexReplace >*)NULL ) ,
+ ::getCppuType(( const Reference< XServiceInfo >*)NULL ) ,
+ ::getCppuType(( const Reference< XTypeProvider >*)NULL ) ) ;
+
+ // ... and set his address to static pointer!
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+Sequence< sal_Int8 > SAL_CALL ActionTriggerContainer::getImplementationId() throw ( RuntimeException )
+{
+ // Create one Id for all instances of this class.
+ // Use ethernet address to do this! (sal_True)
+
+ // Optimize this method
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pID is NULL - for the second call pID is different from NULL!
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pID == NULL )
+ {
+ // Create a new static ID ...
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ // ... and set his address to static pointer!
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/actiontriggerpropertyset.cxx b/framework/source/fwe/classes/actiontriggerpropertyset.cxx
new file mode 100644
index 000000000000..6be1ddd537e6
--- /dev/null
+++ b/framework/source/fwe/classes/actiontriggerpropertyset.cxx
@@ -0,0 +1,482 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <classes/actiontriggerpropertyset.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <cppuhelper/proptypehlp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <vcl/svapp.hxx>
+
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::awt;
+
+//struct SAL_DLLPUBLIC_IMPORT ::cppu::OBroadcastHelperVar< OMultiTypeInterfaceContainerHelper, OMultiTypeInterfaceContainerHelper::keyType >;
+
+// Handles for properties
+// (PLEASE SORT THIS FIELD, IF YOU ADD NEW PROPERTIES!)
+// We use an enum to define these handles, to use all numbers from 0 to nn and
+// if you add someone, you don't must control this!
+// But don't forget to change values of follow defines, if you do something with this enum!
+enum EPROPERTIES
+{
+ HANDLE_COMMANDURL,
+ HANDLE_HELPURL,
+ HANDLE_IMAGE,
+ HANDLE_SUBCONTAINER,
+ HANDLE_TEXT,
+ PROPERTYCOUNT
+};
+
+namespace framework
+{
+
+ActionTriggerPropertySet::ActionTriggerPropertySet( const Reference< XMultiServiceFactory >& /*xServiceManager*/ )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , OBroadcastHelper ( m_aLock.getShareableOslMutex() )
+ , OPropertySetHelper ( *SAL_STATIC_CAST( OBroadcastHelper *, this ))
+ , OWeakObject ()
+ , m_xBitmap ( 0 )
+ , m_xActionTriggerContainer( 0 )
+{
+}
+
+ActionTriggerPropertySet::~ActionTriggerPropertySet()
+{
+}
+
+// XInterface
+Any SAL_CALL ActionTriggerPropertySet::queryInterface( const Type& aType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ aType ,
+ SAL_STATIC_CAST( XServiceInfo*, this ));
+
+ if( a.hasValue() )
+ return a;
+ else
+ {
+ a = OPropertySetHelper::queryInterface( aType );
+
+ if( a.hasValue() )
+ return a;
+ }
+
+ return OWeakObject::queryInterface( aType );
+}
+
+void SAL_CALL ActionTriggerPropertySet::acquire() throw ()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL ActionTriggerPropertySet::release() throw ()
+{
+ OWeakObject::release();
+}
+
+
+// XServiceInfo
+::rtl::OUString SAL_CALL ActionTriggerPropertySet::getImplementationName()
+throw ( RuntimeException )
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATIONNAME_ACTIONTRIGGER ));
+}
+
+sal_Bool SAL_CALL ActionTriggerPropertySet::supportsService( const ::rtl::OUString& ServiceName )
+throw ( RuntimeException )
+{
+ if ( ServiceName.equalsAscii( SERVICENAME_ACTIONTRIGGER ))
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ActionTriggerPropertySet::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > seqServiceNames( 1 );
+ seqServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGER ));
+ return seqServiceNames;
+}
+
+// XTypeProvider
+Sequence< Type > SAL_CALL ActionTriggerPropertySet::getTypes() throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ if ( pTypeCollection == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pTypeCollection == NULL )
+ {
+ // Create a static typecollection ...
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType(( const Reference< XPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XFastPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XMultiPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XServiceInfo >*)NULL ) ,
+ ::getCppuType(( const Reference< XTypeProvider >*)NULL ) ) ;
+
+ // ... and set his address to static pointer!
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+Sequence< sal_Int8 > SAL_CALL ActionTriggerPropertySet::getImplementationId() throw ( RuntimeException )
+{
+ // Create one Id for all instances of this class.
+ // Use ethernet address to do this! (sal_True)
+
+ // Optimize this method
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pID is NULL - for the second call pID is different from NULL!
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pID == NULL )
+ {
+ // Create a new static ID ...
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ // ... and set his address to static pointer!
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// OPropertySetHelper implementation
+//---------------------------------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ActionTriggerPropertySet::convertFastPropertyValue(
+ Any& aConvertedValue,
+ Any& aOldValue,
+ sal_Int32 nHandle,
+ const Any& aValue )
+throw( IllegalArgumentException )
+{
+ // Check, if value of property will changed in method "setFastPropertyValue_NoBroadcast()".
+ // Return sal_True, if changed - else return sal_False.
+ // Attention: Method "impl_tryToChangeProperty()" can throw the IllegalArgumentException !!!
+ // Initialize return value with sal_False !!!
+ // (Handle can be invalid)
+ sal_Bool bReturn = sal_False;
+
+ switch( nHandle )
+ {
+ case HANDLE_COMMANDURL:
+ bReturn = impl_tryToChangeProperty( m_aCommandURL, aValue, aOldValue, aConvertedValue );
+ break;
+
+ case HANDLE_HELPURL:
+ bReturn = impl_tryToChangeProperty( m_aHelpURL, aValue, aOldValue, aConvertedValue ) ;
+ break;
+
+ case HANDLE_IMAGE:
+ bReturn = impl_tryToChangeProperty( m_xBitmap, aValue, aOldValue, aConvertedValue ) ;
+ break;
+
+ case HANDLE_SUBCONTAINER:
+ bReturn = impl_tryToChangeProperty( m_xActionTriggerContainer, aValue, aOldValue, aConvertedValue );
+ break;
+
+ case HANDLE_TEXT:
+ bReturn = impl_tryToChangeProperty( m_aText, aValue, aOldValue, aConvertedValue ) ;
+ break;
+ }
+
+ // Return state of operation.
+ return bReturn;
+}
+
+
+void SAL_CALL ActionTriggerPropertySet::setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle, const Any& aValue )
+throw( Exception )
+{
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+
+ // Search for right handle ... and try to set property value.
+ switch( nHandle )
+ {
+ case HANDLE_COMMANDURL:
+ aValue >>= m_aCommandURL;
+ break;
+
+ case HANDLE_HELPURL:
+ aValue >>= m_aHelpURL;
+ break;
+
+ case HANDLE_IMAGE:
+ aValue >>= m_xBitmap;
+ break;
+
+ case HANDLE_SUBCONTAINER:
+ aValue >>= m_xActionTriggerContainer;
+ break;
+
+ case HANDLE_TEXT:
+ aValue >>= m_aText;
+ break;
+ }
+}
+
+void SAL_CALL ActionTriggerPropertySet::getFastPropertyValue(
+ Any& aValue, sal_Int32 nHandle ) const
+{
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+
+ // Search for right handle ... and try to get property value.
+ switch( nHandle )
+ {
+ case HANDLE_COMMANDURL:
+ aValue <<= m_aCommandURL;
+ break;
+
+ case HANDLE_HELPURL:
+ aValue <<= m_aHelpURL;
+ break;
+
+ case HANDLE_IMAGE:
+ aValue <<= m_xBitmap;
+ break;
+
+ case HANDLE_SUBCONTAINER:
+ aValue <<= m_xActionTriggerContainer;
+ break;
+
+ case HANDLE_TEXT:
+ aValue <<= m_aText;
+ break;
+ }
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL ActionTriggerPropertySet::getInfoHelper()
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
+ static OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ // Ready for multithreading
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfoHelper == NULL )
+ {
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
+ // "sal_True" say: Table is sorted by name.
+ static OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return (*pInfoHelper);
+}
+
+Reference< XPropertySetInfo > SAL_CALL ActionTriggerPropertySet::getPropertySetInfo()
+throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
+ static Reference< XPropertySetInfo >* pInfo = NULL ;
+
+ if( pInfo == NULL )
+ {
+ // Ready for multithreading
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfo == NULL )
+ {
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+const Sequence< Property > ActionTriggerPropertySet::impl_getStaticPropertyDescriptor()
+{
+ static const Property pActionTriggerPropertys[] =
+ {
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" )), HANDLE_COMMANDURL , ::getCppuType((::rtl::OUString*)0) , PropertyAttribute::TRANSIENT ),
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpURL" )), HANDLE_HELPURL , ::getCppuType((::rtl::OUString*)0) , PropertyAttribute::TRANSIENT ),
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Image" )), HANDLE_IMAGE , ::getCppuType((Reference<XBitmap>*)0) , PropertyAttribute::TRANSIENT ),
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SubContainer" )), HANDLE_SUBCONTAINER , ::getCppuType((::rtl::OUString*)0) , PropertyAttribute::TRANSIENT ),
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" )), HANDLE_TEXT , ::getCppuType((Reference<XInterface>*)0) , PropertyAttribute::TRANSIENT )
+ };
+
+ // Use it to initialize sequence!
+ static const Sequence< Property > seqActionTriggerPropertyDescriptor( pActionTriggerPropertys, PROPERTYCOUNT );
+
+ // Return static "PropertyDescriptor"
+ return seqActionTriggerPropertyDescriptor ;
+}
+
+
+//******************************************************************************************************************************
+// private method
+//******************************************************************************************************************************
+sal_Bool ActionTriggerPropertySet::impl_tryToChangeProperty(
+ const ::rtl::OUString& sCurrentValue ,
+ const Any& aNewValue ,
+ Any& aOldValue ,
+ Any& aConvertedValue )
+throw( IllegalArgumentException )
+{
+ // Set default return value if method failed.
+ sal_Bool bReturn = sal_False;
+ // Get new value from any.
+ // IllegalArgumentException() can be thrown!
+ ::rtl::OUString sValue ;
+ convertPropertyValue( sValue, aNewValue );
+
+ // If value change ...
+ if( sValue != sCurrentValue )
+ {
+ // ... set information of change.
+ aOldValue <<= sCurrentValue ;
+ aConvertedValue <<= sValue ;
+ // Return OK - "value will be change ..."
+ bReturn = sal_True;
+ }
+ else
+ {
+ // ... clear information of return parameter!
+ aOldValue.clear () ;
+ aConvertedValue.clear () ;
+ // Return NOTHING - "value will not be change ..."
+ bReturn = sal_False;
+ }
+
+ return bReturn;
+}
+
+
+sal_Bool ActionTriggerPropertySet::impl_tryToChangeProperty(
+ const Reference< XBitmap > aCurrentValue ,
+ const Any& aNewValue ,
+ Any& aOldValue ,
+ Any& aConvertedValue )
+throw( IllegalArgumentException )
+{
+ // Set default return value if method failed.
+ sal_Bool bReturn = sal_False;
+ // Get new value from any.
+ // IllegalArgumentException() can be thrown!
+ Reference< XBitmap > aValue ;
+ convertPropertyValue( aValue, aNewValue );
+
+ // If value change ...
+ if( aValue != aCurrentValue )
+ {
+ // ... set information of change.
+ aOldValue <<= aCurrentValue ;
+ aConvertedValue <<= aValue ;
+ // Return OK - "value will be change ..."
+ bReturn = sal_True;
+ }
+ else
+ {
+ // ... clear information of return parameter!
+ aOldValue.clear () ;
+ aConvertedValue.clear () ;
+ // Return NOTHING - "value will not be change ..."
+ bReturn = sal_False;
+ }
+
+ return bReturn;
+}
+
+sal_Bool ActionTriggerPropertySet::impl_tryToChangeProperty(
+ const Reference< XInterface > aCurrentValue ,
+ const Any& aNewValue ,
+ Any& aOldValue ,
+ Any& aConvertedValue )
+throw( IllegalArgumentException )
+{
+ // Set default return value if method failed.
+ sal_Bool bReturn = sal_False;
+ // Get new value from any.
+ // IllegalArgumentException() can be thrown!
+ Reference< XInterface > aValue ;
+ convertPropertyValue( aValue, aNewValue );
+
+ // If value change ...
+ if( aValue != aCurrentValue )
+ {
+ // ... set information of change.
+ aOldValue <<= aCurrentValue ;
+ aConvertedValue <<= aValue ;
+ // Return OK - "value will be change ..."
+ bReturn = sal_True;
+ }
+ else
+ {
+ // ... clear information of return parameter!
+ aOldValue.clear () ;
+ aConvertedValue.clear () ;
+ // Return NOTHING - "value will not be change ..."
+ bReturn = sal_False;
+ }
+
+ return bReturn;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/actiontriggerseparatorpropertyset.cxx b/framework/source/fwe/classes/actiontriggerseparatorpropertyset.cxx
new file mode 100644
index 000000000000..0597b2d09837
--- /dev/null
+++ b/framework/source/fwe/classes/actiontriggerseparatorpropertyset.cxx
@@ -0,0 +1,351 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <classes/actiontriggerseparatorpropertyset.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <cppuhelper/proptypehlp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <vcl/svapp.hxx>
+
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::awt;
+
+// Handles for properties
+// (PLEASE SORT THIS FIELD, IF YOU ADD NEW PROPERTIES!)
+// We use an enum to define these handles, to use all numbers from 0 to nn and
+// if you add someone, you don't must control this!
+// But don't forget to change values of follow defines, if you do something with this enum!
+enum EPROPERTIES
+{
+ HANDLE_TYPE,
+ PROPERTYCOUNT
+};
+
+namespace framework
+{
+
+ActionTriggerSeparatorPropertySet::ActionTriggerSeparatorPropertySet( const Reference< XMultiServiceFactory >& /*ServiceManager*/ )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , OBroadcastHelper ( m_aLock.getShareableOslMutex() )
+ , OPropertySetHelper ( *SAL_STATIC_CAST( OBroadcastHelper *, this ) )
+ , OWeakObject ( )
+ , m_nSeparatorType( 0 )
+{
+}
+
+ActionTriggerSeparatorPropertySet::~ActionTriggerSeparatorPropertySet()
+{
+}
+
+// XInterface
+Any SAL_CALL ActionTriggerSeparatorPropertySet::queryInterface( const Type& aType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ aType ,
+ SAL_STATIC_CAST( XServiceInfo*, this ));
+
+ if( a.hasValue() )
+ return a;
+ else
+ {
+ a = OPropertySetHelper::queryInterface( aType );
+
+ if( a.hasValue() )
+ return a;
+ }
+
+ return OWeakObject::queryInterface( aType );
+}
+
+void ActionTriggerSeparatorPropertySet::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+void ActionTriggerSeparatorPropertySet::release() throw()
+{
+ OWeakObject::release();
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL ActionTriggerSeparatorPropertySet::getImplementationName()
+throw ( RuntimeException )
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATIONNAME_ACTIONTRIGGERSEPARATOR ));
+}
+
+sal_Bool SAL_CALL ActionTriggerSeparatorPropertySet::supportsService( const ::rtl::OUString& ServiceName )
+throw ( RuntimeException )
+{
+ if ( ServiceName.equalsAscii( SERVICENAME_ACTIONTRIGGERSEPARATOR ))
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ActionTriggerSeparatorPropertySet::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > seqServiceNames( 1 );
+ seqServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERSEPARATOR ));
+ return seqServiceNames;
+}
+
+// XTypeProvider
+Sequence< Type > SAL_CALL ActionTriggerSeparatorPropertySet::getTypes() throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ if ( pTypeCollection == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pTypeCollection == NULL )
+ {
+ // Create a static typecollection ...
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType(( const Reference< XPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XFastPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XMultiPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XServiceInfo >*)NULL ) ,
+ ::getCppuType(( const Reference< XTypeProvider >*)NULL ) ) ;
+
+ // ... and set his address to static pointer!
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+Sequence< sal_Int8 > SAL_CALL ActionTriggerSeparatorPropertySet::getImplementationId() throw ( RuntimeException )
+{
+ // Create one Id for all instances of this class.
+ // Use ethernet address to do this! (sal_True)
+
+ // Optimize this method
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pID is NULL - for the second call pID is different from NULL!
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pID == NULL )
+ {
+ // Create a new static ID ...
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ // ... and set his address to static pointer!
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// OPropertySetHelper implementation
+//---------------------------------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ActionTriggerSeparatorPropertySet::convertFastPropertyValue(
+ Any& aConvertedValue,
+ Any& aOldValue,
+ sal_Int32 nHandle,
+ const Any& aValue )
+throw( IllegalArgumentException )
+{
+ // Check, if value of property will changed in method "setFastPropertyValue_NoBroadcast()".
+ // Return sal_True, if changed - else return sal_False.
+ // Attention: Method "impl_tryToChangeProperty()" can throw the IllegalArgumentException !!!
+ // Initialize return value with sal_False !!!
+ // (Handle can be invalid)
+ sal_Bool bReturn = sal_False;
+
+ switch( nHandle )
+ {
+ case HANDLE_TYPE:
+ bReturn = impl_tryToChangeProperty( m_nSeparatorType, aValue, aOldValue, aConvertedValue );
+ break;
+ }
+
+ // Return state of operation.
+ return bReturn;
+}
+
+
+void SAL_CALL ActionTriggerSeparatorPropertySet::setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle, const Any& aValue )
+throw( Exception )
+{
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+
+ // Search for right handle ... and try to set property value.
+ switch( nHandle )
+ {
+ case HANDLE_TYPE:
+ aValue >>= m_nSeparatorType;
+ break;
+ }
+}
+
+void SAL_CALL ActionTriggerSeparatorPropertySet::getFastPropertyValue(
+ Any& aValue, sal_Int32 nHandle ) const
+{
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+
+ // Search for right handle ... and try to get property value.
+ switch( nHandle )
+ {
+ case HANDLE_TYPE:
+ aValue <<= m_nSeparatorType;
+ break;
+ }
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL ActionTriggerSeparatorPropertySet::getInfoHelper()
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
+ static OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ // Ready for multithreading
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfoHelper == NULL )
+ {
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
+ // "sal_True" say: Table is sorted by name.
+ static OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return (*pInfoHelper);
+}
+
+Reference< XPropertySetInfo > SAL_CALL ActionTriggerSeparatorPropertySet::getPropertySetInfo()
+throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
+ static Reference< XPropertySetInfo >* pInfo = NULL ;
+
+ if( pInfo == NULL )
+ {
+ // Ready for multithreading
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfo == NULL )
+ {
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+const Sequence< Property > ActionTriggerSeparatorPropertySet::impl_getStaticPropertyDescriptor()
+{
+ static const Property pActionTriggerPropertys[] =
+ {
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SeparatorType" )), HANDLE_TYPE, ::getCppuType((sal_Int16*)0), PropertyAttribute::TRANSIENT )
+ };
+
+ // Use it to initialize sequence!
+ static const Sequence< Property > seqActionTriggerPropertyDescriptor( pActionTriggerPropertys, PROPERTYCOUNT );
+
+ // Return static "PropertyDescriptor"
+ return seqActionTriggerPropertyDescriptor ;
+}
+
+
+//******************************************************************************************************************************
+// private method
+//******************************************************************************************************************************
+sal_Bool ActionTriggerSeparatorPropertySet::impl_tryToChangeProperty(
+ sal_Int16 aCurrentValue ,
+ const Any& aNewValue ,
+ Any& aOldValue ,
+ Any& aConvertedValue )
+throw( IllegalArgumentException )
+{
+ // Set default return value if method failed.
+ sal_Bool bReturn = sal_False;
+ // Get new value from any.
+ // IllegalArgumentException() can be thrown!
+ sal_Int16 aValue = 0;
+ convertPropertyValue( aValue, aNewValue );
+
+ // If value change ...
+ if( aValue != aCurrentValue )
+ {
+ // ... set information of change.
+ aOldValue <<= aCurrentValue ;
+ aConvertedValue <<= aValue ;
+ // Return OK - "value will be change ..."
+ bReturn = sal_True;
+ }
+ else
+ {
+ // ... clear information of return parameter!
+ aOldValue.clear () ;
+ aConvertedValue.clear () ;
+ // Return NOTHING - "value will not be change ..."
+ bReturn = sal_False;
+ }
+
+ return bReturn;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/addonmenu.cxx b/framework/source/fwe/classes/addonmenu.cxx
new file mode 100644
index 000000000000..baaf086e4702
--- /dev/null
+++ b/framework/source/fwe/classes/addonmenu.cxx
@@ -0,0 +1,458 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "framework/addonmenu.hxx"
+#include "framework/addonsoptions.hxx"
+#include <general.h>
+#include <macros/debug/assertion.hxx>
+#include <framework/imageproducer.hxx>
+#include <framework/menuconfiguration.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <tools/config.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/menuoptions.hxx>
+#include <svl/solar.hrc>
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+
+// Please look at sfx2/inc/sfxsids.hrc the values are defined there. Due to build dependencies
+// we cannot include the header file.
+const sal_uInt16 SID_HELPMENU = (SID_SFX_START + 410);
+const sal_uInt16 SID_ONLINE_REGISTRATION = (SID_SFX_START + 1537);
+
+namespace framework
+{
+
+AddonMenu::AddonMenu( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame ) :
+ m_xFrame( rFrame )
+{
+}
+
+AddonMenu::~AddonMenu()
+{
+ for ( sal_uInt16 i = 0; i < GetItemCount(); i++ )
+ {
+ if ( GetItemType( i ) != MENUITEM_SEPARATOR )
+ {
+ // delete user attributes created with new!
+ sal_uInt16 nId = GetItemId( i );
+ MenuConfiguration::Attributes* pUserAttributes = (MenuConfiguration::Attributes*)GetUserValue( nId );
+ delete pUserAttributes;
+ delete GetPopupMenu( nId );
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------
+// Check if command URL string has the unique prefix to identify addon popup menus
+sal_Bool AddonPopupMenu::IsCommandURLPrefix( const ::rtl::OUString& aCmdURL )
+{
+ const char aPrefixCharBuf[] = ADDONSPOPUPMENU_URL_PREFIX_STR;
+
+ return aCmdURL.matchAsciiL( aPrefixCharBuf, sizeof( aPrefixCharBuf )-1, 0 );
+}
+
+AddonPopupMenu::AddonPopupMenu( const com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& rFrame ) :
+ AddonMenu( rFrame )
+{
+}
+
+AddonPopupMenu::~AddonPopupMenu()
+{
+}
+
+// ------------------------------------------------------------------------
+
+static Reference< XModel > GetModelFromFrame( const Reference< XFrame >& rFrame )
+{
+ // Query for the model to get check the context information
+ Reference< XModel > xModel;
+ if ( rFrame.is() )
+ {
+ Reference< XController > xController( rFrame->getController(), UNO_QUERY );
+ if ( xController.is() )
+ xModel = xController->getModel();
+ }
+
+ return xModel;
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool AddonMenuManager::HasAddonMenuElements()
+{
+ return AddonsOptions().HasAddonsMenu();
+}
+
+sal_Bool AddonMenuManager::HasAddonHelpMenuElements()
+{
+ return AddonsOptions().HasAddonsHelpMenu();
+}
+
+// Factory method to create different Add-On menu types
+PopupMenu* AddonMenuManager::CreatePopupMenuType( MenuType eMenuType, const Reference< XFrame >& rFrame )
+{
+ if ( eMenuType == ADDON_MENU )
+ return new AddonMenu( rFrame );
+ else if ( eMenuType == ADDON_POPUPMENU )
+ return new AddonPopupMenu( rFrame );
+ else
+ return NULL;
+}
+
+// Create the Add-Ons menu
+AddonMenu* AddonMenuManager::CreateAddonMenu( const Reference< XFrame >& rFrame )
+{
+ AddonsOptions aOptions;
+ AddonMenu* pAddonMenu = NULL;
+ sal_uInt16 nUniqueMenuId = ADDONMENU_ITEMID_START;
+
+ const Sequence< Sequence< PropertyValue > >& rAddonMenuEntries = aOptions.GetAddonsMenu();
+ if ( rAddonMenuEntries.getLength() > 0 )
+ {
+ pAddonMenu = (AddonMenu *)AddonMenuManager::CreatePopupMenuType( ADDON_MENU, rFrame );
+ Reference< XModel > xModel = GetModelFromFrame( rFrame );
+ AddonMenuManager::BuildMenu( pAddonMenu, ADDON_MENU, MENU_APPEND, nUniqueMenuId, rAddonMenuEntries, rFrame, xModel );
+
+ // Don't return an empty Add-On menu
+ if ( pAddonMenu->GetItemCount() == 0 )
+ {
+ delete pAddonMenu;
+ pAddonMenu = NULL;
+ }
+ }
+
+ return pAddonMenu;
+}
+
+// Returns the next insert position from nPos.
+sal_uInt16 AddonMenuManager::GetNextPos( sal_uInt16 nPos )
+{
+ return ( nPos == MENU_APPEND ) ? MENU_APPEND : ( nPos+1 );
+}
+
+
+static sal_uInt16 FindMenuId( Menu* pMenu, const String aCommand )
+{
+ sal_uInt16 nPos = 0;
+ String aCmd;
+ for ( nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
+ {
+ sal_uInt16 nId = pMenu->GetItemId( nPos );
+ aCmd = pMenu->GetItemCommand( nId );
+ if ( aCmd == aCommand )
+ return nId;
+ }
+
+ return USHRT_MAX;
+}
+
+
+// Merge the Add-Ons help menu items into the given menu bar at a defined pos
+void AddonMenuManager::MergeAddonHelpMenu( const Reference< XFrame >& rFrame, MenuBar* pMergeMenuBar )
+{
+ if ( pMergeMenuBar )
+ {
+ PopupMenu* pHelpMenu = pMergeMenuBar->GetPopupMenu( SID_HELPMENU );
+ if ( !pHelpMenu )
+ {
+ sal_uInt16 nId = FindMenuId( pMergeMenuBar, String::CreateFromAscii( ".uno:HelpMenu" ));
+ if ( nId != USHRT_MAX )
+ pHelpMenu = pMergeMenuBar->GetPopupMenu( nId );
+ }
+
+ if ( pHelpMenu )
+ {
+ static const char REFERENCECOMMAND_AFTER[] = ".uno:OnlineRegistrationDlg";
+ static const char REFERENCECOMMAND_BEFORE[] = ".uno:About";
+
+ // Add-Ons help menu items should be inserted after the "registration" menu item
+ bool bAddAfter = true;
+ sal_uInt16 nItemCount = pHelpMenu->GetItemCount();
+ sal_uInt16 nRegPos = pHelpMenu->GetItemPos( SID_ONLINE_REGISTRATION );
+ sal_uInt16 nInsPos = nRegPos;
+ sal_uInt16 nInsSepAfterPos = MENU_APPEND;
+ sal_uInt16 nUniqueMenuId = ADDONMENU_ITEMID_START;
+ AddonsOptions aOptions;
+
+ if ( nRegPos == USHRT_MAX )
+ {
+ // try to detect the online registration dialog menu item with the command URL
+ sal_uInt16 nId = FindMenuId( pHelpMenu, String::CreateFromAscii( REFERENCECOMMAND_AFTER ));
+ nRegPos = pHelpMenu->GetItemPos( nId );
+ nInsPos = nRegPos;
+ }
+
+ if ( nRegPos == USHRT_MAX )
+ {
+ // second try:
+ // try to detect the about menu item with the command URL
+ sal_uInt16 nId = FindMenuId( pHelpMenu, String::CreateFromAscii( REFERENCECOMMAND_BEFORE ));
+ nRegPos = pHelpMenu->GetItemPos( nId );
+ nInsPos = nRegPos;
+ bAddAfter = false;
+ }
+
+ Sequence< Sequence< PropertyValue > > aAddonSubMenu;
+ const Sequence< Sequence< PropertyValue > >& rAddonHelpMenuEntries = aOptions.GetAddonsHelpMenu();
+
+ nInsPos = bAddAfter ? AddonMenuManager::GetNextPos( nInsPos ) : nInsPos;
+ if ( nInsPos < nItemCount && pHelpMenu->GetItemType( nInsPos ) != MENUITEM_SEPARATOR )
+ nInsSepAfterPos = nInsPos;
+
+ Reference< XModel > xModel = GetModelFromFrame( rFrame );
+ AddonMenuManager::BuildMenu( pHelpMenu, ADDON_MENU, nInsPos, nUniqueMenuId, rAddonHelpMenuEntries, rFrame, xModel );
+
+ if ( pHelpMenu->GetItemCount() > nItemCount )
+ {
+ if ( nInsSepAfterPos < MENU_APPEND )
+ {
+ nInsSepAfterPos += ( pHelpMenu->GetItemCount() - nItemCount );
+ if ( pHelpMenu->GetItemType( nInsSepAfterPos ) != MENUITEM_SEPARATOR )
+ pHelpMenu->InsertSeparator( nInsSepAfterPos );
+ }
+ if ( nRegPos < MENU_APPEND )
+ pHelpMenu->InsertSeparator( nRegPos+1 );
+ else
+ pHelpMenu->InsertSeparator( nItemCount );
+ }
+ }
+ }
+}
+
+// Merge the addon popup menus into the given menu bar at the provided pos.
+void AddonMenuManager::MergeAddonPopupMenus( const Reference< XFrame >& rFrame,
+ const Reference< XModel >& rModel,
+ sal_uInt16 nMergeAtPos,
+ MenuBar* pMergeMenuBar )
+{
+ if ( pMergeMenuBar )
+ {
+ AddonsOptions aAddonsOptions;
+ sal_uInt16 nInsertPos = nMergeAtPos;
+
+ ::rtl::OUString aTitle;
+ ::rtl::OUString aURL;
+ ::rtl::OUString aTarget;
+ ::rtl::OUString aImageId;
+ ::rtl::OUString aContext;
+ Sequence< Sequence< PropertyValue > > aAddonSubMenu;
+ sal_uInt16 nUniqueMenuId = ADDONMENU_ITEMID_START;
+
+ const Sequence< Sequence< PropertyValue > >& rAddonMenuEntries = aAddonsOptions.GetAddonsMenuBarPart();
+ for ( sal_Int32 i = 0; i < rAddonMenuEntries.getLength(); i++ )
+ {
+ AddonMenuManager::GetMenuEntry( rAddonMenuEntries[i],
+ aTitle,
+ aURL,
+ aTarget,
+ aImageId,
+ aContext,
+ aAddonSubMenu );
+ if ( aTitle.getLength() > 0 &&
+ aURL.getLength() > 0 &&
+ aAddonSubMenu.getLength() > 0 &&
+ AddonMenuManager::IsCorrectContext( rModel, aContext ))
+ {
+ sal_uInt16 nId = nUniqueMenuId++;
+ AddonPopupMenu* pAddonPopupMenu = (AddonPopupMenu *)AddonMenuManager::CreatePopupMenuType( ADDON_POPUPMENU, rFrame );
+
+ AddonMenuManager::BuildMenu( pAddonPopupMenu, ADDON_MENU, MENU_APPEND, nUniqueMenuId, aAddonSubMenu, rFrame, rModel );
+
+ if ( pAddonPopupMenu->GetItemCount() > 0 )
+ {
+ pAddonPopupMenu->SetCommandURL( aURL );
+ pMergeMenuBar->InsertItem( nId, aTitle, 0, nInsertPos++ );
+ pMergeMenuBar->SetPopupMenu( nId, pAddonPopupMenu );
+
+ // Store the command URL into the VCL menu bar for later identification
+ pMergeMenuBar->SetItemCommand( nId, aURL );
+ }
+ else
+ delete pAddonPopupMenu;
+ }
+ }
+ }
+}
+
+// Insert the menu and sub menu entries into pCurrentMenu with the aAddonMenuDefinition provided
+void AddonMenuManager::BuildMenu( PopupMenu* pCurrentMenu,
+ MenuType nSubMenuType,
+ sal_uInt16 nInsPos,
+ sal_uInt16& nUniqueMenuId,
+ Sequence< Sequence< PropertyValue > > aAddonMenuDefinition,
+ const Reference< XFrame >& rFrame,
+ const Reference< XModel >& rModel )
+{
+ Sequence< Sequence< PropertyValue > > aAddonSubMenu;
+ sal_Bool bInsertSeparator = sal_False;
+ sal_uInt32 i = 0;
+ sal_uInt32 nElements = 0;
+ sal_uInt32 nCount = aAddonMenuDefinition.getLength();
+ AddonsOptions aAddonsOptions;
+
+ ::rtl::OUString aTitle;
+ ::rtl::OUString aURL;
+ ::rtl::OUString aTarget;
+ ::rtl::OUString aImageId;
+ ::rtl::OUString aContext;
+
+ for ( i = 0; i < nCount; ++i )
+ {
+ GetMenuEntry( aAddonMenuDefinition[i], aTitle, aURL, aTarget, aImageId, aContext, aAddonSubMenu );
+
+ if ( !IsCorrectContext( rModel, aContext ) || ( !aTitle.getLength() && !aURL.getLength() ))
+ continue;
+
+ if ( aURL == ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:separator" )))
+ bInsertSeparator = sal_True;
+ else
+ {
+ PopupMenu* pSubMenu = NULL;
+ if ( aAddonSubMenu.getLength() > 0 )
+ {
+ pSubMenu = AddonMenuManager::CreatePopupMenuType( nSubMenuType, rFrame );
+ AddonMenuManager::BuildMenu( pSubMenu, nSubMenuType, MENU_APPEND, nUniqueMenuId, aAddonSubMenu, rFrame, rModel );
+
+ // Don't create a menu item for an empty sub menu
+ if ( pSubMenu->GetItemCount() == 0 )
+ {
+ delete pSubMenu;
+ pSubMenu = NULL;
+ continue;
+ }
+ }
+
+ if ( bInsertSeparator && nElements > 0 )
+ {
+ // Insert a separator only when we insert a new element afterwards and we
+ // have already one before us
+ nElements = 0;
+ bInsertSeparator = sal_False;
+ pCurrentMenu->InsertSeparator( nInsPos );
+ nInsPos = AddonMenuManager::GetNextPos( nInsPos );
+ }
+
+ sal_uInt16 nId = nUniqueMenuId++;
+ pCurrentMenu->InsertItem( nId, aTitle, 0, nInsPos );
+ nInsPos = AddonMenuManager::GetNextPos( nInsPos );
+
+ ++nElements;
+
+ // Store values from configuration to the New and Wizard menu entries to enable
+ // sfx2 based code to support high contrast mode correctly!
+ pCurrentMenu->SetUserValue( nId, sal_uIntPtr( new MenuConfiguration::Attributes( aTarget, aImageId )) );
+ pCurrentMenu->SetItemCommand( nId, aURL );
+
+ if ( pSubMenu )
+ pCurrentMenu->SetPopupMenu( nId, pSubMenu );
+ }
+ }
+}
+
+// Retrieve the menu entry property values from a sequence
+void AddonMenuManager::GetMenuEntry( const Sequence< PropertyValue >& rAddonMenuEntry,
+ ::rtl::OUString& rTitle,
+ ::rtl::OUString& rURL,
+ ::rtl::OUString& rTarget,
+ ::rtl::OUString& rImageId,
+ ::rtl::OUString& rContext,
+ Sequence< Sequence< PropertyValue > >& rAddonSubMenu )
+{
+ // Reset submenu parameter
+ rAddonSubMenu = Sequence< Sequence< PropertyValue > >();
+
+ for ( int i = 0; i < rAddonMenuEntry.getLength(); i++ )
+ {
+ ::rtl::OUString aMenuEntryPropName = rAddonMenuEntry[i].Name;
+ if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_URL )
+ rAddonMenuEntry[i].Value >>= rURL;
+ else if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_TITLE )
+ rAddonMenuEntry[i].Value >>= rTitle;
+ else if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_TARGET )
+ rAddonMenuEntry[i].Value >>= rTarget;
+ else if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_IMAGEIDENTIFIER )
+ rAddonMenuEntry[i].Value >>= rImageId;
+ else if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_SUBMENU )
+ rAddonMenuEntry[i].Value >>= rAddonSubMenu;
+ else if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_CONTEXT )
+ rAddonMenuEntry[i].Value >>= rContext;
+ }
+}
+
+// Check if the context string matches the provided xModel context
+sal_Bool AddonMenuManager::IsCorrectContext( const Reference< XModel >& rModel, const ::rtl::OUString& aContext )
+{
+ if ( rModel.is() )
+ {
+ Reference< com::sun::star::lang::XServiceInfo > xServiceInfo( rModel, UNO_QUERY );
+ if ( xServiceInfo.is() )
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString aToken = aContext.getToken( 0, ',', nIndex );
+
+ if ( xServiceInfo->supportsService( aToken ))
+ return sal_True;
+ }
+ while ( nIndex >= 0 );
+ }
+ }
+
+ return ( aContext.getLength() == 0 );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/addonsoptions.cxx b/framework/source/fwe/classes/addonsoptions.cxx
new file mode 100644
index 000000000000..f52a48ac096a
--- /dev/null
+++ b/framework/source/fwe/classes/addonsoptions.cxx
@@ -0,0 +1,1823 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+#include <framework/addonsoptions.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/configitem.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <tools/color.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include <rtl/ustrbuf.hxx>
+#include <rtl/uri.hxx>
+#include <comphelper/processfactory.hxx>
+#include <vcl/graph.hxx>
+#include <svtools/filter.hxx>
+
+#include <boost/unordered_map.hpp>
+#include <algorithm>
+#include <vector>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using namespace ::std ;
+using namespace ::utl ;
+using namespace ::osl ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star::beans ;
+using namespace ::com::sun::star::lang ;
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+#define ROOTNODE_ADDONMENU ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Addons" ))
+#define PATHDELIMITER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/" ))
+#define TOOLBARITEMS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ToolBarItems" ))
+#define SEPARATOR_URL_STR "private:separator"
+#define SEPARATOR_URL_LEN 17
+#define SEPARATOR_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SEPARATOR_URL_STR ))
+
+#define PROPERTYNAME_URL ADDONSMENUITEM_PROPERTYNAME_URL
+#define PROPERTYNAME_TITLE ADDONSMENUITEM_PROPERTYNAME_TITLE
+#define PROPERTYNAME_TARGET ADDONSMENUITEM_PROPERTYNAME_TARGET
+#define PROPERTYNAME_IMAGEIDENTIFIER ADDONSMENUITEM_PROPERTYNAME_IMAGEIDENTIFIER
+#define PROPERTYNAME_CONTEXT ADDONSMENUITEM_PROPERTYNAME_CONTEXT
+#define PROPERTYNAME_SUBMENU ADDONSMENUITEM_PROPERTYNAME_SUBMENU
+#define PROPERTYNAME_CONTROLTYPE ADDONSMENUITEM_PROPERTYNAME_CONTROLTYPE
+#define PROPERTYNAME_WIDTH ADDONSMENUITEM_PROPERTYNAME_WIDTH
+
+#define PROPERTYNAME_IMAGESMALL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmall" ))
+#define PROPERTYNAME_IMAGEBIG ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBig" ))
+#define PROPERTYNAME_IMAGESMALLHC ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallHC" ))
+#define PROPERTYNAME_IMAGEBIGHC ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigHC" ))
+#define PROPERTYNAME_IMAGESMALL_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallURL" ))
+#define PROPERTYNAME_IMAGEBIG_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigURL" ))
+#define PROPERTYNAME_IMAGESMALLHC_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallHCURL" ))
+#define PROPERTYNAME_IMAGEBIGHC_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigHCURL" ))
+
+#define IMAGES_NODENAME ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UserDefinedImages" ))
+#define PRIVATE_IMAGE_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:image/" ))
+
+#define PROPERTYNAME_MERGEMENU_MERGEPOINT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergePoint" ))
+#define PROPERTYNAME_MERGEMENU_MERGECOMMAND ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommand" ))
+#define PROPERTYNAME_MERGEMENU_MERGECOMMANDPARAMETER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommandParameter" ))
+#define PROPERTYNAME_MERGEMENU_MERGEFALLBACK ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeFallback" ))
+#define PROPERTYNAME_MERGEMENU_MERGECONTEXT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeContext" ))
+#define PROPERTYNAME_MERGEMENU_MENUITEMS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MenuItems" ))
+#define MERGEMENU_MERGEPOINT_SEPARATOR '\\'
+
+#define PROPERTYNAME_MERGETOOLBAR_TOOLBAR ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeToolBar" ))
+#define PROPERTYNAME_MERGETOOLBAR_MERGEPOINT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergePoint" ))
+#define PROPERTYNAME_MERGETOOLBAR_MERGECOMMAND ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommand" ))
+#define PROPERTYNAME_MERGETOOLBAR_MERGECOMMANDPARAMETER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommandParameter" ))
+#define PROPERTYNAME_MERGETOOLBAR_MERGEFALLBACK ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeFallback" ))
+#define PROPERTYNAME_MERGETOOLBAR_MERGECONTEXT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeContext" ))
+#define PROPERTYNAME_MERGETOOLBAR_TOOLBARITEMS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ToolBarItems" ))
+
+// The following order is mandatory. Please add properties at the end!
+#define INDEX_URL 0
+#define INDEX_TITLE 1
+#define INDEX_IMAGEIDENTIFIER 2
+#define INDEX_TARGET 3
+#define INDEX_CONTEXT 4
+#define INDEX_SUBMENU 5
+#define INDEX_CONTROLTYPE 6
+#define INDEX_WIDTH 7
+#define PROPERTYCOUNT_INDEX 8
+
+// The following order is mandatory. Please add properties at the end!
+#define PROPERTYCOUNT_MENUITEM 6
+#define OFFSET_MENUITEM_URL 0
+#define OFFSET_MENUITEM_TITLE 1
+#define OFFSET_MENUITEM_IMAGEIDENTIFIER 2
+#define OFFSET_MENUITEM_TARGET 3
+#define OFFSET_MENUITEM_CONTEXT 4
+#define OFFSET_MENUITEM_SUBMENU 5
+
+// The following order is mandatory. Please add properties at the end!
+#define PROPERTYCOUNT_POPUPMENU 4
+#define OFFSET_POPUPMENU_TITLE 0
+#define OFFSET_POPUPMENU_CONTEXT 1
+#define OFFSET_POPUPMENU_SUBMENU 2
+#define OFFSET_POPUPMENU_URL 3 // Used for property set
+
+// The following order is mandatory. Please add properties at the end!
+#define PROPERTYCOUNT_TOOLBARITEM 7
+#define OFFSET_TOOLBARITEM_URL 0
+#define OFFSET_TOOLBARITEM_TITLE 1
+#define OFFSET_TOOLBARITEM_IMAGEIDENTIFIER 2
+#define OFFSET_TOOLBARITEM_TARGET 3
+#define OFFSET_TOOLBARITEM_CONTEXT 4
+#define OFFSET_TOOLBARITEM_CONTROLTYPE 5
+#define OFFSET_TOOLBARITEM_WIDTH 6
+
+// The following order is mandatory. Please add properties at the end!
+#define PROPERTYCOUNT_IMAGES 8
+#define PROPERTYCOUNT_EMBEDDED_IMAGES 4
+#define OFFSET_IMAGES_SMALL 0
+#define OFFSET_IMAGES_BIG 1
+#define OFFSET_IMAGES_SMALLHC 2
+#define OFFSET_IMAGES_BIGHC 3
+#define OFFSET_IMAGES_SMALL_URL 4
+#define OFFSET_IMAGES_BIG_URL 5
+#define OFFSET_IMAGES_SMALLHC_URL 6
+#define OFFSET_IMAGES_BIGHC_URL 7
+
+#define PROPERTYCOUNT_MERGE_MENUBAR 6
+#define OFFSET_MERGEMENU_MERGEPOINT 0
+#define OFFSET_MERGEMENU_MERGECOMMAND 1
+#define OFFSET_MERGEMENU_MERGECOMMANDPARAMETER 2
+#define OFFSET_MERGEMENU_MERGEFALLBACK 3
+#define OFFSET_MERGEMENU_MERGECONTEXT 4
+#define OFFSET_MERGEMENU_MENUITEMS 5
+
+#define PROPERTYCOUNT_MERGE_TOOLBAR 7
+#define OFFSET_MERGETOOLBAR_TOOLBAR 0
+#define OFFSET_MERGETOOLBAR_MERGEPOINT 1
+#define OFFSET_MERGETOOLBAR_MERGECOMMAND 2
+#define OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER 3
+#define OFFSET_MERGETOOLBAR_MERGEFALLBACK 4
+#define OFFSET_MERGETOOLBAR_MERGECONTEXT 5
+#define OFFSET_MERGETOOLBAR_TOOLBARITEMS 6
+
+#define EXPAND_PROTOCOL "vnd.sun.star.expand:"
+
+const Size aImageSizeSmall( 16, 16 );
+const Size aImageSizeBig( 26, 26 );
+
+//_________________________________________________________________________________________________________________
+// private declarations!
+//_________________________________________________________________________________________________________________
+
+/*-****************************************************************************************************************
+ @descr struct to hold information about one menu entry.
+****************************************************************************************************************-*/
+
+namespace framework
+{
+
+class AddonsOptions_Impl : public ConfigItem
+{
+ //-------------------------------------------------------------------------------------------------------------
+ // public methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ public:
+ //---------------------------------------------------------------------------------------------------------
+ // constructor / destructor
+ //---------------------------------------------------------------------------------------------------------
+
+ AddonsOptions_Impl();
+ ~AddonsOptions_Impl();
+
+ //---------------------------------------------------------------------------------------------------------
+ // overloaded methods of baseclass
+ //---------------------------------------------------------------------------------------------------------
+
+ /*-****************************************************************************************************//**
+ @short called for notify of configmanager
+ @descr These method is called from the ConfigManager before application ends or from the
+ PropertyChangeListener if the sub tree broadcasts changes. You must update your
+ internal values.
+
+ @seealso baseclass ConfigItem
+
+ @param "lPropertyNames" is the list of properties which should be updated.
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ virtual void Notify( const Sequence< ::rtl::OUString >& lPropertyNames );
+
+ /*-****************************************************************************************************//**
+ @short write changes to configuration
+ @descr These method writes the changed values into the sub tree
+ and should always called in our destructor to guarantee consistency of config data.
+
+ @seealso baseclass ConfigItem
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ virtual void Commit();
+
+ //---------------------------------------------------------------------------------------------------------
+ // public interface
+ //---------------------------------------------------------------------------------------------------------
+
+ /*-****************************************************************************************************//**
+ @short base implementation of public interface for "SvtDynamicMenuOptions"!
+ @descr These class is used as static member of "SvtDynamicMenuOptions" ...
+ => The code exist only for one time and isn't duplicated for every instance!
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ sal_Bool HasAddonsMenu () const ;
+ sal_Bool HasAddonsHelpMenu () const ;
+ sal_Int32 GetAddonsToolBarCount() const ;
+ const Sequence< Sequence< PropertyValue > >& GetAddonsMenu () const ;
+ const Sequence< Sequence< PropertyValue > >& GetAddonsMenuBarPart () const ;
+ const Sequence< Sequence< PropertyValue > >& GetAddonsToolBarPart ( sal_uInt32 nIndex ) const ;
+ const ::rtl::OUString GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const;
+ const Sequence< Sequence< PropertyValue > >& GetAddonsHelpMenu () const ;
+ Image GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bNoScale ) const;
+ const MergeMenuInstructionContainer& GetMergeMenuInstructions() const;
+ bool GetMergeToolbarInstructions( const ::rtl::OUString& rToolbarName, MergeToolbarInstructionContainer& rToolbarInstructions ) const;
+
+ void ReadConfigurationData();
+
+ //-------------------------------------------------------------------------------------------------------------
+ // private methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ private:
+ struct OUStringHashCode
+ {
+ size_t operator()( const ::rtl::OUString& sString ) const
+ {
+ return sString.hashCode();
+ }
+ };
+
+ struct ImageEntry
+ {
+ Image aImageSmall;
+ Image aImageBig;
+
+ Image aImageSmallNoScale;
+ Image aImageBigNoScale;
+ };
+
+ typedef boost::unordered_map< ::rtl::OUString, ImageEntry, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > ImageManager;
+ typedef boost::unordered_map< ::rtl::OUString, sal_uInt32, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > StringToIndexMap;
+ typedef std::vector< Sequence< Sequence< PropertyValue > > > AddonToolBars;
+ typedef ::boost::unordered_map< ::rtl::OUString, MergeToolbarInstructionContainer, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > ToolbarMergingInstructions;
+
+ enum ImageSize
+ {
+ IMGSIZE_SMALL,
+ IMGSIZE_BIG
+ };
+
+ /*-****************************************************************************************************//**
+ @short return list of key names of our configuration management which represent oue module tree
+ @descr These methods return the current list of key names! We need it to get needed values from our
+ configuration management!
+
+ @seealso -
+
+ @param "nCount" , returns count of menu entries for "new"
+ @return A list of configuration key names is returned.
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ sal_Bool ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& aAddonMenuSeq );
+ sal_Bool ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeMenuBarSeq );
+ sal_Bool ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< rtl::OUString >& rAddonOfficeToolBarResNames );
+ sal_Bool ReadToolBarItemSet( const rtl::OUString rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& aAddonOfficeToolBarSeq );
+ sal_Bool ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeHelpMenuSeq );
+ sal_Bool ReadImages( ImageManager& aImageManager );
+ sal_Bool ReadMenuMergeInstructions( MergeMenuInstructionContainer& rContainer );
+ sal_Bool ReadToolbarMergeInstructions( ToolbarMergingInstructions& rToolbarMergeMap );
+
+ sal_Bool ReadMergeMenuData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu );
+ sal_Bool ReadMergeToolbarData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems );
+ sal_Bool ReadMenuItem( const ::rtl::OUString& aMenuItemNodeName, Sequence< PropertyValue >& aMenuItem, sal_Bool bIgnoreSubMenu = sal_False );
+ sal_Bool ReadPopupMenu( const ::rtl::OUString& aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu );
+ sal_Bool AppendPopupMenu( Sequence< PropertyValue >& aTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu );
+ sal_Bool ReadToolBarItem( const ::rtl::OUString& aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem );
+ sal_Bool ReadImagesItem( const ::rtl::OUString& aImagesItemNodeName, Sequence< PropertyValue >& aImagesItem );
+ ImageEntry* ReadImageData( const ::rtl::OUString& aImagesNodeName );
+ void ReadAndAssociateImages( const ::rtl::OUString& aURL, const ::rtl::OUString& aImageId );
+ void ReadImageFromURL( ImageSize nImageSize, const ::rtl::OUString& aURL, Image& aImage, Image& aNoScaleImage );
+ sal_Bool HasAssociatedImages( const ::rtl::OUString& aURL );
+ void SubstituteVariables( ::rtl::OUString& aURL );
+
+ sal_Bool ReadSubMenuEntries( const Sequence< ::rtl::OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenu );
+ void InsertToolBarSeparator( Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq );
+ ::rtl::OUString GeneratePrefixURL();
+
+ Sequence< ::rtl::OUString > GetPropertyNamesMergeMenuInstruction( const ::rtl::OUString& aPropertyRootName ) const;
+ Sequence< ::rtl::OUString > GetPropertyNamesMenuItem( const ::rtl::OUString& aPropertyRootNode ) const;
+ Sequence< ::rtl::OUString > GetPropertyNamesPopupMenu( const ::rtl::OUString& aPropertyRootNode ) const;
+ Sequence< ::rtl::OUString > GetPropertyNamesToolBarItem( const ::rtl::OUString& aPropertyRootNode ) const;
+ Sequence< ::rtl::OUString > GetPropertyNamesImages( const ::rtl::OUString& aPropertyRootNode ) const;
+ sal_Bool CreateImageFromSequence( Image& rImage, sal_Bool bBig, Sequence< sal_Int8 >& rBitmapDataSeq ) const;
+
+ //-------------------------------------------------------------------------------------------------------------
+ // private member
+ //-------------------------------------------------------------------------------------------------------------
+
+ private:
+ ImageEntry* ReadOptionalImageData( const ::rtl::OUString& aMenuNodeName );
+
+ sal_Int32 m_nRootAddonPopupMenuId;
+ ::rtl::OUString m_aPropNames[PROPERTYCOUNT_INDEX];
+ ::rtl::OUString m_aPropImagesNames[PROPERTYCOUNT_IMAGES];
+ ::rtl::OUString m_aPropMergeMenuNames[PROPERTYCOUNT_MERGE_MENUBAR];
+ ::rtl::OUString m_aPropMergeToolbarNames[PROPERTYCOUNT_MERGE_TOOLBAR];
+ ::rtl::OUString m_aEmpty;
+ ::rtl::OUString m_aPathDelimiter;
+ ::rtl::OUString m_aSeparator;
+ ::rtl::OUString m_aRootAddonPopupMenuURLPrexfix;
+ ::rtl::OUString m_aPrivateImageURL;
+ Sequence< Sequence< PropertyValue > > m_aCachedMenuProperties;
+ Sequence< Sequence< PropertyValue > > m_aCachedMenuBarPartProperties;
+ AddonToolBars m_aCachedToolBarPartProperties;
+ std::vector< rtl::OUString > m_aCachedToolBarPartResourceNames;
+ Sequence< Sequence< PropertyValue > > m_aCachedHelpMenuProperties;
+ Reference< com::sun::star::util::XMacroExpander > m_xMacroExpander;
+ ImageManager m_aImageManager;
+ Sequence< Sequence< PropertyValue > > m_aEmptyAddonToolBar;
+ MergeMenuInstructionContainer m_aCachedMergeMenuInsContainer;
+ ToolbarMergingInstructions m_aCachedToolbarMergingInstructions;
+};
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+AddonsOptions_Impl::AddonsOptions_Impl()
+ // Init baseclasses first
+ : ConfigItem( ROOTNODE_ADDONMENU ),
+ m_nRootAddonPopupMenuId( 0 ),
+ m_aPathDelimiter( PATHDELIMITER ),
+ m_aSeparator( SEPARATOR_URL ),
+ m_aRootAddonPopupMenuURLPrexfix( ADDONSPOPUPMENU_URL_PREFIX ),
+ m_aPrivateImageURL( PRIVATE_IMAGE_URL )
+{
+ // initialize array with fixed property names
+ m_aPropNames[ INDEX_URL ] = PROPERTYNAME_URL;
+ m_aPropNames[ INDEX_TITLE ] = PROPERTYNAME_TITLE;
+ m_aPropNames[ INDEX_TARGET ] = PROPERTYNAME_TARGET;
+ m_aPropNames[ INDEX_IMAGEIDENTIFIER ] = PROPERTYNAME_IMAGEIDENTIFIER;
+ m_aPropNames[ INDEX_CONTEXT ] = PROPERTYNAME_CONTEXT;
+ m_aPropNames[ INDEX_SUBMENU ] = PROPERTYNAME_SUBMENU; // Submenu set!
+ m_aPropNames[ INDEX_CONTROLTYPE ] = PROPERTYNAME_CONTROLTYPE;
+ m_aPropNames[ INDEX_WIDTH ] = PROPERTYNAME_WIDTH;
+
+ // initialize array with fixed images property names
+ m_aPropImagesNames[ OFFSET_IMAGES_SMALL ] = PROPERTYNAME_IMAGESMALL;
+ m_aPropImagesNames[ OFFSET_IMAGES_BIG ] = PROPERTYNAME_IMAGEBIG;
+ m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ] = PROPERTYNAME_IMAGESMALLHC;
+ m_aPropImagesNames[ OFFSET_IMAGES_BIGHC ] = PROPERTYNAME_IMAGEBIGHC;
+ m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL ] = PROPERTYNAME_IMAGESMALL_URL;
+ m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ] = PROPERTYNAME_IMAGEBIG_URL;
+ m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL ] = PROPERTYNAME_IMAGESMALLHC_URL;
+ m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL ] = PROPERTYNAME_IMAGEBIGHC_URL;
+
+ // initialize array with fixed merge menu property names
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] = PROPERTYNAME_MERGEMENU_MERGEPOINT;
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] = PROPERTYNAME_MERGEMENU_MERGECOMMAND;
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGEMENU_MERGECOMMANDPARAMETER;
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] = PROPERTYNAME_MERGEMENU_MERGEFALLBACK;
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] = PROPERTYNAME_MERGEMENU_MERGECONTEXT;
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] = PROPERTYNAME_MERGEMENU_MENUITEMS;
+
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR ] = PROPERTYNAME_MERGETOOLBAR_TOOLBAR;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT ] = PROPERTYNAME_MERGETOOLBAR_MERGEPOINT;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND ] = PROPERTYNAME_MERGETOOLBAR_MERGECOMMAND;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGETOOLBAR_MERGECOMMANDPARAMETER;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK ] = PROPERTYNAME_MERGETOOLBAR_MERGEFALLBACK;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT ] = PROPERTYNAME_MERGETOOLBAR_MERGECONTEXT;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS ] = PROPERTYNAME_MERGETOOLBAR_TOOLBARITEMS;
+
+ Reference< XComponentContext > xContext;
+ Reference< com::sun::star::beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
+ xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
+ if ( xContext.is() )
+ {
+ m_xMacroExpander = Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))),
+ UNO_QUERY );
+ }
+
+ ReadConfigurationData();
+
+ // Enable notification mechanism of ouer baseclass.
+ // We need it to get information about changes outside these class on ouer used configuration keys!
+ Sequence< rtl::OUString > aNotifySeq( 1 );
+ aNotifySeq[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AddonUI" ));
+ EnableNotification( aNotifySeq );
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+AddonsOptions_Impl::~AddonsOptions_Impl()
+{
+ // We must save our current values .. if user forget it!
+ if( IsModified() == sal_True )
+ {
+ Commit();
+ }
+}
+
+void AddonsOptions_Impl::ReadConfigurationData()
+{
+ // reset members to be read again from configuration
+ m_aCachedMenuProperties = Sequence< Sequence< PropertyValue > >();
+ m_aCachedMenuBarPartProperties = Sequence< Sequence< PropertyValue > >();
+ m_aCachedToolBarPartProperties = AddonToolBars();
+ m_aCachedHelpMenuProperties = Sequence< Sequence< PropertyValue > >();
+ m_aCachedToolBarPartResourceNames.clear();
+ m_aImageManager = ImageManager();
+
+ ReadAddonMenuSet( m_aCachedMenuProperties );
+ ReadOfficeMenuBarSet( m_aCachedMenuBarPartProperties );
+ ReadOfficeToolBarSet( m_aCachedToolBarPartProperties, m_aCachedToolBarPartResourceNames );
+ ReadOfficeHelpSet( m_aCachedHelpMenuProperties );
+ ReadImages( m_aImageManager );
+
+ m_aCachedMergeMenuInsContainer.clear();
+ m_aCachedToolbarMergingInstructions.clear();
+
+ ReadMenuMergeInstructions( m_aCachedMergeMenuInsContainer );
+ ReadToolbarMergeInstructions( m_aCachedToolbarMergingInstructions );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::Notify( const Sequence< ::rtl::OUString >& /*lPropertyNames*/ )
+{
+ Application::PostUserEvent( STATIC_LINK( 0, AddonsOptions, Notify ) );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::Commit()
+{
+ OSL_FAIL( "AddonsOptions_Impl::Commit()\nNot implemented yet!\n" );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::HasAddonsMenu() const
+{
+ return ( m_aCachedMenuProperties.getLength() > 0 );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::HasAddonsHelpMenu () const
+{
+ return ( m_aCachedHelpMenuProperties.getLength() > 0 );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Int32 AddonsOptions_Impl::GetAddonsToolBarCount() const
+{
+ return m_aCachedToolBarPartProperties.size();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenu() const
+{
+ return m_aCachedMenuProperties;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenuBarPart() const
+{
+ return m_aCachedMenuBarPartProperties;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
+{
+ if ( /*nIndex >= 0 &&*/ nIndex < m_aCachedToolBarPartProperties.size() )
+ return m_aCachedToolBarPartProperties[nIndex];
+ else
+ return m_aEmptyAddonToolBar;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const ::rtl::OUString AddonsOptions_Impl::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
+{
+ if ( nIndex < m_aCachedToolBarPartResourceNames.size() )
+ return m_aCachedToolBarPartResourceNames[nIndex];
+ else
+ return rtl::OUString();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsHelpMenu () const
+{
+ return m_aCachedHelpMenuProperties;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const MergeMenuInstructionContainer& AddonsOptions_Impl::GetMergeMenuInstructions() const
+{
+ return m_aCachedMergeMenuInsContainer;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+bool AddonsOptions_Impl::GetMergeToolbarInstructions(
+ const ::rtl::OUString& rToolbarName,
+ MergeToolbarInstructionContainer& rToolbarInstructions ) const
+{
+ ToolbarMergingInstructions::const_iterator pIter = m_aCachedToolbarMergingInstructions.find( rToolbarName );
+ if ( pIter != m_aCachedToolbarMergingInstructions.end() )
+ {
+ rToolbarInstructions = pIter->second;
+ return true;
+ }
+ else
+ return false;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+Image AddonsOptions_Impl::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bNoScale ) const
+{
+ Image aImage;
+
+ ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
+ if ( pIter != m_aImageManager.end() )
+ {
+ if ( bNoScale )
+ aImage = ( bBig ? pIter->second.aImageBigNoScale : pIter->second.aImageSmallNoScale );
+ if ( !aImage )
+ aImage = ( bBig ? pIter->second.aImageBig : pIter->second.aImageSmall );
+ }
+
+ return aImage;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& rAddonMenuSeq )
+{
+ // Read the AddonMenu set and fill property sequences
+ ::rtl::OUString aAddonMenuNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/AddonMenu" ));
+ Sequence< ::rtl::OUString > aAddonMenuNodeSeq = GetNodeNames( aAddonMenuNodeName );
+ ::rtl::OUString aAddonMenuItemNode( aAddonMenuNodeName + m_aPathDelimiter );
+
+ sal_uInt32 nCount = aAddonMenuNodeSeq.getLength();
+ sal_uInt32 nIndex = 0;
+ Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
+
+ // Init the property value sequence
+ aMenuItem[ OFFSET_MENUITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
+ aMenuItem[ OFFSET_MENUITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU ]; // Submenu set!
+
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aRootMenuItemNode( aAddonMenuItemNode + aAddonMenuNodeSeq[n] );
+
+ // Read the MenuItem
+ if ( ReadMenuItem( aRootMenuItemNode, aMenuItem ) )
+ {
+ // Successfully read a menu item, append to our list
+ sal_uInt32 nMenuItemCount = rAddonMenuSeq.getLength() + 1;
+ rAddonMenuSeq.realloc( nMenuItemCount );
+ rAddonMenuSeq[nIndex++] = aMenuItem;
+ }
+ }
+
+ return ( rAddonMenuSeq.getLength() > 0 );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeHelpMenuSeq )
+{
+ // Read the AddonMenu set and fill property sequences
+ ::rtl::OUString aAddonHelpMenuNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeHelp" ));
+ Sequence< ::rtl::OUString > aAddonHelpMenuNodeSeq = GetNodeNames( aAddonHelpMenuNodeName );
+ ::rtl::OUString aAddonHelpMenuItemNode( aAddonHelpMenuNodeName + m_aPathDelimiter );
+
+ sal_uInt32 nCount = aAddonHelpMenuNodeSeq.getLength();
+ sal_uInt32 nIndex = 0;
+ Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
+
+ // Init the property value sequence
+ aMenuItem[ OFFSET_MENUITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
+ aMenuItem[ OFFSET_MENUITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU ]; // Submenu set!
+
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aRootMenuItemNode( aAddonHelpMenuItemNode + aAddonHelpMenuNodeSeq[n] );
+
+ // Read the MenuItem
+ if ( ReadMenuItem( aRootMenuItemNode, aMenuItem, sal_True ) )
+ {
+ // Successfully read a menu item, append to our list
+ sal_uInt32 nMenuItemCount = rAddonOfficeHelpMenuSeq.getLength() + 1;
+ rAddonOfficeHelpMenuSeq.realloc( nMenuItemCount );
+ rAddonOfficeHelpMenuSeq[nIndex++] = aMenuItem;
+ }
+ }
+
+ return ( rAddonOfficeHelpMenuSeq.getLength() > 0 );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeMenuBarSeq )
+{
+ // Read the OfficeMenuBar set and fill property sequences
+ ::rtl::OUString aAddonMenuBarNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeMenuBar" ));
+ Sequence< ::rtl::OUString > aAddonMenuBarNodeSeq = GetNodeNames( aAddonMenuBarNodeName );
+ ::rtl::OUString aAddonMenuBarNode( aAddonMenuBarNodeName + m_aPathDelimiter );
+
+ sal_uInt32 nCount = aAddonMenuBarNodeSeq.getLength();
+ sal_uInt32 nIndex = 0;
+ Sequence< PropertyValue > aPopupMenu( PROPERTYCOUNT_POPUPMENU );
+
+ // Init the property value sequence
+ aPopupMenu[ OFFSET_POPUPMENU_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
+ aPopupMenu[ OFFSET_POPUPMENU_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT];
+ aPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU];
+ aPopupMenu[ OFFSET_POPUPMENU_URL ].Name = m_aPropNames[ INDEX_URL ];
+
+ StringToIndexMap aTitleToIndexMap;
+
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aPopupMenuNode( aAddonMenuBarNode + aAddonMenuBarNodeSeq[n] );
+
+ // Read the MenuItem
+ if ( ReadPopupMenu( aPopupMenuNode, aPopupMenu ) )
+ {
+ // Successfully read a popup menu, append to our list
+ ::rtl::OUString aPopupTitle;
+ if ( aPopupMenu[OFFSET_POPUPMENU_TITLE].Value >>= aPopupTitle )
+ {
+ StringToIndexMap::const_iterator pIter = aTitleToIndexMap.find( aPopupTitle );
+ if ( pIter != aTitleToIndexMap.end() )
+ {
+ // title already there => concat both popup menus
+ Sequence< PropertyValue >& rOldPopupMenu = rAddonOfficeMenuBarSeq[pIter->second];
+ AppendPopupMenu( rOldPopupMenu, aPopupMenu );
+ }
+ else
+ {
+ // not found
+ sal_uInt32 nMenuItemCount = rAddonOfficeMenuBarSeq.getLength() + 1;
+ rAddonOfficeMenuBarSeq.realloc( nMenuItemCount );
+ rAddonOfficeMenuBarSeq[nIndex] = aPopupMenu;
+ aTitleToIndexMap.insert( StringToIndexMap::value_type( aPopupTitle, nIndex ));
+ ++nIndex;
+ }
+ }
+ }
+ }
+
+ return ( rAddonOfficeMenuBarSeq.getLength() > 0 );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< rtl::OUString >& rAddonOfficeToolBarResNames )
+{
+ // Read the OfficeToolBar set and fill property sequences
+ ::rtl::OUString aAddonToolBarNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeToolBar" ));
+ Sequence< ::rtl::OUString > aAddonToolBarNodeSeq = GetNodeNames( aAddonToolBarNodeName );
+ ::rtl::OUString aAddonToolBarNode( aAddonToolBarNodeName + m_aPathDelimiter );
+
+ sal_uInt32 nCount = aAddonToolBarNodeSeq.getLength();
+
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aToolBarItemNode( aAddonToolBarNode + aAddonToolBarNodeSeq[n] );
+ rAddonOfficeToolBarResNames.push_back( aAddonToolBarNodeSeq[n] );
+ rAddonOfficeToolBars.push_back( m_aEmptyAddonToolBar );
+ ReadToolBarItemSet( aToolBarItemNode, rAddonOfficeToolBars[n] );
+ }
+
+ return ( !rAddonOfficeToolBars.empty() );
+}
+
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadToolBarItemSet( const rtl::OUString rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
+{
+ sal_Bool bInsertSeparator = sal_False;
+ sal_uInt32 nToolBarItemCount = rAddonOfficeToolBarSeq.getLength();
+ ::rtl::OUString aAddonToolBarItemSetNode( rToolBarItemSetNodeName + m_aPathDelimiter );
+ Sequence< ::rtl::OUString > aAddonToolBarItemSetNodeSeq = GetNodeNames( rToolBarItemSetNodeName );
+ Sequence< PropertyValue > aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
+
+ // Init the property value sequence
+ aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
+ aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Name = m_aPropNames[ INDEX_CONTROLTYPE ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Name = m_aPropNames[ INDEX_WIDTH ];
+
+ sal_uInt32 nCount = aAddonToolBarItemSetNodeSeq.getLength();
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aToolBarItemNode( aAddonToolBarItemSetNode + aAddonToolBarItemSetNodeSeq[n] );
+
+ // Read the ToolBarItem
+ if ( ReadToolBarItem( aToolBarItemNode, aToolBarItem ) )
+ {
+ if ( bInsertSeparator )
+ {
+ bInsertSeparator = sal_False;
+ InsertToolBarSeparator( rAddonOfficeToolBarSeq );
+ }
+
+ // Successfully read a toolbar item, append to our list
+ sal_uInt32 nAddonCount = rAddonOfficeToolBarSeq.getLength();
+ rAddonOfficeToolBarSeq.realloc( nAddonCount+1 );
+ rAddonOfficeToolBarSeq[nAddonCount] = aToolBarItem;
+ }
+ }
+
+ return ( (sal_uInt32)rAddonOfficeToolBarSeq.getLength() > nToolBarItemCount );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::InsertToolBarSeparator( Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
+{
+ Sequence< PropertyValue > aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
+
+ aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
+ aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
+
+ aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= SEPARATOR_URL;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= m_aEmpty;
+
+ sal_uInt32 nToolBarItemCount = rAddonOfficeToolBarSeq.getLength();
+ rAddonOfficeToolBarSeq.realloc( nToolBarItemCount+1 );
+ rAddonOfficeToolBarSeq[nToolBarItemCount] = aToolBarItem;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadImages( ImageManager& aImageManager )
+{
+ // Read the user-defined Images set and fill image manager
+ ::rtl::OUString aAddonImagesNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/Images" ));
+ Sequence< ::rtl::OUString > aAddonImagesNodeSeq = GetNodeNames( aAddonImagesNodeName );
+ ::rtl::OUString aAddonImagesNode( aAddonImagesNodeName + m_aPathDelimiter );
+
+ sal_uInt32 nCount = aAddonImagesNodeSeq.getLength();
+
+ // Init the property value sequence
+ Sequence< ::rtl::OUString > aAddonImageItemNodePropNames( 1 );
+ ::rtl::OUString aURL;
+
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aImagesItemNode( aAddonImagesNode + aAddonImagesNodeSeq[n] );
+
+ // Create sequence for data access
+ ::rtl::OUStringBuffer aBuffer( aImagesItemNode );
+ aBuffer.append( m_aPathDelimiter );
+ aBuffer.append( m_aPropNames[ OFFSET_MENUITEM_URL ] );
+ aAddonImageItemNodePropNames[0] = aBuffer.makeStringAndClear();
+
+ Sequence< Any > aAddonImageItemNodeValues = GetProperties( aAddonImageItemNodePropNames );
+
+ // An user-defined image entry must have an URL. As "ImageIdentifier" has a higher priority
+ // we also check if we already have an images association.
+ if (( aAddonImageItemNodeValues[0] >>= aURL ) &&
+ aURL.getLength() > 0 &&
+ !HasAssociatedImages( aURL ))
+ {
+ ::rtl::OUStringBuffer aBuf( aImagesItemNode );
+ aBuf.append( m_aPathDelimiter );
+ aBuf.append( IMAGES_NODENAME );
+ aBuf.append( m_aPathDelimiter );
+ ::rtl::OUString aImagesUserDefinedItemNode = aBuf.makeStringAndClear();
+
+ // Read a user-defined images data
+ ImageEntry* pImageEntry = ReadImageData( aImagesUserDefinedItemNode );
+ if ( pImageEntry )
+ {
+ // Successfully read a user-defined images item, put it into our image manager
+ aImageManager.insert( ImageManager::value_type( aURL, *pImageEntry ));
+ delete pImageEntry; // We have the ownership of the pointer
+ }
+ }
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+
+::rtl::OUString AddonsOptions_Impl::GeneratePrefixURL()
+{
+ // Create an unique prefixed Add-On popup menu URL so it can be identified later as a runtime popup menu.
+ // They use a different image manager, so they must be identified by the sfx2/framework code.
+ ::rtl::OUString aPopupMenuURL;
+ ::rtl::OUStringBuffer aBuf( m_aRootAddonPopupMenuURLPrexfix.getLength() + 3 );
+ aBuf.append( m_aRootAddonPopupMenuURLPrexfix );
+ aBuf.append( ::rtl::OUString::valueOf( ++m_nRootAddonPopupMenuId ));
+ aPopupMenuURL = aBuf.makeStringAndClear();
+ return aPopupMenuURL;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+
+sal_Bool AddonsOptions_Impl::ReadMenuMergeInstructions( MergeMenuInstructionContainer& aContainer )
+{
+ const ::rtl::OUString aMenuMergeRootName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeMenuBarMerging/" ));
+
+ Sequence< ::rtl::OUString > aAddonMergeNodesSeq = GetNodeNames( aMenuMergeRootName );
+ ::rtl::OUString aAddonMergeNode( aMenuMergeRootName );
+
+ sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
+
+ // Init the property value sequence
+ Sequence< ::rtl::OUString > aNodePropNames( 5 );
+ ::rtl::OUString aURL;
+
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ ::rtl::OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
+
+ Sequence< ::rtl::OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
+ sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
+
+ for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
+ {
+ ::rtl::OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
+ aMergeAddonInstructionBase.append( m_aPathDelimiter );
+ aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
+ aMergeAddonInstructionBase.append( m_aPathDelimiter );
+
+ // Create sequence for data access
+ ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
+ aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] );
+ aNodePropNames[0] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] );
+ aNodePropNames[1] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] );
+ aNodePropNames[2] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] );
+ aNodePropNames[3] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] );
+ aNodePropNames[4] = aBuffer.makeStringAndClear();
+
+ Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
+
+ MergeMenuInstruction aMergeMenuInstruction;
+ aNodePropValues[0] >>= aMergeMenuInstruction.aMergePoint;
+ aNodePropValues[1] >>= aMergeMenuInstruction.aMergeCommand;
+ aNodePropValues[2] >>= aMergeMenuInstruction.aMergeCommandParameter;
+ aNodePropValues[3] >>= aMergeMenuInstruction.aMergeFallback;
+ aNodePropValues[4] >>= aMergeMenuInstruction.aMergeContext;
+
+ ::rtl::OUString aMergeMenuBase = aMergeAddonInstructionBase.makeStringAndClear();
+ ReadMergeMenuData( aMergeMenuBase, aMergeMenuInstruction.aMergeMenu );
+
+ aContainer.push_back( aMergeMenuInstruction );
+ }
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadMergeMenuData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu )
+{
+ ::rtl::OUString aMergeMenuBaseNode( aMergeAddonInstructionBase+m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] );
+
+ Sequence< ::rtl::OUString > aSubMenuNodeNames = GetNodeNames( aMergeMenuBaseNode );
+ aMergeMenuBaseNode += m_aPathDelimiter;
+
+ // extend the node names to have full path strings
+ for ( sal_uInt32 i = 0; i < (sal_uInt32)aSubMenuNodeNames.getLength(); i++ )
+ aSubMenuNodeNames[i] = ::rtl::OUString( aMergeMenuBaseNode + aSubMenuNodeNames[i] );
+
+ return ReadSubMenuEntries( aSubMenuNodeNames, rMergeMenu );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadToolbarMergeInstructions( ToolbarMergingInstructions& rCachedToolbarMergingInstructions )
+{
+ const ::rtl::OUString aToolbarMergeRootName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeToolbarMerging/" ));
+
+ Sequence< ::rtl::OUString > aAddonMergeNodesSeq = GetNodeNames( aToolbarMergeRootName );
+ ::rtl::OUString aAddonMergeNode( aToolbarMergeRootName );
+
+ sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
+
+ // Init the property value sequence
+ Sequence< ::rtl::OUString > aNodePropNames( 6 );
+ ::rtl::OUString aURL;
+
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ ::rtl::OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
+
+ Sequence< ::rtl::OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
+ sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
+
+ for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
+ {
+ ::rtl::OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
+ aMergeAddonInstructionBase.append( m_aPathDelimiter );
+ aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
+ aMergeAddonInstructionBase.append( m_aPathDelimiter );
+
+ // Create sequence for data access
+ ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR ] );
+ aNodePropNames[0] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT ] );
+ aNodePropNames[1] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND ] );
+ aNodePropNames[2] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] );
+ aNodePropNames[3] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK ] );
+ aNodePropNames[4] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT ] );
+ aNodePropNames[5] = aBuffer.makeStringAndClear();
+
+ Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
+
+ MergeToolbarInstruction aMergeToolbarInstruction;
+ aNodePropValues[0] >>= aMergeToolbarInstruction.aMergeToolbar;
+ aNodePropValues[1] >>= aMergeToolbarInstruction.aMergePoint;
+ aNodePropValues[2] >>= aMergeToolbarInstruction.aMergeCommand;
+ aNodePropValues[3] >>= aMergeToolbarInstruction.aMergeCommandParameter;
+ aNodePropValues[4] >>= aMergeToolbarInstruction.aMergeFallback;
+ aNodePropValues[5] >>= aMergeToolbarInstruction.aMergeContext;
+
+ ReadMergeToolbarData( aMergeAddonInstructionBase.makeStringAndClear(),
+ aMergeToolbarInstruction.aMergeToolbarItems );
+
+ MergeToolbarInstructionContainer& rVector = rCachedToolbarMergingInstructions[ aMergeToolbarInstruction.aMergeToolbar ];
+ rVector.push_back( aMergeToolbarInstruction );
+ }
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadMergeToolbarData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems )
+{
+ ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS ] );
+
+ ::rtl::OUString aMergeToolbarBaseNode = aBuffer.makeStringAndClear();
+
+ return ReadToolBarItemSet( aMergeToolbarBaseNode, rMergeToolbarItems );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadMenuItem( const ::rtl::OUString& aMenuNodeName, Sequence< PropertyValue >& aMenuItem, sal_Bool bIgnoreSubMenu )
+{
+ sal_Bool bResult = sal_False;
+ ::rtl::OUString aStrValue;
+ ::rtl::OUString aAddonMenuItemTreeNode( aMenuNodeName + m_aPathDelimiter );
+ Sequence< Any > aMenuItemNodePropValues;
+
+ aMenuItemNodePropValues = GetProperties( GetPropertyNamesMenuItem( aAddonMenuItemTreeNode ) );
+ if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_TITLE ] >>= aStrValue ) && aStrValue.getLength() > 0 )
+ {
+ aMenuItem[ OFFSET_MENUITEM_TITLE ].Value <<= aStrValue;
+
+ ::rtl::OUString aRootSubMenuName( aAddonMenuItemTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
+ Sequence< ::rtl::OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
+ if ( aRootSubMenuNodeNames.getLength() > 0 && !bIgnoreSubMenu )
+ {
+ // Set a unique prefixed Add-On popup menu URL so it can be identified later
+ ::rtl::OUString aPopupMenuURL = GeneratePrefixURL();
+ ::rtl::OUString aPopupMenuImageId;
+
+ aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aPopupMenuImageId;
+ ReadAndAssociateImages( aPopupMenuURL, aPopupMenuImageId );
+
+ // A popup menu must have a title and can have a URL and ImageIdentifier
+ // Set the other property values to empty
+ aMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aPopupMenuURL;
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= m_aEmpty;
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= aPopupMenuImageId;
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
+
+ // Continue to read the sub menu nodes
+ Sequence< Sequence< PropertyValue > > aSubMenuSeq;
+ ::rtl::OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
+ for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
+ aRootSubMenuNodeNames[n] = ::rtl::OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
+ ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= aSubMenuSeq;
+ bResult = sal_True;
+ }
+ else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) && aStrValue.getLength() > 0 )
+ {
+ // A simple menu item => read the other properties;
+ ::rtl::OUString aMenuImageId;
+
+ aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aMenuImageId;
+ ReadAndAssociateImages( aStrValue, aMenuImageId );
+
+ aMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aStrValue;
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_TARGET ];
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= aMenuImageId;
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
+
+ bResult = sal_True;
+ }
+ }
+ else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) &&
+ aStrValue.equalsAsciiL( SEPARATOR_URL_STR, SEPARATOR_URL_LEN ))
+ {
+ // Separator
+ aMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aStrValue;
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= m_aEmpty;
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= m_aEmpty;
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= m_aEmpty;
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
+ bResult = sal_True;
+ }
+
+ return bResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadPopupMenu( const ::rtl::OUString& aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu )
+{
+ sal_Bool bResult = sal_False;
+ ::rtl::OUString aStrValue;
+ ::rtl::OUString aAddonPopupMenuTreeNode( aPopupMenuNodeName + m_aPathDelimiter );
+ Sequence< Any > aPopupMenuNodePropValues;
+
+ aPopupMenuNodePropValues = GetProperties( GetPropertyNamesPopupMenu( aAddonPopupMenuTreeNode ) );
+ if (( aPopupMenuNodePropValues[ OFFSET_POPUPMENU_TITLE ] >>= aStrValue ) &&
+ aStrValue.getLength() > 0 )
+ {
+ aPopupMenu[ OFFSET_POPUPMENU_TITLE ].Value <<= aStrValue;
+
+ ::rtl::OUString aRootSubMenuName( aAddonPopupMenuTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
+ Sequence< ::rtl::OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
+ if ( aRootSubMenuNodeNames.getLength() > 0 )
+ {
+ // A top-level popup menu needs a title
+ // Set a unique prefixed Add-On popup menu URL so it can be identified later
+ ::rtl::OUString aPopupMenuURL = GeneratePrefixURL();
+
+ aPopupMenu[ OFFSET_POPUPMENU_URL ].Value <<= aPopupMenuURL;
+ aPopupMenu[ OFFSET_POPUPMENU_CONTEXT ].Value <<= aPopupMenuNodePropValues[ OFFSET_POPUPMENU_CONTEXT ];
+
+ // Continue to read the sub menu nodes
+ Sequence< Sequence< PropertyValue > > aSubMenuSeq;
+ ::rtl::OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
+ for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
+ aRootSubMenuNodeNames[n] = ::rtl::OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
+ ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
+ aPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aSubMenuSeq;
+ bResult = sal_True;
+ }
+ }
+
+ return bResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::AppendPopupMenu( Sequence< PropertyValue >& rTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu )
+{
+ Sequence< Sequence< PropertyValue > > aTargetSubMenuSeq;
+ Sequence< Sequence< PropertyValue > > aSourceSubMenuSeq;
+
+ if (( rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aTargetSubMenuSeq ) &&
+ ( rSourcePopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aSourceSubMenuSeq ))
+ {
+ sal_uInt32 nIndex = aTargetSubMenuSeq.getLength();
+ aTargetSubMenuSeq.realloc( nIndex + aSourceSubMenuSeq.getLength() );
+ for ( sal_uInt32 i = 0; i < sal_uInt32( aSourceSubMenuSeq.getLength() ); i++ )
+ aTargetSubMenuSeq[nIndex++] = aSourceSubMenuSeq[i];
+ rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aTargetSubMenuSeq;
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadToolBarItem( const ::rtl::OUString& aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem )
+{
+ sal_Bool bResult = sal_False;
+ ::rtl::OUString aTitle;
+ ::rtl::OUString aURL;
+ ::rtl::OUString aAddonToolBarItemTreeNode( aToolBarItemNodeName + m_aPathDelimiter );
+ Sequence< Any > aToolBarItemNodePropValues;
+
+ aToolBarItemNodePropValues = GetProperties( GetPropertyNamesToolBarItem( aAddonToolBarItemTreeNode ) );
+
+ // A toolbar item must have a command URL
+ if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_URL ] >>= aURL ) && aURL.getLength() > 0 )
+ {
+ if ( aURL.equals( SEPARATOR_URL ))
+ {
+ // A speparator toolbar item only needs a URL
+ aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= aURL;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Value <<= sal_Int32( 0 );
+
+ bResult = sal_True;
+ }
+ else if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TITLE ] >>= aTitle ) && aTitle.getLength() > 0 )
+ {
+ // A normal toolbar item must also have title => read the other properties;
+ ::rtl::OUString aImageId;
+
+ // Try to map a user-defined image URL to our internal private image URL
+ aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ] >>= aImageId;
+ ReadAndAssociateImages( aURL, aImageId );
+
+ aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= aURL;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= aTitle;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TARGET ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= aImageId;
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTEXT ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTROLTYPE ];
+
+ // Configuration uses hyper for long. Therefore transform into sal_Int32
+ sal_Int64 nValue( 0 );
+ aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_WIDTH ] >>= nValue;
+ aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
+
+ bResult = sal_True;
+ }
+ }
+
+ return bResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadSubMenuEntries( const Sequence< ::rtl::OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenuSeq )
+{
+ Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
+
+ // Init the property value sequence
+ aMenuItem[ OFFSET_MENUITEM_URL ].Name = PROPERTYNAME_URL;
+ aMenuItem[ OFFSET_MENUITEM_TITLE ].Name = PROPERTYNAME_TITLE;
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Name = PROPERTYNAME_TARGET;
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = PROPERTYNAME_IMAGEIDENTIFIER;
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = PROPERTYNAME_CONTEXT;
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = PROPERTYNAME_SUBMENU; // Submenu set!
+
+ sal_uInt32 nIndex = 0;
+ sal_uInt32 nCount = aSubMenuNodeNames.getLength();
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ if ( ReadMenuItem( aSubMenuNodeNames[n], aMenuItem ))
+ {
+ sal_uInt32 nSubMenuCount = rSubMenuSeq.getLength() + 1;
+ rSubMenuSeq.realloc( nSubMenuCount );
+ rSubMenuSeq[nIndex++] = aMenuItem;
+ }
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::HasAssociatedImages( const ::rtl::OUString& aURL )
+{
+ ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
+ return ( pIter != m_aImageManager.end() );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::SubstituteVariables( ::rtl::OUString& aURL )
+{
+ if (( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) &&
+ m_xMacroExpander.is() )
+ {
+ // cut protocol
+ ::rtl::OUString macro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
+ // decode uric class chars
+ macro = ::rtl::Uri::decode(
+ macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ // expand macro string
+ aURL = m_xMacroExpander->expandMacros( macro );
+ }
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::ReadImageFromURL( ImageSize nImageSize, const ::rtl::OUString& aImageURL, Image& aImage, Image& aImageNoScale )
+{
+ SvStream* pStream = UcbStreamHelper::CreateStream( aImageURL, STREAM_STD_READ );
+ if ( pStream && ( pStream->GetErrorCode() == 0 ))
+ {
+ // Use graphic class to also support more graphic formats (bmp,png,...)
+ Graphic aGraphic;
+
+ GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
+ pGF->ImportGraphic( aGraphic, String(), *pStream, GRFILTER_FORMAT_DONTKNOW );
+
+ BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
+
+ const Size aSize = ( nImageSize == IMGSIZE_SMALL ) ? aImageSizeSmall : aImageSizeBig; // Sizes used for menu/toolbox images
+
+ Size aBmpSize = aBitmapEx.GetSizePixel();
+ if ( aBmpSize.Width() > 0 && aBmpSize.Height() > 0 )
+ {
+ // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
+ if( !aBitmapEx.IsTransparent() )
+ aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
+
+ // A non-scaled bitmap can have a flexible width, but must have a defined height!
+ Size aNoScaleSize( aBmpSize.Width(), aSize.Height() );
+ if ( aBmpSize != aNoScaleSize )
+ {
+ BitmapEx aNoScaleBmp( aBitmapEx );
+ aNoScaleBmp.Scale( aNoScaleSize, BMP_SCALE_INTERPOLATE );
+ }
+ else
+ aImageNoScale = Image( aBitmapEx );
+
+ if ( aBmpSize != aSize )
+ aBitmapEx.Scale( aSize, BMP_SCALE_INTERPOLATE );
+
+ aImage = Image( aBitmapEx );
+ }
+ }
+
+ delete pStream;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::ReadAndAssociateImages( const ::rtl::OUString& aURL, const ::rtl::OUString& aImageId )
+{
+ const int MAX_NUM_IMAGES = 2;
+ const char* aExtArray[MAX_NUM_IMAGES] = { "_16", "_26" };
+ const char* pBmpExt = ".bmp";
+
+ if ( aImageId.getLength() == 0 )
+ return;
+
+ bool bImageFound = true;
+ ImageEntry aImageEntry;
+ ::rtl::OUString aImageURL( aImageId );
+
+ SubstituteVariables( aImageURL );
+
+ // Loop to create the four possible image names and try to read the bitmap files
+ for ( int i = 0; i < MAX_NUM_IMAGES; i++ )
+ {
+ ::rtl::OUStringBuffer aFileURL( aImageURL );
+ aFileURL.appendAscii( aExtArray[i] );
+ aFileURL.appendAscii( pBmpExt );
+
+ Image aImage;
+ Image aImageNoScale;
+ ReadImageFromURL( ((i==0)||(i==2)) ? IMGSIZE_SMALL : IMGSIZE_BIG, aFileURL.makeStringAndClear(), aImage, aImageNoScale );
+ if ( !!aImage )
+ {
+ bImageFound = true;
+ switch ( i )
+ {
+ case 0:
+ aImageEntry.aImageSmall = aImage;
+ aImageEntry.aImageSmallNoScale = aImageNoScale;
+ break;
+ case 1:
+ aImageEntry.aImageBig = aImage;
+ aImageEntry.aImageBigNoScale = aImageNoScale;
+ break;
+ }
+ }
+ }
+
+ if ( bImageFound )
+ m_aImageManager.insert( ImageManager::value_type( aURL, aImageEntry ));
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+AddonsOptions_Impl::ImageEntry* AddonsOptions_Impl::ReadImageData( const ::rtl::OUString& aImagesNodeName )
+{
+ Sequence< ::rtl::OUString > aImageDataNodeNames = GetPropertyNamesImages( aImagesNodeName );
+ Sequence< Any > aPropertyData;
+ Sequence< sal_Int8 > aImageDataSeq;
+ ::rtl::OUString aImageURL;
+
+ ImageEntry* pEntry = NULL;
+
+ // It is possible to use both forms (embedded image data and URLs to external bitmap files) at the
+ // same time. Embedded image data has a higher priority.
+ aPropertyData = GetProperties( aImageDataNodeNames );
+ for ( int i = 0; i < PROPERTYCOUNT_IMAGES; i++ )
+ {
+ if ( i < PROPERTYCOUNT_EMBEDDED_IMAGES )
+ {
+ // Extract image data from the embedded hex binary sequence
+ Image aImage;
+ if (( aPropertyData[i] >>= aImageDataSeq ) &&
+ aImageDataSeq.getLength() > 0 &&
+ ( CreateImageFromSequence( aImage,
+ ( i == OFFSET_IMAGES_BIG ),
+ aImageDataSeq )) )
+ {
+ if ( !pEntry )
+ pEntry = new ImageEntry;
+
+ if ( i == OFFSET_IMAGES_SMALL )
+ pEntry->aImageSmall = aImage;
+ else if ( i == OFFSET_IMAGES_BIG )
+ pEntry->aImageBig = aImage;
+ }
+ }
+ else
+ {
+ // Retrieve image data from a external bitmap file. Make sure that embedded image data
+ // has a higher priority.
+ aPropertyData[i] >>= aImageURL;
+
+ if ( aImageURL.getLength() > 0 )
+ {
+ Image aImage;
+ Image aImageNoScale;
+
+ SubstituteVariables( aImageURL );
+ ReadImageFromURL( ((i==OFFSET_IMAGES_SMALL_URL)||(i==OFFSET_IMAGES_SMALLHC_URL)) ? IMGSIZE_SMALL : IMGSIZE_BIG,
+ aImageURL, aImage, aImageNoScale );
+ if ( !!aImage )
+ {
+ if ( !pEntry )
+ pEntry = new ImageEntry;
+
+ if ( i == OFFSET_IMAGES_SMALL_URL && !pEntry->aImageSmall )
+ {
+ pEntry->aImageSmall = aImage;
+ pEntry->aImageSmallNoScale = aImageNoScale;
+ }
+ else if ( !pEntry->aImageBig )
+ {
+ pEntry->aImageBig = aImage;
+ pEntry->aImageBigNoScale = aImageNoScale;
+ }
+ }
+ }
+ }
+ }
+
+ return pEntry;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::CreateImageFromSequence( Image& rImage, sal_Bool bBig, Sequence< sal_Int8 >& rBitmapDataSeq ) const
+{
+ sal_Bool bResult = sal_False;
+ Size aSize = bBig ? aImageSizeBig : aImageSizeSmall; // Sizes used for menu/toolbox images
+
+ if ( rBitmapDataSeq.getLength() > 0 )
+ {
+ SvMemoryStream aMemStream( rBitmapDataSeq.getArray(), rBitmapDataSeq.getLength(), STREAM_STD_READ );
+ BitmapEx aBitmapEx;
+
+ aMemStream >> aBitmapEx;
+
+ // Scale bitmap to fit the correct size for the menu/toolbar. Use best quality
+ if ( aBitmapEx.GetSizePixel() != aSize )
+ aBitmapEx.Scale( aSize, BMP_SCALE_INTERPOLATE );
+
+ if( !aBitmapEx.IsTransparent() )
+ {
+ // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
+ aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
+ }
+
+ rImage = Image( aBitmapEx );
+ bResult = sal_True;
+ }
+
+ return bResult;
+}
+
+//*****************************************************************************************************************
+// private methods
+//*****************************************************************************************************************
+Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesMergeMenuInstruction( const ::rtl::OUString& aPropertyRootNode ) const
+{
+ Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_MERGE_MENUBAR );
+
+ // Create property names dependent from the root node name
+ lResult[ OFFSET_MERGEMENU_MERGEPOINT ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] );
+ lResult[ OFFSET_MERGEMENU_MERGECOMMAND ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] );
+ lResult[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] );
+ lResult[ OFFSET_MERGEMENU_MERGEFALLBACK ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] );
+ lResult[ OFFSET_MERGEMENU_MERGECONTEXT ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] );
+ lResult[ OFFSET_MERGEMENU_MENUITEMS ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] );
+
+ return lResult;
+}
+
+Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesMenuItem( const ::rtl::OUString& aPropertyRootNode ) const
+{
+ Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_MENUITEM );
+
+ // Create property names dependent from the root node name
+ lResult[OFFSET_MENUITEM_URL] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL ] );
+ lResult[OFFSET_MENUITEM_TITLE] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
+ lResult[OFFSET_MENUITEM_IMAGEIDENTIFIER] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER ] );
+ lResult[OFFSET_MENUITEM_TARGET] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TARGET ] );
+ lResult[OFFSET_MENUITEM_CONTEXT] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
+ lResult[OFFSET_MENUITEM_SUBMENU] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU ] );
+
+ return lResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesPopupMenu( const ::rtl::OUString& aPropertyRootNode ) const
+{
+ // The URL is automatically set and not read from the configuration.
+ Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_POPUPMENU-1 );
+
+ // Create property names dependent from the root node name
+ lResult[OFFSET_POPUPMENU_TITLE] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
+ lResult[OFFSET_POPUPMENU_CONTEXT] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
+ lResult[OFFSET_POPUPMENU_SUBMENU] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU ] );
+
+ return lResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesToolBarItem( const ::rtl::OUString& aPropertyRootNode ) const
+{
+ Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_TOOLBARITEM );
+
+ // Create property names dependent from the root node name
+ lResult[0] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL ] );
+ lResult[1] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
+ lResult[2] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER] );
+ lResult[3] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TARGET ] );
+ lResult[4] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
+ lResult[5] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTROLTYPE ] );
+ lResult[6] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_WIDTH ] );
+
+ return lResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesImages( const ::rtl::OUString& aPropertyRootNode ) const
+{
+ Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_IMAGES );
+
+ // Create property names dependent from the root node name
+ lResult[0] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL ] );
+ lResult[1] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG ] );
+ lResult[2] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ] );
+ lResult[3] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC ] );
+ lResult[4] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL ] );
+ lResult[5] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ] );
+ lResult[6] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL] );
+ lResult[7] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL ] );
+
+ return lResult;
+}
+
+//*****************************************************************************************************************
+// initialize static member
+// DON'T DO IT IN YOUR HEADER!
+// see definition for further informations
+//*****************************************************************************************************************
+AddonsOptions_Impl* AddonsOptions::m_pDataContainer = NULL ;
+sal_Int32 AddonsOptions::m_nRefCount = 0 ;
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+AddonsOptions::AddonsOptions()
+{
+ // Global access, must be guarded (multithreading!).
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Increase ouer refcount ...
+ ++m_nRefCount;
+ // ... and initialize ouer data container only if it not already exist!
+ if( m_pDataContainer == NULL )
+ {
+ m_pDataContainer = new AddonsOptions_Impl;
+ }
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+AddonsOptions::~AddonsOptions()
+{
+ // Global access, must be guarded (multithreading!)
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Decrease ouer refcount.
+ --m_nRefCount;
+ // If last instance was deleted ...
+ // we must destroy ouer static data container!
+ if( m_nRefCount <= 0 )
+ {
+ delete m_pDataContainer;
+ m_pDataContainer = NULL;
+ }
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions::HasAddonsMenu() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->HasAddonsMenu();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+
+sal_Bool AddonsOptions::HasAddonsHelpMenu() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->HasAddonsHelpMenu();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+
+sal_Int32 AddonsOptions::GetAddonsToolBarCount() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsToolBarCount();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenu() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsMenu();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenuBarPart() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsMenuBarPart();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsToolBarPart( nIndex );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const ::rtl::OUString AddonsOptions::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsToolbarResourceName( nIndex );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsHelpMenu() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsHelpMenu();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const MergeMenuInstructionContainer& AddonsOptions::GetMergeMenuInstructions() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMergeMenuInstructions();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+bool AddonsOptions::GetMergeToolbarInstructions(
+ const ::rtl::OUString& rToolbarName,
+ MergeToolbarInstructionContainer& rToolbarInstructions ) const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMergeToolbarInstructions(
+ rToolbarName, rToolbarInstructions );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+Image AddonsOptions::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bNoScale ) const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetImageFromURL( aURL, bBig, bNoScale );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+Image AddonsOptions::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig ) const
+{
+ return GetImageFromURL( aURL, bBig, sal_False );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Mutex& AddonsOptions::GetOwnStaticMutex()
+{
+ // Initialize static mutex only for one time!
+ static Mutex* pMutex = NULL;
+ // If these method first called (Mutex not already exist!) ...
+ if( pMutex == NULL )
+ {
+ // ... we must create a new one. Protect follow code with the global mutex -
+ // It must be - we create a static variable!
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
+ if( pMutex == NULL )
+ {
+ // Create the new mutex and set it for return on static variable.
+ static Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+ // Return new created or already existing mutex object.
+ return *pMutex;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+IMPL_STATIC_LINK_NOINSTANCE( AddonsOptions, Notify, void*, EMPTYARG )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->ReadConfigurationData();
+ return 0;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/bmkmenu.cxx b/framework/source/fwe/classes/bmkmenu.cxx
new file mode 100644
index 000000000000..66108f645a90
--- /dev/null
+++ b/framework/source/fwe/classes/bmkmenu.cxx
@@ -0,0 +1,250 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <limits.h>
+
+#include "framework/bmkmenu.hxx"
+#include <general.h>
+#include <macros/debug/assertion.hxx>
+#include <framework/imageproducer.hxx>
+#include <framework/menuconfiguration.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <tools/config.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/dynamicmenuoptions.hxx>
+#include <svtools/menuoptions.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::comphelper;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+
+namespace framework
+{
+
+void GetMenuEntry(
+ Sequence< PropertyValue >& aDynamicMenuEntry,
+ ::rtl::OUString& rTitle,
+ ::rtl::OUString& rURL,
+ ::rtl::OUString& rFrame,
+ ::rtl::OUString& rImageId );
+
+class BmkMenu_Impl
+{
+ private:
+ static sal_uInt16 m_nMID;
+
+ public:
+ BmkMenu* m_pRoot;
+ sal_Bool m_bInitialized;
+
+ BmkMenu_Impl( BmkMenu* pRoot );
+ BmkMenu_Impl();
+ ~BmkMenu_Impl();
+
+ static sal_uInt16 GetMID();
+};
+
+sal_uInt16 BmkMenu_Impl::m_nMID = BMKMENU_ITEMID_START;
+
+BmkMenu_Impl::BmkMenu_Impl( BmkMenu* pRoot ) :
+ m_pRoot(pRoot),
+ m_bInitialized(sal_False)
+{
+}
+
+BmkMenu_Impl::BmkMenu_Impl() :
+ m_pRoot(0),
+ m_bInitialized(sal_False)
+{
+}
+
+BmkMenu_Impl::~BmkMenu_Impl()
+{
+}
+
+sal_uInt16 BmkMenu_Impl::GetMID()
+{
+ m_nMID++;
+ if( !m_nMID )
+ m_nMID = BMKMENU_ITEMID_START;
+ return m_nMID;
+}
+
+// ------------------------------------------------------------------------
+
+BmkMenu::BmkMenu( com::sun::star::uno::Reference< XFrame >& xFrame, BmkMenu::BmkMenuType nType, BmkMenu* pRoot )
+ :AddonMenu(xFrame)
+ ,m_nType( nType )
+{
+ _pImp = new BmkMenu_Impl( pRoot );
+ Initialize();
+}
+
+BmkMenu::BmkMenu( Reference< XFrame >& xFrame, BmkMenu::BmkMenuType nType )
+ :AddonMenu(xFrame)
+ ,m_nType( nType )
+{
+ _pImp = new BmkMenu_Impl();
+ Initialize();
+}
+
+BmkMenu::~BmkMenu()
+{
+ delete _pImp;
+}
+
+void BmkMenu::Initialize()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::BmkMenu::Initialize" );
+
+ if( _pImp->m_bInitialized )
+ return;
+
+ _pImp->m_bInitialized = sal_True;
+
+ Sequence< Sequence< PropertyValue > > aDynamicMenuEntries;
+
+ if ( m_nType == BmkMenu::BMK_NEWMENU )
+ aDynamicMenuEntries = SvtDynamicMenuOptions().GetMenu( E_NEWMENU );
+ else if ( m_nType == BmkMenu::BMK_WIZARDMENU )
+ aDynamicMenuEntries = SvtDynamicMenuOptions().GetMenu( E_WIZARDMENU );
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus();
+
+ ::rtl::OUString aTitle;
+ ::rtl::OUString aURL;
+ ::rtl::OUString aTargetFrame;
+ ::rtl::OUString aImageId;
+
+ sal_uInt32 i, nCount = aDynamicMenuEntries.getLength();
+ for ( i = 0; i < nCount; ++i )
+ {
+ GetMenuEntry( aDynamicMenuEntries[i], aTitle, aURL, aTargetFrame, aImageId );
+
+ if ( !aTitle.getLength() && !aURL.getLength() )
+ continue;
+
+ if ( aURL == ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:separator" )))
+ InsertSeparator();
+ else
+ {
+ sal_Bool bImageSet = sal_False;
+ sal_uInt16 nId = CreateMenuId();
+
+ if ( bShowMenuImages )
+ {
+ if ( aImageId.getLength() > 0 )
+ {
+ Image aImage = GetImageFromURL( m_xFrame, aImageId, false );
+ if ( !!aImage )
+ {
+ bImageSet = sal_True;
+ InsertItem( nId, aTitle, aImage );
+ }
+ }
+
+ if ( !bImageSet )
+ {
+ Image aImage = GetImageFromURL( m_xFrame, aURL, false );
+ if ( !aImage )
+ InsertItem( nId, aTitle );
+ else
+ InsertItem( nId, aTitle, aImage );
+ }
+ }
+ else
+ InsertItem( nId, aTitle );
+
+ MenuConfiguration::Attributes* pUserAttributes = new MenuConfiguration::Attributes( aTargetFrame, aImageId );
+ SetUserValue( nId, (sal_uIntPtr)pUserAttributes );
+
+ SetItemCommand( nId, aURL );
+ }
+ }
+}
+
+sal_uInt16 BmkMenu::CreateMenuId()
+{
+ return BmkMenu_Impl::GetMID();
+}
+
+void GetMenuEntry
+(
+ Sequence< PropertyValue >& aDynamicMenuEntry,
+ ::rtl::OUString& rTitle,
+ ::rtl::OUString& rURL,
+ ::rtl::OUString& rFrame,
+ ::rtl::OUString& rImageId
+)
+{
+ for ( int i = 0; i < aDynamicMenuEntry.getLength(); i++ )
+ {
+ if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_URL )
+ aDynamicMenuEntry[i].Value >>= rURL;
+ else if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_TITLE )
+ aDynamicMenuEntry[i].Value >>= rTitle;
+ else if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER )
+ aDynamicMenuEntry[i].Value >>= rImageId;
+ else if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_TARGETNAME )
+ aDynamicMenuEntry[i].Value >>= rFrame;
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/framelistanalyzer.cxx b/framework/source/fwe/classes/framelistanalyzer.cxx
new file mode 100644
index 000000000000..fadd3cae0545
--- /dev/null
+++ b/framework/source/fwe/classes/framelistanalyzer.cxx
@@ -0,0 +1,305 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "framework/framelistanalyzer.hxx"
+
+//_______________________________________________
+// my own includes
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <targets.h>
+#include <properties.h>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+
+//_______________________________________________
+// includes of other projects
+#include <unotools/processfactory.hxx>
+#include <vcl/svapp.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//_______________________________________________
+// non exported const
+
+//_______________________________________________
+// non exported definitions
+
+//_______________________________________________
+// declarations
+
+//_______________________________________________
+
+/**
+ */
+
+FrameListAnalyzer::FrameListAnalyzer( const css::uno::Reference< css::frame::XFramesSupplier >& xSupplier ,
+ const css::uno::Reference< css::frame::XFrame >& xReferenceFrame ,
+ sal_uInt32 eDetectMode )
+ : m_xSupplier (xSupplier )
+ , m_xReferenceFrame(xReferenceFrame)
+ , m_eDetectMode (eDetectMode )
+{
+ impl_analyze();
+}
+
+//_______________________________________________
+
+/**
+ */
+
+FrameListAnalyzer::~FrameListAnalyzer()
+{
+}
+
+//_______________________________________________
+
+/** returns an analyzed list of all currently opened (top!) frames inside the desktop tree.
+
+ We try to get a snapshot of all opened frames, which are part of the desktop frame container.
+ Of course we can't access frames, which stands outside of this tree.
+ But it's neccessary to collect top frames here only. Otherwhise we interpret closing of last
+ frame wrong. Further we analyze this list and split into different parts.
+ E.g. for "CloseDoc" we must know, which frames of the given list referr to the same model.
+ These frames must be closed then. But all other frames must be untouched.
+ In case the request was "CloseWin" these splitted lists can be used too, to decide if the last window
+ or document was closed. Then we have to initialize the backing window ...
+ Last but not least we must know something about our special help frame. It must be handled
+ seperatly. And last but not least - the backing component frame must be detected too.
+*/
+
+void FrameListAnalyzer::impl_analyze()
+{
+ // reset all members to get a consistent state
+ m_bReferenceIsHidden = sal_False;
+ m_bReferenceIsHelp = sal_False;
+ m_bReferenceIsBacking = sal_False;
+ m_xHelp = css::uno::Reference< css::frame::XFrame >();
+ m_xBackingComponent = css::uno::Reference< css::frame::XFrame >();
+
+ // try to get the task container by using the given supplier
+ css::uno::Reference< css::container::XIndexAccess > xFrameContainer(m_xSupplier->getFrames(), css::uno::UNO_QUERY);
+
+ // All return list get an initial size to include all possible frames.
+ // They will be packed at the end of this method ... using the actual step positions then.
+ sal_Int32 nVisibleStep = 0;
+ sal_Int32 nHiddenStep = 0;
+ sal_Int32 nModelStep = 0;
+ sal_Int32 nCount = xFrameContainer->getCount();
+
+ m_lOtherVisibleFrames.realloc(nCount);
+ m_lOtherHiddenFrames.realloc(nCount);
+ m_lModelFrames.realloc(nCount);
+
+ // ask for the model of the given reference frame.
+ // It must be compared with the model of every frame of the container
+ // to sort it into the list of frames with the same model.
+ // Supress this step, if right detect mode isn't set.
+ css::uno::Reference< css::frame::XModel > xReferenceModel;
+ if ((m_eDetectMode & E_MODEL) == E_MODEL )
+ {
+ css::uno::Reference< css::frame::XController > xReferenceController;
+ if (m_xReferenceFrame.is())
+ xReferenceController = m_xReferenceFrame->getController();
+ if (xReferenceController.is())
+ xReferenceModel = xReferenceController->getModel();
+ }
+
+ // check, if the reference frame is in hidden mode.
+ // But look, if this analyze step is realy needed.
+ css::uno::Reference< css::beans::XPropertySet > xSet(m_xReferenceFrame, css::uno::UNO_QUERY);
+ if (
+ ((m_eDetectMode & E_HIDDEN) == E_HIDDEN) &&
+ (xSet.is() )
+ )
+ {
+ xSet->getPropertyValue(FRAME_PROPNAME_ISHIDDEN) >>= m_bReferenceIsHidden;
+ }
+
+ // check, if the reference frame includes the backing component.
+ // But look, if this analyze step is realy needed.
+ if ((m_eDetectMode & E_BACKINGCOMPONENT) == E_BACKINGCOMPONENT)
+ {
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory();
+ css::uno::Reference< css::frame::XModuleManager > xModuleMgr(xSMGR->createInstance(SERVICENAME_MODULEMANAGER), css::uno::UNO_QUERY_THROW);
+ ::rtl::OUString sModule = xModuleMgr->identify(m_xReferenceFrame);
+ m_bReferenceIsBacking = (sModule.equals(SERVICENAME_STARTMODULE));
+ }
+ catch(const css::uno::Exception&)
+ {}
+ }
+
+ // check, if the reference frame includes the help module.
+ // But look, if this analyze step is realy needed.
+ if (
+ ((m_eDetectMode & E_HELP) == E_HELP ) &&
+ (m_xReferenceFrame.is() ) &&
+ (m_xReferenceFrame->getName() == SPECIALTARGET_HELPTASK)
+ )
+ {
+ m_bReferenceIsHelp = sal_True;
+ }
+
+ try
+ {
+ // Step over all frames of the desktop frame container and analyze it.
+ for (sal_Int32 i=0; i<nCount; ++i)
+ {
+ // Ignore invalid items ... and of course the reference frame.
+ // It will be a member of the given frame list too - but it was already
+ // analyzed before!
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ if (
+ !(xFrameContainer->getByIndex(i) >>= xFrame) ||
+ !(xFrame.is() ) ||
+ (xFrame==m_xReferenceFrame )
+ )
+ continue;
+
+ #ifdef ENABLE_WARNINGS
+ if (
+ ((m_eDetectMode & E_ZOMBIE) == E_ZOMBIE) &&
+ (
+ (!xFrame->getContainerWindow().is()) ||
+ (!xFrame->getComponentWindow().is())
+ )
+ )
+ {
+ LOG_WARNING("FrameListAnalyzer::impl_analyze()", "ZOMBIE!")
+ }
+ #endif
+
+ // -------------------------------------------------
+ // a) Is it the special help task?
+ // Return it seperated from any return list.
+ if (
+ ((m_eDetectMode & E_HELP) == E_HELP ) &&
+ (xFrame->getName()==SPECIALTARGET_HELPTASK)
+ )
+ {
+ m_xHelp = xFrame;
+ continue;
+ }
+
+ // -------------------------------------------------
+ // b) Or is includes this task the special backing component?
+ // Return it seperated from any return list.
+ // But check if the reference task itself is the backing frame.
+ // Our user mst know it to decide right.
+ if ((m_eDetectMode & E_BACKINGCOMPONENT) == E_BACKINGCOMPONENT)
+ {
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory();
+ css::uno::Reference< css::frame::XModuleManager > xModuleMgr(xSMGR->createInstance(SERVICENAME_MODULEMANAGER), css::uno::UNO_QUERY);
+ ::rtl::OUString sModule = xModuleMgr->identify(xFrame);
+ if (sModule.equals(SERVICENAME_STARTMODULE))
+ {
+ m_xBackingComponent = xFrame;
+ continue;
+ }
+ }
+ catch(const css::uno::Exception&)
+ {}
+ }
+
+ // -------------------------------------------------
+ // c) Or is it the a task, which uses the specified model?
+ // Add it to the list of "model frames".
+ if ((m_eDetectMode & E_MODEL) == E_MODEL)
+ {
+ css::uno::Reference< css::frame::XController > xController = xFrame->getController();
+ css::uno::Reference< css::frame::XModel > xModel ;
+ if (xController.is())
+ xModel = xController->getModel();
+ if (xModel==xReferenceModel)
+ {
+ m_lModelFrames[nModelStep] = xFrame;
+ ++nModelStep;
+ continue;
+ }
+ }
+
+ // -------------------------------------------------
+ // d) Or is it the a task, which use another or no model at all?
+ // Add it to the list of "other frames". But look for it's
+ // visible state ... if it's allowed to do so.
+ // -------------------------------------------------
+ sal_Bool bHidden = sal_False;
+ if ((m_eDetectMode & E_HIDDEN) == E_HIDDEN )
+ {
+ xSet = css::uno::Reference< css::beans::XPropertySet >(xFrame, css::uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ xSet->getPropertyValue(FRAME_PROPNAME_ISHIDDEN) >>= bHidden;
+ }
+ }
+
+ if (bHidden)
+ {
+ m_lOtherHiddenFrames[nHiddenStep] = xFrame;
+ ++nHiddenStep;
+ }
+ else
+ {
+ m_lOtherVisibleFrames[nVisibleStep] = xFrame;
+ ++nVisibleStep;
+ }
+ }
+ }
+ catch(css::lang::IndexOutOfBoundsException)
+ {
+ // stop copying if index seams to be wrong.
+ // This interface can't realy guarantee its count for multithreaded
+ // environments. So it can occure!
+ }
+
+ // Pack both lists by using the actual step positions.
+ // All empty or ignorable items should exist at the end of these lists
+ // behind the position pointers. So they will be removed by a reallocation.
+ m_lOtherVisibleFrames.realloc(nVisibleStep);
+ m_lOtherHiddenFrames.realloc(nHiddenStep);
+ m_lModelFrames.realloc(nModelStep);
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/fwkresid.cxx b/framework/source/fwe/classes/fwkresid.cxx
new file mode 100644
index 000000000000..ff8a7e3d8431
--- /dev/null
+++ b/framework/source/fwe/classes/fwkresid.cxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "classes/fwkresid.hxx"
+#include <tools/string.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+#include <rtl/strbuf.hxx>
+
+namespace framework
+{
+
+ResMgr* FwkResId::GetResManager()
+{
+ static ResMgr* pResMgr = NULL;
+
+ if ( !pResMgr )
+ {
+ SolarMutexGuard aSolarGuard;
+ pResMgr = ResMgr::CreateResMgr("fwe");
+ }
+
+ return pResMgr;
+}
+
+// -----------------------------------------------------------------------
+
+FwkResId::FwkResId( sal_uInt16 nId ) :
+ ResId( nId, *FwkResId::GetResManager() )
+{
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/imagewrapper.cxx b/framework/source/fwe/classes/imagewrapper.cxx
new file mode 100644
index 000000000000..405930a5e32b
--- /dev/null
+++ b/framework/source/fwe/classes/imagewrapper.cxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <classes/imagewrapper.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/bitmapex.hxx>
+#include <tools/stream.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+
+namespace framework
+{
+
+static Sequence< sal_Int8 > impl_getStaticIdentifier()
+{
+ static sal_uInt8 pGUID[16] = { 0x46, 0xAD, 0x69, 0xFB, 0xA7, 0xBE, 0x44, 0x83, 0xB2, 0xA7, 0xB3, 0xEC, 0x59, 0x4A, 0xB7, 0x00 };
+ static ::com::sun::star::uno::Sequence< sal_Int8 > seqID((sal_Int8*)pGUID,16) ;
+ return seqID ;
+}
+
+
+ImageWrapper::ImageWrapper( const Image& aImage ) : ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_aImage( aImage )
+{
+}
+
+
+ImageWrapper::~ImageWrapper()
+{
+}
+
+
+Sequence< sal_Int8 > ImageWrapper::GetUnoTunnelId()
+{
+ return impl_getStaticIdentifier();
+}
+
+// XBitmap
+com::sun::star::awt::Size SAL_CALL ImageWrapper::getSize() throw ( RuntimeException )
+{
+ SolarMutexGuard aGuard;
+
+ BitmapEx aBitmapEx( m_aImage.GetBitmapEx() );
+ Size aBitmapSize( aBitmapEx.GetSizePixel() );
+
+ return com::sun::star::awt::Size( aBitmapSize.Width(), aBitmapSize.Height() );
+}
+
+Sequence< sal_Int8 > SAL_CALL ImageWrapper::getDIB() throw ( RuntimeException )
+{
+ SolarMutexGuard aGuard;
+
+ SvMemoryStream aMem;
+ aMem << m_aImage.GetBitmapEx().GetBitmap();
+ return Sequence< sal_Int8 >( (sal_Int8*) aMem.GetData(), aMem.Tell() );
+}
+
+Sequence< sal_Int8 > SAL_CALL ImageWrapper::getMaskDIB() throw ( RuntimeException )
+{
+ SolarMutexGuard aGuard;
+ BitmapEx aBmpEx( m_aImage.GetBitmapEx() );
+
+ if ( aBmpEx.IsAlpha() )
+ {
+ SvMemoryStream aMem;
+ aMem << aBmpEx.GetAlpha().GetBitmap();
+ return Sequence< sal_Int8 >( (sal_Int8*) aMem.GetData(), aMem.Tell() );
+ }
+ else if ( aBmpEx.IsTransparent() )
+ {
+ SvMemoryStream aMem;
+ aMem << aBmpEx.GetMask();
+ return Sequence< sal_Int8 >( (sal_Int8*) aMem.GetData(), aMem.Tell() );
+ }
+
+ return Sequence< sal_Int8 >();
+}
+
+// XUnoTunnel
+sal_Int64 SAL_CALL ImageWrapper::getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw ( RuntimeException )
+{
+ if ( aIdentifier == impl_getStaticIdentifier() )
+ return reinterpret_cast< sal_Int64 >( this );
+ else
+ return 0;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/menuextensionsupplier.cxx b/framework/source/fwe/classes/menuextensionsupplier.cxx
new file mode 100644
index 000000000000..20256a756c0d
--- /dev/null
+++ b/framework/source/fwe/classes/menuextensionsupplier.cxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <framework/menuextensionsupplier.hxx>
+#include <osl/mutex.hxx>
+
+static pfunc_setMenuExtensionSupplier pMenuExtensionSupplierFunc = NULL;
+
+namespace framework
+{
+
+pfunc_setMenuExtensionSupplier SAL_CALL SetMenuExtensionSupplier( pfunc_setMenuExtensionSupplier pMenuExtensionSupplierFuncArg )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+
+ pfunc_setMenuExtensionSupplier pOldMenuExtensionSupplierFunc = pMenuExtensionSupplierFunc;
+ pMenuExtensionSupplierFunc = pMenuExtensionSupplierFuncArg;
+ return pOldMenuExtensionSupplierFunc;
+}
+
+MenuExtensionItem SAL_CALL GetMenuExtension()
+{
+ MenuExtensionItem aItem;
+
+ pfunc_setMenuExtensionSupplier pLocalMenuExtensionSupplierFunc( 0 );
+
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pLocalMenuExtensionSupplierFunc = pMenuExtensionSupplierFunc;
+ }
+
+ if ( pLocalMenuExtensionSupplierFunc )
+ return (*pLocalMenuExtensionSupplierFunc)();
+ else
+ return aItem;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/rootactiontriggercontainer.cxx b/framework/source/fwe/classes/rootactiontriggercontainer.cxx
new file mode 100644
index 000000000000..45598b6b47c1
--- /dev/null
+++ b/framework/source/fwe/classes/rootactiontriggercontainer.cxx
@@ -0,0 +1,381 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <classes/rootactiontriggercontainer.hxx>
+#include <classes/actiontriggercontainer.hxx>
+#include <classes/actiontriggerpropertyset.hxx>
+#include <classes/actiontriggerseparatorpropertyset.hxx>
+#include <framework/actiontriggerhelper.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+
+
+namespace framework
+{
+
+static Sequence< sal_Int8 > impl_getStaticIdentifier()
+{
+ static sal_uInt8 pGUID[16] = { 0x17, 0x0F, 0xA2, 0xC9, 0xCA, 0x50, 0x4A, 0xD3, 0xA6, 0x3B, 0x39, 0x99, 0xC5, 0x96, 0x43, 0x27 };
+ static ::com::sun::star::uno::Sequence< sal_Int8 > seqID((sal_Int8*)pGUID,16) ;
+ return seqID ;
+}
+
+
+RootActionTriggerContainer::RootActionTriggerContainer( const Menu* pMenu, const ::rtl::OUString* pMenuIdentifier, const Reference< XMultiServiceFactory >& rServiceManager ) :
+ PropertySetContainer( rServiceManager )
+ , m_bContainerCreated( sal_False )
+ , m_bContainerChanged( sal_False )
+ , m_bInContainerCreation( sal_False )
+ , m_pMenu( pMenu )
+ , m_pMenuIdentifier( pMenuIdentifier )
+{
+}
+
+RootActionTriggerContainer::~RootActionTriggerContainer()
+{
+}
+
+Sequence< sal_Int8 > RootActionTriggerContainer::GetUnoTunnelId() const
+{
+ return impl_getStaticIdentifier();
+}
+
+const Menu* RootActionTriggerContainer::GetMenu()
+{
+ if ( !m_bContainerChanged )
+ return m_pMenu;
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ Menu* pNewMenu = new PopupMenu;
+
+ ActionTriggerHelper::CreateMenuFromActionTriggerContainer( pNewMenu, this );
+ m_pMenu = pNewMenu;
+ m_bContainerChanged = sal_False;
+
+ return m_pMenu;
+ }
+}
+
+
+// XInterface
+Any SAL_CALL RootActionTriggerContainer::queryInterface( const Type& aType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ aType ,
+ SAL_STATIC_CAST( XMultiServiceFactory* , this ),
+ SAL_STATIC_CAST( XServiceInfo* , this ),
+ SAL_STATIC_CAST( XUnoTunnel* , this ),
+ SAL_STATIC_CAST( XTypeProvider* , this ),
+ SAL_STATIC_CAST( XNamed* , this ));
+
+ if( a.hasValue() )
+ {
+ return a;
+ }
+
+ return PropertySetContainer::queryInterface( aType );
+}
+
+void SAL_CALL RootActionTriggerContainer::acquire() throw ()
+{
+ PropertySetContainer::acquire();
+}
+
+void SAL_CALL RootActionTriggerContainer::release() throw ()
+{
+ PropertySetContainer::release();
+}
+
+// XMultiServiceFactory
+Reference< XInterface > SAL_CALL RootActionTriggerContainer::createInstance( const ::rtl::OUString& aServiceSpecifier )
+throw ( Exception, RuntimeException )
+{
+ if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGER ))
+ return (OWeakObject *)( new ActionTriggerPropertySet( m_xServiceManager ));
+ else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER ))
+ return (OWeakObject *)( new ActionTriggerContainer( m_xServiceManager ));
+ else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERSEPARATOR ))
+ return (OWeakObject *)( new ActionTriggerSeparatorPropertySet( m_xServiceManager ));
+ else
+ throw com::sun::star::uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown service specifier!" )), (OWeakObject *)this );
+}
+
+Reference< XInterface > SAL_CALL RootActionTriggerContainer::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/ )
+throw ( Exception, RuntimeException )
+{
+ return createInstance( ServiceSpecifier );
+}
+
+Sequence< ::rtl::OUString > SAL_CALL RootActionTriggerContainer::getAvailableServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > aSeq( 3 );
+
+ aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGER ));
+ aSeq[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER ));
+ aSeq[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERSEPARATOR ));
+
+ return aSeq;
+}
+
+
+// XIndexContainer
+void SAL_CALL RootActionTriggerContainer::insertByIndex( sal_Int32 Index, const Any& Element )
+throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bContainerCreated )
+ FillContainer();
+
+ if ( !m_bInContainerCreation )
+ m_bContainerChanged = sal_True;
+ PropertySetContainer::insertByIndex( Index, Element );
+}
+
+void SAL_CALL RootActionTriggerContainer::removeByIndex( sal_Int32 Index )
+throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bContainerCreated )
+ FillContainer();
+
+ if ( !m_bInContainerCreation )
+ m_bContainerChanged = sal_True;
+ PropertySetContainer::removeByIndex( Index );
+}
+
+
+// XIndexReplace
+void SAL_CALL RootActionTriggerContainer::replaceByIndex( sal_Int32 Index, const Any& Element )
+throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bContainerCreated )
+ FillContainer();
+
+ if ( !m_bInContainerCreation )
+ m_bContainerChanged = sal_True;
+ PropertySetContainer::replaceByIndex( Index, Element );
+}
+
+
+// XIndexAccess
+sal_Int32 SAL_CALL RootActionTriggerContainer::getCount()
+throw ( RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bContainerCreated )
+ {
+ if ( m_pMenu )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ return m_pMenu->GetItemCount();
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ return PropertySetContainer::getCount();
+ }
+}
+
+Any SAL_CALL RootActionTriggerContainer::getByIndex( sal_Int32 Index )
+throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bContainerCreated )
+ FillContainer();
+
+ return PropertySetContainer::getByIndex( Index );
+}
+
+
+// XElementAccess
+Type SAL_CALL RootActionTriggerContainer::getElementType()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return ::getCppuType(( Reference< XPropertySet >*)0);
+}
+
+sal_Bool SAL_CALL RootActionTriggerContainer::hasElements()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( m_pMenu )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ return ( m_pMenu->GetItemCount() > 0 );
+ }
+
+ return sal_False;
+}
+
+
+// XServiceInfo
+::rtl::OUString SAL_CALL RootActionTriggerContainer::getImplementationName()
+throw ( RuntimeException )
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATIONNAME_ROOTACTIONTRIGGERCONTAINER ));
+}
+
+sal_Bool SAL_CALL RootActionTriggerContainer::supportsService( const ::rtl::OUString& ServiceName )
+throw ( RuntimeException )
+{
+ if ( ServiceName.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER ))
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL RootActionTriggerContainer::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > seqServiceNames( 1 );
+
+ seqServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER ));
+ return seqServiceNames;
+}
+
+// XUnoTunnel
+sal_Int64 SAL_CALL RootActionTriggerContainer::getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw ( RuntimeException )
+{
+ if ( aIdentifier == impl_getStaticIdentifier() )
+ return reinterpret_cast< sal_Int64 >( this );
+ else
+ return 0;
+}
+
+// XTypeProvider
+Sequence< Type > SAL_CALL RootActionTriggerContainer::getTypes() throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ if ( pTypeCollection == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pTypeCollection == NULL )
+ {
+ // Create a static typecollection ...
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType(( const Reference< XMultiServiceFactory >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexContainer >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexAccess >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexReplace >*)NULL ) ,
+ ::getCppuType(( const Reference< XServiceInfo >*)NULL ) ,
+ ::getCppuType(( const Reference< XTypeProvider >*)NULL ) ,
+ ::getCppuType(( const Reference< XUnoTunnel >*)NULL ) ,
+ ::getCppuType(( const Reference< XNamed >*)NULL )) ;
+
+ // ... and set his address to static pointer!
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+Sequence< sal_Int8 > SAL_CALL RootActionTriggerContainer::getImplementationId() throw ( RuntimeException )
+{
+ // Create one Id for all instances of this class.
+ // Use ethernet address to do this! (sal_True)
+
+ // Optimize this method
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pID is NULL - for the second call pID is different from NULL!
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pID == NULL )
+ {
+ // Create a new static ID ...
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ // ... and set his address to static pointer!
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+}
+
+// private implementation helper
+void RootActionTriggerContainer::FillContainer()
+{
+ m_bContainerCreated = sal_True;
+ m_bInContainerCreation = sal_True;
+ Reference<XIndexContainer> xXIndexContainer( (OWeakObject *)this, UNO_QUERY );
+ ActionTriggerHelper::FillActionTriggerContainerFromMenu(
+ xXIndexContainer,
+ m_pMenu );
+ m_bInContainerCreation = sal_False;
+}
+::rtl::OUString RootActionTriggerContainer::getName() throw ( RuntimeException )
+{
+ ::rtl::OUString sRet;
+ if( m_pMenuIdentifier )
+ sRet = *m_pMenuIdentifier;
+ return sRet;
+}
+
+void RootActionTriggerContainer::setName( const ::rtl::OUString& ) throw ( RuntimeException)
+{
+ throw RuntimeException();
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/classes/sfxhelperfunctions.cxx b/framework/source/fwe/classes/sfxhelperfunctions.cxx
new file mode 100644
index 000000000000..cce8982e1278
--- /dev/null
+++ b/framework/source/fwe/classes/sfxhelperfunctions.cxx
@@ -0,0 +1,182 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <framework/sfxhelperfunctions.hxx>
+
+#include <tools/diagnose_ex.h>
+
+static pfunc_setToolBoxControllerCreator pToolBoxControllerCreator = NULL;
+static pfunc_setStatusBarControllerCreator pStatusBarControllerCreator = NULL;
+static pfunc_getRefreshToolbars pRefreshToolbars = NULL;
+static pfunc_createDockingWindow pCreateDockingWindow = NULL;
+static pfunc_isDockingWindowVisible pIsDockingWindowVisible = NULL;
+static pfunc_activateToolPanel pActivateToolPanel = NULL;
+
+
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::frame;
+
+namespace framework
+{
+
+pfunc_setToolBoxControllerCreator SAL_CALL SetToolBoxControllerCreator( pfunc_setToolBoxControllerCreator pSetToolBoxControllerCreator )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_setToolBoxControllerCreator pOldSetToolBoxControllerCreator = pToolBoxControllerCreator;
+ pToolBoxControllerCreator = pSetToolBoxControllerCreator;
+ return pOldSetToolBoxControllerCreator;
+}
+
+svt::ToolboxController* SAL_CALL CreateToolBoxController( const Reference< XFrame >& rFrame, ToolBox* pToolbox, unsigned short nID, const ::rtl::OUString& aCommandURL )
+{
+ pfunc_setToolBoxControllerCreator pFactory = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pFactory = pToolBoxControllerCreator;
+ }
+
+ if ( pFactory )
+ return (*pFactory)( rFrame, pToolbox, nID, aCommandURL );
+ else
+ return NULL;
+}
+
+pfunc_setStatusBarControllerCreator SAL_CALL SetStatusBarControllerCreator( pfunc_setStatusBarControllerCreator pSetStatusBarControllerCreator )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_setStatusBarControllerCreator pOldSetStatusBarControllerCreator = pSetStatusBarControllerCreator;
+ pStatusBarControllerCreator = pSetStatusBarControllerCreator;
+ return pOldSetStatusBarControllerCreator;
+}
+
+svt::StatusbarController* SAL_CALL CreateStatusBarController( const Reference< XFrame >& rFrame, StatusBar* pStatusBar, unsigned short nID, const ::rtl::OUString& aCommandURL )
+{
+ pfunc_setStatusBarControllerCreator pFactory = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pFactory = pStatusBarControllerCreator;
+ }
+
+ if ( pFactory )
+ return (*pFactory)( rFrame, pStatusBar, nID, aCommandURL );
+ else
+ return NULL;
+}
+
+pfunc_getRefreshToolbars SAL_CALL SetRefreshToolbars( pfunc_getRefreshToolbars pNewRefreshToolbarsFunc )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_getRefreshToolbars pOldFunc = pRefreshToolbars;
+ pRefreshToolbars = pNewRefreshToolbarsFunc;
+
+ return pOldFunc;
+}
+
+void SAL_CALL RefreshToolbars( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame )
+{
+ pfunc_getRefreshToolbars pCallback = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pCallback = pRefreshToolbars;
+ }
+
+ if ( pCallback )
+ (*pCallback)( rFrame );
+}
+
+pfunc_createDockingWindow SAL_CALL SetDockingWindowCreator( pfunc_createDockingWindow pNewCreateDockingWindow )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_createDockingWindow pOldFunc = pCreateDockingWindow;
+ pCreateDockingWindow = pNewCreateDockingWindow;
+
+ return pOldFunc;
+}
+
+void SAL_CALL CreateDockingWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const ::rtl::OUString& rResourceURL )
+{
+ pfunc_createDockingWindow pFactory = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pFactory = pCreateDockingWindow;
+ }
+
+ if ( pFactory )
+ (*pFactory)( rFrame, rResourceURL );
+}
+
+pfunc_isDockingWindowVisible SAL_CALL SetIsDockingWindowVisible( pfunc_isDockingWindowVisible pNewIsDockingWindowVisible)
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_isDockingWindowVisible pOldFunc = pIsDockingWindowVisible;
+ pIsDockingWindowVisible = pNewIsDockingWindowVisible;
+
+ return pOldFunc;
+}
+
+bool SAL_CALL IsDockingWindowVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const ::rtl::OUString& rResourceURL )
+{
+ pfunc_isDockingWindowVisible pCall = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pCall = pIsDockingWindowVisible;
+ }
+
+ if ( pCall )
+ return (*pCall)( rFrame, rResourceURL );
+ else
+ return false;
+}
+
+pfunc_activateToolPanel SAL_CALL SetActivateToolPanel( pfunc_activateToolPanel i_pActivator )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_activateToolPanel pOldFunc = pActivateToolPanel;
+ pActivateToolPanel = i_pActivator;
+ return pOldFunc;
+}
+
+void SAL_CALL ActivateToolPanel( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& i_rFrame, const ::rtl::OUString& i_rPanelURL )
+{
+ pfunc_activateToolPanel pActivator = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pActivator = pActivateToolPanel;
+ }
+
+ ENSURE_OR_RETURN_VOID( pActivator, "framework::ActivateToolPanel: no activator function!" );
+ (*pActivator)( i_rFrame, i_rPanelURL );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/dispatch/interaction.cxx b/framework/source/fwe/dispatch/interaction.cxx
new file mode 100644
index 000000000000..9b3d4f4c69d8
--- /dev/null
+++ b/framework/source/fwe/dispatch/interaction.cxx
@@ -0,0 +1,366 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <comphelper/interaction.hxx>
+#include <framework/interaction.hxx>
+#include <general.h>
+
+using namespace ::com::sun::star;
+
+namespace framework{
+
+/*-************************************************************************************************************//**
+ @short declaration of special continuation for filter selection
+ @descr Sometimes filter detection during loading document failed. Then we need a possibility
+ to ask user for his decision. These continuation transport selected filter by user to
+ code user of interaction.
+
+ @attention This implementation could be used one times only. We don't support a resetable continuation yet!
+ Why? Normaly interaction should show a filter selection dialog and ask user for his decision.
+ He can select any filter - then instances of these class will be called by handler ... or user
+ close dialog without any selection. Then another continuation should be slected by handler to
+ abort continuations ... Retrying isn't very usefull here ... I think.
+
+ @implements XInteractionFilterSelect
+
+ @base ImplInheritanceHelper1
+ ContinuationBase
+
+ @devstatus ready to use
+ @threadsafe no (used on once position only!)
+*//*-*************************************************************************************************************/
+class ContinuationFilterSelect : public comphelper::OInteraction< ::com::sun::star::document::XInteractionFilterSelect >
+{
+ // c++ interface
+ public:
+ ContinuationFilterSelect();
+
+ // uno interface
+ public:
+ virtual void SAL_CALL setFilter( const ::rtl::OUString& sFilter ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::rtl::OUString SAL_CALL getFilter( ) throw( ::com::sun::star::uno::RuntimeException );
+
+ // member
+ private:
+ ::rtl::OUString m_sFilter;
+
+}; // class ContinuationFilterSelect
+
+
+//---------------------------------------------------------------------------------------------------------
+// initialize continuation with right start values
+//---------------------------------------------------------------------------------------------------------
+ContinuationFilterSelect::ContinuationFilterSelect()
+ : m_sFilter( ::rtl::OUString() )
+{
+}
+
+//---------------------------------------------------------------------------------------------------------
+// handler should use it after selection to set user specified filter for transport
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL ContinuationFilterSelect::setFilter( const ::rtl::OUString& sFilter ) throw( css::uno::RuntimeException )
+{
+ m_sFilter = sFilter;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// read access to transported filter
+//---------------------------------------------------------------------------------------------------------
+::rtl::OUString SAL_CALL ContinuationFilterSelect::getFilter() throw( css::uno::RuntimeException )
+{
+ return m_sFilter;
+}
+
+class RequestFilterSelect_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionRequest >
+{
+public:
+ RequestFilterSelect_Impl( const ::rtl::OUString& sURL );
+ sal_Bool isAbort () const;
+ ::rtl::OUString getFilter() const;
+
+public:
+ virtual ::com::sun::star::uno::Any SAL_CALL getRequest() throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > SAL_CALL getContinuations() throw( ::com::sun::star::uno::RuntimeException );
+
+private:
+ ::com::sun::star::uno::Any m_aRequest ;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > m_lContinuations;
+ comphelper::OInteractionAbort* m_pAbort;
+ ContinuationFilterSelect* m_pFilter;
+};
+
+//---------------------------------------------------------------------------------------------------------
+// initialize instance with all neccessary informations
+// We use it without any further checks on our member then ...!
+//---------------------------------------------------------------------------------------------------------
+RequestFilterSelect_Impl::RequestFilterSelect_Impl( const ::rtl::OUString& sURL )
+{
+ ::rtl::OUString temp;
+ css::uno::Reference< css::uno::XInterface > temp2;
+ css::document::NoSuchFilterRequest aFilterRequest( temp ,
+ temp2 ,
+ sURL );
+ m_aRequest <<= aFilterRequest;
+
+ m_pAbort = new comphelper::OInteractionAbort;
+ m_pFilter = new ContinuationFilterSelect;
+
+ m_lContinuations.realloc( 2 );
+ m_lContinuations[0] = css::uno::Reference< css::task::XInteractionContinuation >( m_pAbort );
+ m_lContinuations[1] = css::uno::Reference< css::task::XInteractionContinuation >( m_pFilter );
+}
+
+//---------------------------------------------------------------------------------------------------------
+// return abort state of interaction
+// If it is true, return value of method "getFilter()" will be unspecified then!
+//---------------------------------------------------------------------------------------------------------
+sal_Bool RequestFilterSelect_Impl::isAbort() const
+{
+ return m_pAbort->wasSelected();
+}
+
+//---------------------------------------------------------------------------------------------------------
+// return user selected filter
+// Return value valid for non aborted interaction only. Please check "isAbort()" before you call these ony!
+//---------------------------------------------------------------------------------------------------------
+::rtl::OUString RequestFilterSelect_Impl::getFilter() const
+{
+ return m_pFilter->getFilter();
+}
+
+//---------------------------------------------------------------------------------------------------------
+// handler call it to get type of request
+// Is hard coded to "please select filter" here. see ctor for further informations.
+//---------------------------------------------------------------------------------------------------------
+css::uno::Any SAL_CALL RequestFilterSelect_Impl::getRequest() throw( css::uno::RuntimeException )
+{
+ return m_aRequest;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// handler call it to get possible continuations
+// We support "abort/select_filter" only here.
+// After interaction we support read access on these continuations on our c++ interface to
+// return user decision.
+//---------------------------------------------------------------------------------------------------------
+css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > SAL_CALL RequestFilterSelect_Impl::getContinuations() throw( css::uno::RuntimeException )
+{
+ return m_lContinuations;
+}
+
+
+RequestFilterSelect::RequestFilterSelect( const ::rtl::OUString& sURL )
+{
+ pImp = new RequestFilterSelect_Impl( sURL );
+ pImp->acquire();
+}
+
+RequestFilterSelect::~RequestFilterSelect()
+{
+ pImp->release();
+}
+
+
+//---------------------------------------------------------------------------------------------------------
+// return abort state of interaction
+// If it is true, return value of method "getFilter()" will be unspecified then!
+//---------------------------------------------------------------------------------------------------------
+sal_Bool RequestFilterSelect::isAbort() const
+{
+ return pImp->isAbort();
+}
+
+//---------------------------------------------------------------------------------------------------------
+// return user selected filter
+// Return value valid for non aborted interaction only. Please check "isAbort()" before you call these ony!
+//---------------------------------------------------------------------------------------------------------
+::rtl::OUString RequestFilterSelect::getFilter() const
+{
+ return pImp->getFilter();
+}
+
+uno::Reference < task::XInteractionRequest > RequestFilterSelect::GetRequest()
+{
+ return uno::Reference < task::XInteractionRequest > (pImp);
+}
+
+/*
+class RequestAmbigousFilter_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionRequest >
+{
+public:
+ RequestAmbigousFilter_Impl( const ::rtl::OUString& sURL ,
+ const ::rtl::OUString& sSelectedFilter ,
+ const ::rtl::OUString& sDetectedFilter );
+ sal_Bool isAbort () const;
+ ::rtl::OUString getFilter() const;
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getRequest () throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > SAL_CALL getContinuations() throw( ::com::sun::star::uno::RuntimeException );
+
+ ::com::sun::star::uno::Any m_aRequest ;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > m_lContinuations;
+ ContinuationAbort* m_pAbort ;
+ ContinuationFilterSelect* m_pFilter ;
+};
+
+RequestAmbigousFilter::RequestAmbigousFilter( const ::rtl::OUString& sURL, const ::rtl::OUString& sSelectedFilter,
+ const ::rtl::OUString& sDetectedFilter )
+{
+ pImp = new RequestAmbigousFilter_Impl( sURL, sSelectedFilter, sDetectedFilter );
+ pImp->acquire();
+}
+
+RequestAmbigousFilter::~RequestAmbigousFilter()
+{
+ pImp->release();
+}
+
+sal_Bool RequestAmbigousFilter::isAbort() const
+{
+ return pImp->isAbort();
+}
+
+//---------------------------------------------------------------------------------------------------------
+// return user selected filter
+// Return value valid for non aborted interaction only. Please check "isAbort()" before you call these ony!
+//---------------------------------------------------------------------------------------------------------
+::rtl::OUString RequestAmbigousFilter::getFilter() const
+{
+ return pImp->getFilter();
+}
+
+uno::Reference < task::XInteractionRequest > RequestAmbigousFilter::GetRequest()
+{
+ return uno::Reference < task::XInteractionRequest > (pImp);
+}
+
+//---------------------------------------------------------------------------------------------------------
+// initialize instance with all neccessary informations
+// We use it without any further checks on our member then ...!
+//---------------------------------------------------------------------------------------------------------
+RequestAmbigousFilter_Impl::RequestAmbigousFilter_Impl( const ::rtl::OUString& sURL ,
+ const ::rtl::OUString& sSelectedFilter ,
+ const ::rtl::OUString& sDetectedFilter )
+{
+ ::rtl::OUString temp;
+ css::uno::Reference< css::uno::XInterface > temp2;
+ css::document::AmbigousFilterRequest aFilterRequest( temp ,
+ temp2 ,
+ sURL ,
+ sSelectedFilter ,
+ sDetectedFilter );
+ m_aRequest <<= aFilterRequest;
+
+ m_pAbort = new ContinuationAbort ;
+ m_pFilter = new ContinuationFilterSelect;
+
+ m_lContinuations.realloc( 2 );
+ m_lContinuations[0] = css::uno::Reference< css::task::XInteractionContinuation >( m_pAbort );
+ m_lContinuations[1] = css::uno::Reference< css::task::XInteractionContinuation >( m_pFilter );
+}
+
+//---------------------------------------------------------------------------------------------------------
+// return abort state of interaction
+// If it is true, return value of method "getFilter()" will be unspecified then!
+//---------------------------------------------------------------------------------------------------------
+sal_Bool RequestAmbigousFilter_Impl::isAbort() const
+{
+ return m_pAbort->isSelected();
+}
+
+//---------------------------------------------------------------------------------------------------------
+// return user selected filter
+// Return value valid for non aborted interaction only. Please check "isAbort()" before you call these ony!
+//---------------------------------------------------------------------------------------------------------
+::rtl::OUString RequestAmbigousFilter_Impl::getFilter() const
+{
+ return m_pFilter->getFilter();
+}
+
+//---------------------------------------------------------------------------------------------------------
+// handler call it to get type of request
+// Is hard coded to "please select filter" here. see ctor for further informations.
+//---------------------------------------------------------------------------------------------------------
+css::uno::Any SAL_CALL RequestAmbigousFilter_Impl::getRequest() throw( css::uno::RuntimeException )
+{
+ return m_aRequest;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// handler call it to get possible continuations
+// We support "abort/select_filter" only here.
+// After interaction we support read access on these continuations on our c++ interface to
+// return user decision.
+//---------------------------------------------------------------------------------------------------------
+css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > SAL_CALL RequestAmbigousFilter_Impl::getContinuations() throw( css::uno::RuntimeException )
+{
+ return m_lContinuations;
+}
+*/
+
+class InteractionRequest_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionRequest >
+{
+ uno::Any m_aRequest;
+ uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > m_lContinuations;
+
+public:
+ InteractionRequest_Impl( const ::com::sun::star::uno::Any& aRequest,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > lContinuations )
+ {
+ m_aRequest = aRequest;
+ m_lContinuations = lContinuations;
+ }
+
+ virtual uno::Any SAL_CALL getRequest() throw( uno::RuntimeException );
+ virtual uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL getContinuations()
+ throw( uno::RuntimeException );
+};
+
+uno::Any SAL_CALL InteractionRequest_Impl::getRequest() throw( uno::RuntimeException )
+{
+ return m_aRequest;
+}
+
+uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL InteractionRequest_Impl::getContinuations()
+ throw( uno::RuntimeException )
+{
+ return m_lContinuations;
+}
+
+uno::Reference < task::XInteractionRequest > InteractionRequest::CreateRequest(
+ const uno::Any& aRequest, const uno::Sequence< uno::Reference< task::XInteractionContinuation > > lContinuations )
+{
+ return new InteractionRequest_Impl( aRequest, lContinuations );
+}
+
+} // namespace framework
diff --git a/framework/source/fwe/helper/acceleratorinfo.cxx b/framework/source/fwe/helper/acceleratorinfo.cxx
new file mode 100644
index 000000000000..74ca316f7b5d
--- /dev/null
+++ b/framework/source/fwe/helper/acceleratorinfo.cxx
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <framework/acceleratorinfo.hxx>
+
+namespace framework
+{
+
+static pfunc_getCommandURLFromKeyCode _pGetCommandURLFromKeyCode = NULL;
+static pfunc_getKeyCodeFromCommandURL _pGetKeyCodeFromCommandURL = NULL;
+
+pfunc_getCommandURLFromKeyCode SAL_CALL SetCommandURLFromKeyCode( pfunc_getCommandURLFromKeyCode pNewFunc )
+{
+ pfunc_getCommandURLFromKeyCode pOldFunc = _pGetCommandURLFromKeyCode;
+ _pGetCommandURLFromKeyCode = pNewFunc;
+
+ return pOldFunc;
+}
+
+::rtl::OUString SAL_CALL GetCommandURLFromKeyCode( const KeyCode& aKeyCode )
+{
+ if ( _pGetCommandURLFromKeyCode )
+ return _pGetCommandURLFromKeyCode( aKeyCode );
+ else
+ return rtl::OUString();
+}
+
+pfunc_getKeyCodeFromCommandURL SAL_CALL SetKeyCodeFromCommandURL( pfunc_getKeyCodeFromCommandURL pNewFunc )
+{
+ pfunc_getKeyCodeFromCommandURL pOldFunc = _pGetKeyCodeFromCommandURL;
+ _pGetKeyCodeFromCommandURL = pNewFunc;
+
+ return pOldFunc;
+}
+
+KeyCode SAL_CALL GetKeyCodeFromCommandURL( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const rtl::OUString& aCommandURL )
+{
+ if ( _pGetKeyCodeFromCommandURL )
+ return _pGetKeyCodeFromCommandURL( rFrame, aCommandURL );
+ else
+ return KeyCode();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/helper/actiontriggerhelper.cxx b/framework/source/fwe/helper/actiontriggerhelper.cxx
new file mode 100644
index 000000000000..44518a3458b9
--- /dev/null
+++ b/framework/source/fwe/helper/actiontriggerhelper.cxx
@@ -0,0 +1,405 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <framework/actiontriggerhelper.hxx>
+#include <classes/actiontriggerseparatorpropertyset.hxx>
+#include <classes/rootactiontriggercontainer.hxx>
+#include <classes/imagewrapper.hxx>
+#include <framework/addonsoptions.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+#include <tools/stream.hxx>
+#include <cppuhelper/weak.hxx>
+#include <comphelper/processfactory.hxx>
+
+
+const sal_uInt16 START_ITEMID = 1000;
+
+using namespace com::sun::star::awt;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+
+using ::rtl::OUString;
+
+namespace framework
+{
+
+// ----------------------------------------------------------------------------
+// implementation helper ( menu => ActionTrigger )
+// ----------------------------------------------------------------------------
+
+sal_Bool IsSeparator( Reference< XPropertySet > xPropertySet )
+{
+ Reference< XServiceInfo > xServiceInfo( xPropertySet, UNO_QUERY );
+ try
+ {
+ return xServiceInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERSEPARATOR )) );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ return sal_False;
+}
+
+void GetMenuItemAttributes( Reference< XPropertySet > xActionTriggerPropertySet,
+ OUString& aMenuLabel,
+ OUString& aCommandURL,
+ OUString& aHelpURL,
+ Reference< XBitmap >& xBitmap,
+ Reference< XIndexContainer >& xSubContainer )
+{
+ Any a;
+
+ try
+ {
+ // mandatory properties
+ a = xActionTriggerPropertySet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" )) );
+ a >>= aMenuLabel;
+ a = xActionTriggerPropertySet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" )) );
+ a >>= aCommandURL;
+ a = xActionTriggerPropertySet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Image" )) );
+ a >>= xBitmap;
+ a = xActionTriggerPropertySet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "SubContainer" )) );
+ a >>= xSubContainer;
+ }
+ catch ( Exception& )
+ {
+ }
+
+ // optional properties
+ try
+ {
+ a = xActionTriggerPropertySet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpURL" )) );
+ a >>= aHelpURL;
+ }
+ catch ( Exception& )
+ {
+ }
+}
+
+void InsertSubMenuItems( Menu* pSubMenu, sal_uInt16& nItemId, Reference< XIndexContainer > xActionTriggerContainer )
+{
+ Reference< XIndexAccess > xIndexAccess( xActionTriggerContainer, UNO_QUERY );
+ if ( xIndexAccess.is() )
+ {
+ AddonsOptions aAddonOptions;
+ OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+
+ for ( sal_Int32 i = 0; i < xIndexAccess->getCount(); i++ )
+ {
+ try
+ {
+ Reference< XPropertySet > xPropSet;
+ if (( xIndexAccess->getByIndex( i ) >>= xPropSet ) && ( xPropSet.is() ))
+ {
+ if ( IsSeparator( xPropSet ))
+ {
+ // Separator
+ SolarMutexGuard aGuard;
+ pSubMenu->InsertSeparator();
+ }
+ else
+ {
+ // Menu item
+ OUString aLabel;
+ OUString aCommandURL;
+ OUString aHelpURL;
+ Reference< XBitmap > xBitmap;
+ Reference< XIndexContainer > xSubContainer;
+
+ sal_uInt16 nNewItemId = nItemId++;
+ GetMenuItemAttributes( xPropSet, aLabel, aCommandURL, aHelpURL, xBitmap, xSubContainer );
+
+ SolarMutexGuard aGuard;
+ {
+ // insert new menu item
+ sal_Int32 nIndex = aCommandURL.indexOf( aSlotURL );
+ if ( nIndex >= 0 )
+ {
+ // Special code for our menu implementation: some menu items don't have a
+ // command url but uses the item id as a unqiue identifier. These entries
+ // got a special url during conversion from menu=>actiontriggercontainer.
+ // Now we have to extract this special url and set the correct item id!!!
+ nNewItemId = (sal_uInt16)aCommandURL.copy( nIndex+aSlotURL.getLength() ).toInt32();
+ pSubMenu->InsertItem( nNewItemId, aLabel );
+ }
+ else
+ {
+ pSubMenu->InsertItem( nNewItemId, aLabel );
+ pSubMenu->SetItemCommand( nNewItemId, aCommandURL );
+ }
+
+ // handle bitmap
+ if ( xBitmap.is() )
+ {
+ sal_Bool bImageSet = sal_False;
+
+ Reference< XUnoTunnel > xUnoTunnel( xBitmap, UNO_QUERY );
+ if ( xUnoTunnel.is() )
+ {
+ // Try to get implementation pointer through XUnoTunnel
+ sal_Int64 nPointer = xUnoTunnel->getSomething( ImageWrapper::GetUnoTunnelId() );
+ if ( nPointer )
+ {
+ // This is our own optimized implementation of menu images!
+ ImageWrapper* pImageWrapper = reinterpret_cast< ImageWrapper * >( nPointer );
+ Image aMenuImage = pImageWrapper->GetImage();
+
+ if ( !!aMenuImage )
+ pSubMenu->SetItemImage( nNewItemId, aMenuImage );
+
+ bImageSet = sal_True;
+ }
+ }
+
+ if ( !bImageSet )
+ {
+ // This is an unknown implementation of a XBitmap interface. We have to
+ // use a more time consuming way to build an Image!
+ Image aImage;
+ Bitmap aBitmap;
+
+ Sequence< sal_Int8 > aDIBSeq;
+ {
+ aDIBSeq = xBitmap->getDIB();
+ SvMemoryStream aMem( (void *)aDIBSeq.getConstArray(), aDIBSeq.getLength(), STREAM_READ );
+ aMem >> aBitmap;
+ }
+
+ aDIBSeq = xBitmap->getMaskDIB();
+ if ( aDIBSeq.getLength() > 0 )
+ {
+ Bitmap aMaskBitmap;
+ SvMemoryStream aMem( (void *)aDIBSeq.getConstArray(), aDIBSeq.getLength(), STREAM_READ );
+ aMem >> aMaskBitmap;
+ aImage = Image( aBitmap, aMaskBitmap );
+ }
+ else
+ aImage = Image( aBitmap );
+
+ if ( !!aImage )
+ pSubMenu->SetItemImage( nNewItemId, aImage );
+ }
+ }
+ else
+ {
+ // Support add-on images for context menu interceptors
+ Image aImage = aAddonOptions.GetImageFromURL( aCommandURL, sal_False, sal_True );
+ if ( !!aImage )
+ pSubMenu->SetItemImage( nNewItemId, aImage );
+ }
+
+ if ( xSubContainer.is() )
+ {
+ PopupMenu* pNewSubMenu = new PopupMenu;
+
+ // Sub menu (recursive call CreateSubMenu )
+ InsertSubMenuItems( pNewSubMenu, nItemId, xSubContainer );
+ pSubMenu->SetPopupMenu( nNewItemId, pNewSubMenu );
+ }
+ }
+ }
+ }
+ }
+ catch ( IndexOutOfBoundsException )
+ {
+ return;
+ }
+ catch ( WrappedTargetException )
+ {
+ return;
+ }
+ catch ( RuntimeException )
+ {
+ return;
+ }
+ }
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// implementation helper ( ActionTrigger => menu )
+// ----------------------------------------------------------------------------
+
+Reference< XPropertySet > CreateActionTrigger( sal_uInt16 nItemId, const Menu* pMenu, const Reference< XIndexContainer >& rActionTriggerContainer ) throw ( RuntimeException )
+{
+ Reference< XPropertySet > xPropSet;
+
+ Reference< XMultiServiceFactory > xMultiServiceFactory( rActionTriggerContainer, UNO_QUERY );
+ if ( xMultiServiceFactory.is() )
+ {
+ xPropSet = Reference< XPropertySet >( xMultiServiceFactory->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ActionTrigger" )) ),
+ UNO_QUERY );
+
+ Any a;
+
+ try
+ {
+ // Retrieve the menu attributes and set them in our PropertySet
+ OUString aLabel = pMenu->GetItemText( nItemId );
+ a <<= aLabel;
+ xPropSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" )), a );
+
+ OUString aCommandURL = pMenu->GetItemCommand( nItemId );
+
+ if ( aCommandURL.getLength() == 0 )
+ {
+ aCommandURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ aCommandURL += OUString::valueOf( (sal_Int32)nItemId );
+ }
+
+ a <<= aCommandURL;
+ xPropSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" )), a );
+
+ Image aImage = pMenu->GetItemImage( nItemId );
+ if ( !!aImage )
+ {
+ // We use our own optimized XBitmap implementation
+ Reference< XBitmap > xBitmap( static_cast< cppu::OWeakObject* >( new ImageWrapper( aImage )), UNO_QUERY );
+ a <<= xBitmap;
+ xPropSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Image" )), a );
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ return xPropSet;
+}
+
+Reference< XPropertySet > CreateActionTriggerSeparator( const Reference< XIndexContainer >& rActionTriggerContainer ) throw ( RuntimeException )
+{
+ Reference< XMultiServiceFactory > xMultiServiceFactory( rActionTriggerContainer, UNO_QUERY );
+ if ( xMultiServiceFactory.is() )
+ {
+ return Reference< XPropertySet >( xMultiServiceFactory->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ActionTriggerSeparator" )) ),
+ UNO_QUERY );
+ }
+
+ return Reference< XPropertySet >();
+}
+
+Reference< XIndexContainer > CreateActionTriggerContainer( const Reference< XIndexContainer >& rActionTriggerContainer ) throw ( RuntimeException )
+{
+ Reference< XMultiServiceFactory > xMultiServiceFactory( rActionTriggerContainer, UNO_QUERY );
+ if ( xMultiServiceFactory.is() )
+ {
+ return Reference< XIndexContainer >( xMultiServiceFactory->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ActionTriggerContainer" )) ),
+ UNO_QUERY );
+ }
+
+ return Reference< XIndexContainer >();
+}
+
+void FillActionTriggerContainerWithMenu( const Menu* pMenu, Reference< XIndexContainer >& rActionTriggerContainer )
+{
+ SolarMutexGuard aGuard;
+
+ for ( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
+ {
+ sal_uInt16 nItemId = pMenu->GetItemId( nPos );
+ MenuItemType nType = pMenu->GetItemType( nPos );
+
+ try
+ {
+ Any a;
+ Reference< XPropertySet > xPropSet;
+
+ if ( nType == MENUITEM_SEPARATOR )
+ {
+ xPropSet = CreateActionTriggerSeparator( rActionTriggerContainer );
+
+ a <<= xPropSet;
+ rActionTriggerContainer->insertByIndex( nPos, a );
+ }
+ else
+ {
+ xPropSet = CreateActionTrigger( nItemId, pMenu, rActionTriggerContainer );
+
+ a <<= xPropSet;
+ rActionTriggerContainer->insertByIndex( nPos, a );
+
+ PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nItemId );
+ if ( pPopupMenu )
+ {
+ // recursive call to build next sub menu
+ Reference< XIndexContainer > xSubContainer = CreateActionTriggerContainer( rActionTriggerContainer );
+
+ a <<= xSubContainer;
+ xPropSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "SubContainer" )), a );
+ FillActionTriggerContainerWithMenu( pPopupMenu, xSubContainer );
+ }
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+void ActionTriggerHelper::CreateMenuFromActionTriggerContainer(
+ Menu* pNewMenu,
+ const Reference< XIndexContainer >& rActionTriggerContainer )
+{
+ sal_uInt16 nItemId = START_ITEMID;
+
+ if ( rActionTriggerContainer.is() )
+ InsertSubMenuItems( pNewMenu, nItemId, rActionTriggerContainer );
+}
+
+void ActionTriggerHelper::FillActionTriggerContainerFromMenu(
+ Reference< XIndexContainer >& xActionTriggerContainer,
+ const Menu* pMenu )
+{
+ FillActionTriggerContainerWithMenu( pMenu, xActionTriggerContainer );
+}
+
+Reference< XIndexContainer > ActionTriggerHelper::CreateActionTriggerContainerFromMenu(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ const Menu* pMenu,
+ const ::rtl::OUString* pMenuIdentifier )
+{
+ return new RootActionTriggerContainer( pMenu, pMenuIdentifier, xServiceFactory );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/helper/configimporter.cxx b/framework/source/fwe/helper/configimporter.cxx
new file mode 100644
index 000000000000..53752ba15109
--- /dev/null
+++ b/framework/source/fwe/helper/configimporter.cxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <framework/configimporter.hxx>
+#include <framework/toolboxconfiguration.hxx>
+#include <com/sun/star/embed/ElementModes.hpp>
+
+#include <rtl/ustrbuf.hxx>
+
+using namespace ::com::sun::star;
+
+namespace framework
+{
+
+sal_Bool UIConfigurationImporterOOo1x::ImportCustomToolbars(
+ const uno::Reference< ui::XUIConfigurationManager >& rContainerFactory,
+ uno::Sequence< uno::Reference< container::XIndexContainer > >& rSeqContainer,
+ const uno::Reference< lang::XMultiServiceFactory >& rServiceManager,
+ const uno::Reference< embed::XStorage >& rToolbarStorage )
+{
+ const char USERDEFTOOLBOX[] = "userdeftoolbox0.xml";
+ uno::Reference< lang::XMultiServiceFactory > rSrvMgr( rServiceManager );
+
+ sal_Bool bResult ( sal_False );
+ if ( rToolbarStorage.is() && rContainerFactory.is() )
+ {
+ try
+ {
+ for ( sal_uInt16 i = 1; i <= 4; i++ )
+ {
+ rtl::OUStringBuffer aCustomTbxName( 20 );
+ aCustomTbxName.appendAscii( USERDEFTOOLBOX );
+ aCustomTbxName.setCharAt( 14, aCustomTbxName.charAt( 14 ) + i );
+
+ rtl::OUString aTbxStreamName( aCustomTbxName.makeStringAndClear() );
+ uno::Reference< io::XStream > xStream = rToolbarStorage->openStreamElement( aTbxStreamName, embed::ElementModes::READ );
+ if ( xStream.is() )
+ {
+ uno::Reference< io::XInputStream > xInputStream = xStream->getInputStream();
+ if ( xInputStream.is() )
+ {
+ uno::Reference< container::XIndexContainer > xContainer = rContainerFactory->createSettings();
+ if ( ToolBoxConfiguration::LoadToolBox( rSrvMgr, xInputStream, xContainer ))
+ {
+ sal_uInt32 nIndex = rSeqContainer.getLength();
+ rSeqContainer.realloc( nIndex+1 );
+ rSeqContainer[nIndex] = xContainer;
+ bResult = sal_True;
+ }
+ }
+ }
+ }
+ }
+ catch ( uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+
+ return bResult;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/helper/documentundoguard.cxx b/framework/source/fwe/helper/documentundoguard.cxx
new file mode 100644
index 000000000000..91265cf45170
--- /dev/null
+++ b/framework/source/fwe/helper/documentundoguard.cxx
@@ -0,0 +1,271 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_framework.hxx"
+
+#include "framework/documentundoguard.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/document/XUndoManagerSupplier.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/implbase1.hxx>
+#include <rtl/ref.hxx>
+#include <tools/diagnose_ex.h>
+
+//......................................................................................................................
+namespace framework
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::document::XUndoManagerSupplier;
+ using ::com::sun::star::document::XUndoManager;
+ using ::com::sun::star::document::XUndoManagerListener;
+ using ::com::sun::star::document::UndoManagerEvent;
+ using ::com::sun::star::lang::EventObject;
+ /** === end UNO using === **/
+
+ //==================================================================================================================
+ //= UndoManagerContextListener
+ //==================================================================================================================
+ typedef ::cppu::WeakImplHelper1 < XUndoManagerListener
+ > UndoManagerContextListener_Base;
+ class UndoManagerContextListener : public UndoManagerContextListener_Base
+ {
+ public:
+ UndoManagerContextListener( const Reference< XUndoManager >& i_undoManager )
+ :m_xUndoManager( i_undoManager, UNO_QUERY_THROW )
+ ,m_nRelativeContextDepth( 0 )
+ ,m_documentDisposed( false )
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ m_xUndoManager->addUndoManagerListener( this );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+ }
+
+ UndoManagerContextListener()
+ {
+ }
+
+ void finish()
+ {
+ OSL_ENSURE( m_nRelativeContextDepth >= 0, "UndoManagerContextListener: more contexts left than entered?" );
+
+ if ( m_documentDisposed )
+ return;
+
+ // work with a copy of m_nRelativeContextDepth, to be independent from possible bugs in the
+ // listener notifications (where it would be decremented with every leaveUndoContext)
+ sal_Int32 nDepth = m_nRelativeContextDepth;
+ while ( nDepth-- > 0 )
+ {
+ m_xUndoManager->leaveUndoContext();
+ }
+ m_xUndoManager->removeUndoManagerListener( this );
+ }
+
+ // XUndoManagerListener
+ virtual void SAL_CALL undoActionAdded( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL actionUndone( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL actionRedone( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL allActionsCleared( const EventObject& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL redoActionsCleared( const EventObject& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL resetAll( const EventObject& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL enteredContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL enteredHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL leftContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL leftHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
+ virtual void SAL_CALL cancelledContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject& i_event ) throw (RuntimeException);
+
+ private:
+ Reference< XUndoManager > const m_xUndoManager;
+ oslInterlockedCount m_nRelativeContextDepth;
+ bool m_documentDisposed;
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::undoActionAdded( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ // not interested in
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::actionUndone( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ // not interested in
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::actionRedone( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ // not interested in
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::allActionsCleared( const EventObject& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ // not interested in
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::redoActionsCleared( const EventObject& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ // not interested in
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::resetAll( const EventObject& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ m_nRelativeContextDepth = 0;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::enteredContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ osl_incrementInterlockedCount( &m_nRelativeContextDepth );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::enteredHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ osl_incrementInterlockedCount( &m_nRelativeContextDepth );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::leftContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ osl_decrementInterlockedCount( &m_nRelativeContextDepth );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::leftHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ osl_decrementInterlockedCount( &m_nRelativeContextDepth );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::cancelledContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ osl_decrementInterlockedCount( &m_nRelativeContextDepth );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL UndoManagerContextListener::disposing( const EventObject& i_event ) throw (RuntimeException)
+ {
+ (void)i_event;
+ m_documentDisposed = true;
+ }
+
+ //==================================================================================================================
+ //= DocumentUndoGuard_Data
+ //==================================================================================================================
+ struct DocumentUndoGuard_Data
+ {
+ Reference< XUndoManager > xUndoManager;
+ ::rtl::Reference< UndoManagerContextListener > pContextListener;
+ };
+
+ namespace
+ {
+ //--------------------------------------------------------------------------------------------------------------
+ void lcl_init( DocumentUndoGuard_Data& i_data, const Reference< XInterface >& i_undoSupplierComponent )
+ {
+ try
+ {
+ Reference< XUndoManagerSupplier > xUndoSupplier( i_undoSupplierComponent, UNO_QUERY );
+ if ( xUndoSupplier.is() )
+ i_data.xUndoManager.set( xUndoSupplier->getUndoManager(), UNO_QUERY_THROW );
+
+ if ( i_data.xUndoManager.is() )
+ i_data.pContextListener.set( new UndoManagerContextListener( i_data.xUndoManager ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //--------------------------------------------------------------------------------------------------------------
+ void lcl_restore( DocumentUndoGuard_Data& i_data )
+ {
+ try
+ {
+ if ( i_data.pContextListener.is() )
+ i_data.pContextListener->finish();
+ i_data.pContextListener.clear();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+
+ //==================================================================================================================
+ //= DocumentUndoGuard
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ DocumentUndoGuard::DocumentUndoGuard( const Reference< XInterface >& i_undoSupplierComponent )
+ :m_pData( new DocumentUndoGuard_Data )
+ {
+ lcl_init( *m_pData, i_undoSupplierComponent );
+ }
+
+ DocumentUndoGuard::~DocumentUndoGuard()
+ {
+ lcl_restore( *m_pData );
+ }
+
+//......................................................................................................................
+} // namespace framework
+//......................................................................................................................
diff --git a/framework/source/fwe/helper/imageproducer.cxx b/framework/source/fwe/helper/imageproducer.cxx
new file mode 100644
index 000000000000..de4aa0f33811
--- /dev/null
+++ b/framework/source/fwe/helper/imageproducer.cxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <framework/imageproducer.hxx>
+
+namespace framework
+{
+
+static pfunc_getImage _pGetImageFunc = NULL;
+
+pfunc_getImage SAL_CALL SetImageProducer( pfunc_getImage pNewGetImageFunc )
+{
+ pfunc_getImage pOldFunc = _pGetImageFunc;
+ _pGetImageFunc = pNewGetImageFunc;
+
+ return pOldFunc;
+}
+
+
+Image SAL_CALL GetImageFromURL(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame,
+ const ::rtl::OUString& aURL,
+ bool bBig
+)
+{
+ if ( _pGetImageFunc )
+ return _pGetImageFunc( rFrame, aURL, bBig );
+ else
+ return Image();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/helper/propertysetcontainer.cxx b/framework/source/fwe/helper/propertysetcontainer.cxx
new file mode 100644
index 000000000000..7e05bbf03d38
--- /dev/null
+++ b/framework/source/fwe/helper/propertysetcontainer.cxx
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <helper/propertysetcontainer.hxx>
+#include <threadhelp/resetableguard.hxx>
+
+#include <vcl/svapp.hxx>
+
+#define WRONG_TYPE_EXCEPTION "Only XPropertSet allowed!"
+
+using ::rtl::OUString;
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::container;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+
+namespace framework
+{
+
+PropertySetContainer::PropertySetContainer( const Reference< XMultiServiceFactory >& )
+ : ThreadHelpBase( &Application::GetSolarMutex() )
+ , OWeakObject()
+
+{
+}
+
+
+PropertySetContainer::~PropertySetContainer()
+{
+}
+
+
+// XInterface
+void SAL_CALL PropertySetContainer::acquire() throw ()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL PropertySetContainer::release() throw ()
+{
+ OWeakObject::release();
+}
+
+Any SAL_CALL PropertySetContainer::queryInterface( const Type& rType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ rType ,
+ SAL_STATIC_CAST( XIndexContainer*, this ),
+ SAL_STATIC_CAST( XIndexReplace*, this ),
+ SAL_STATIC_CAST( XIndexAccess*, this ),
+ SAL_STATIC_CAST( XElementAccess*, this ) );
+
+ if( a.hasValue() )
+ {
+ return a;
+ }
+
+ return OWeakObject::queryInterface( rType );
+}
+
+// XIndexContainer
+void SAL_CALL PropertySetContainer::insertByIndex( sal_Int32 Index, const ::com::sun::star::uno::Any& Element )
+ throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ sal_Int32 nSize = m_aPropertySetVector.size();
+
+ if ( nSize >= Index )
+ {
+ Reference< XPropertySet > aPropertySetElement;
+
+ if ( Element >>= aPropertySetElement )
+ {
+ if ( nSize == Index )
+ m_aPropertySetVector.push_back( aPropertySetElement );
+ else
+ {
+ PropertySetVector::iterator aIter = m_aPropertySetVector.begin();
+ aIter += Index;
+ m_aPropertySetVector.insert( aIter, aPropertySetElement );
+ }
+ }
+ else
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
+ (OWeakObject *)this, 2 );
+ }
+ }
+ else
+ throw IndexOutOfBoundsException( OUString(), (OWeakObject *)this );
+}
+
+void SAL_CALL PropertySetContainer::removeByIndex( sal_Int32 Index )
+ throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( (sal_Int32)m_aPropertySetVector.size() > Index )
+ {
+ PropertySetVector::iterator aIter = m_aPropertySetVector.begin();
+ aIter += Index;
+ m_aPropertySetVector.erase( aIter );
+ }
+ else
+ throw IndexOutOfBoundsException( OUString(), (OWeakObject *)this );
+}
+
+// XIndexReplace
+void SAL_CALL PropertySetContainer::replaceByIndex( sal_Int32 Index, const ::com::sun::star::uno::Any& Element )
+ throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+{
+ if ( (sal_Int32)m_aPropertySetVector.size() > Index )
+ {
+ Reference< XPropertySet > aPropertySetElement;
+
+ if ( Element >>= aPropertySetElement )
+ {
+ m_aPropertySetVector[ Index ] = aPropertySetElement;
+ }
+ else
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
+ (OWeakObject *)this, 2 );
+ }
+ }
+ else
+ throw IndexOutOfBoundsException( OUString(), (OWeakObject *)this );
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL PropertySetContainer::getCount()
+ throw ( RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ return m_aPropertySetVector.size();
+}
+
+Any SAL_CALL PropertySetContainer::getByIndex( sal_Int32 Index )
+ throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( (sal_Int32)m_aPropertySetVector.size() > Index )
+ {
+ Any a;
+
+ a <<= m_aPropertySetVector[ Index ];
+ return a;
+ }
+ else
+ throw IndexOutOfBoundsException( OUString(), (OWeakObject *)this );
+}
+
+// XElementAccess
+sal_Bool SAL_CALL PropertySetContainer::hasElements()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ return !( m_aPropertySetVector.empty() );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/helper/titlehelper.cxx b/framework/source/fwe/helper/titlehelper.cxx
new file mode 100644
index 000000000000..a1db0de3ec5d
--- /dev/null
+++ b/framework/source/fwe/helper/titlehelper.cxx
@@ -0,0 +1,730 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// includes
+
+#include <framework/titlehelper.hxx>
+#include <services.h>
+#include <properties.h>
+
+#include <com/sun/star/frame/UntitledNumbersConst.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+
+#include <unotools/configmgr.hxx>
+#include <unotools/bootstrap.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/mutex.hxx>
+#include <tools/urlobj.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+namespace css = ::com::sun::star;
+
+//-----------------------------------------------
+TitleHelper::TitleHelper(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ::cppu::BaseMutex ()
+ , m_xSMGR (xSMGR)
+ , m_xOwner ()
+ , m_xUntitledNumbers()
+ , m_xSubTitle ()
+ , m_bExternalTitle (sal_False)
+ , m_sTitle ()
+ , m_nLeasedNumber (css::frame::UntitledNumbersConst::INVALID_NUMBER)
+ , m_aListener (m_aMutex)
+{
+}
+
+//-----------------------------------------------
+TitleHelper::~TitleHelper()
+{
+}
+
+//-----------------------------------------------
+void TitleHelper::setOwner(const css::uno::Reference< css::uno::XInterface >& xOwner)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ m_xOwner = xOwner;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ css::uno::Reference< css::frame::XModel > xModel(xOwner, css::uno::UNO_QUERY);
+ if (xModel.is ())
+ {
+ impl_startListeningForModel (xModel);
+ return;
+ }
+
+ css::uno::Reference< css::frame::XController > xController(xOwner, css::uno::UNO_QUERY);
+ if (xController.is ())
+ {
+ impl_startListeningForController (xController);
+ return;
+ }
+
+ css::uno::Reference< css::frame::XFrame > xFrame(xOwner, css::uno::UNO_QUERY);
+ if (xFrame.is ())
+ {
+ impl_startListeningForFrame (xFrame);
+ return;
+ }
+}
+
+//-----------------------------------------------
+::rtl::OUString SAL_CALL TitleHelper::getTitle()
+ throw (css::uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ // An external title will win always and disable all internal logic about
+ // creating/using a title value.
+ // Even an empty string will be accepted as valid title !
+ if (m_bExternalTitle)
+ return m_sTitle;
+
+ // Title seams to be up-to-date. Return it directly.
+ if (m_sTitle.getLength() > 0)
+ return m_sTitle;
+
+ // Title seams to be unused till now ... do bootstraping
+ impl_updateTitle ();
+
+ return m_sTitle;
+
+ // <- SYNCHRONIZED
+}
+
+//-----------------------------------------------
+void TitleHelper::connectWithUntitledNumbers (const css::uno::Reference< css::frame::XUntitledNumbers >& xNumbers)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ m_xUntitledNumbers = xNumbers;
+
+ // <- SYNCHRONIZED
+}
+
+//-----------------------------------------------
+void SAL_CALL TitleHelper::setTitle(const ::rtl::OUString& sTitle)
+ throw (css::uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ m_bExternalTitle = sal_True;
+ m_sTitle = sTitle;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ impl_sendTitleChangedEvent ();
+}
+
+//-----------------------------------------------
+void SAL_CALL TitleHelper::addTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener >& xListener)
+ throw (css::uno::RuntimeException)
+{
+ // container is threadsafe by himself
+ m_aListener.addInterface( ::getCppuType( (const css::uno::Reference< css::frame::XTitleChangeListener >*)NULL ), xListener );
+}
+
+//-----------------------------------------------
+void SAL_CALL TitleHelper::removeTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener >& xListener)
+ throw (css::uno::RuntimeException)
+{
+ // container is threadsafe by himself
+ m_aListener.removeInterface( ::getCppuType( (const css::uno::Reference< css::frame::XTitleChangeListener >*)NULL ), xListener );
+}
+
+//-----------------------------------------------
+void SAL_CALL TitleHelper::titleChanged(const css::frame::TitleChangedEvent& aEvent)
+ throw (css::uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ css::uno::Reference< css::frame::XTitle > xSubTitle(m_xSubTitle.get (), css::uno::UNO_QUERY);
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if (aEvent.Source != xSubTitle)
+ return;
+
+ impl_updateTitle ();
+}
+
+//-----------------------------------------------
+void SAL_CALL TitleHelper::notifyEvent(const css::document::EventObject& aEvent)
+ throw (css::uno::RuntimeException)
+{
+ if ( ! aEvent.EventName.equalsIgnoreAsciiCaseAscii ("OnSaveAsDone")
+ && ! aEvent.EventName.equalsIgnoreAsciiCaseAscii ("OnTitleChanged"))
+ return;
+
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ css::uno::Reference< css::frame::XModel > xOwner(m_xOwner.get (), css::uno::UNO_QUERY);
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if (
+ aEvent.Source != xOwner ||
+ (aEvent.EventName.equalsIgnoreAsciiCaseAscii ("OnTitleChanged") && !xOwner.is())
+ )
+ {
+ return;
+ }
+
+ impl_updateTitle ();
+}
+
+//-----------------------------------------------
+void SAL_CALL TitleHelper::frameAction(const css::frame::FrameActionEvent& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ css::uno::Reference< css::frame::XFrame > xOwner(m_xOwner.get (), css::uno::UNO_QUERY);
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if (aEvent.Source != xOwner)
+ return;
+
+ // we are interested on events only, which must trigger a title bar update
+ // because component was changed.
+ if (
+ (aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ) ||
+ (aEvent.Action == css::frame::FrameAction_COMPONENT_REATTACHED) ||
+ (aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING )
+ )
+ {
+ impl_updateListeningForFrame (xOwner);
+ impl_updateTitle ();
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL TitleHelper::disposing(const css::lang::EventObject& aEvent)
+ throw (css::uno::RuntimeException)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+ css::uno::Reference< css::uno::XInterface > xOwner (m_xOwner.get() , css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XUntitledNumbers > xNumbers (m_xUntitledNumbers.get(), css::uno::UNO_QUERY);
+ ::sal_Int32 nLeasedNumber = m_nLeasedNumber;
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if ( ! xOwner.is ())
+ return;
+
+ if (xOwner != aEvent.Source)
+ return;
+
+ if (
+ (xNumbers.is () ) &&
+ (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER)
+ )
+ xNumbers->releaseNumber (nLeasedNumber);
+
+ // SYNCHRONIZED ->
+ aLock.reset ();
+
+ m_sTitle = ::rtl::OUString ();
+ m_nLeasedNumber = css::frame::UntitledNumbersConst::INVALID_NUMBER;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ impl_sendTitleChangedEvent ();
+}
+
+//-----------------------------------------------
+void TitleHelper::impl_sendTitleChangedEvent ()
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ css::frame::TitleChangedEvent aEvent(m_xOwner.get (), m_sTitle);
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListener.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XTitleChangeListener >*) NULL ) );
+ if ( ! pContainer)
+ return;
+
+ ::cppu::OInterfaceIteratorHelper pIt( *pContainer );
+ while ( pIt.hasMoreElements() )
+ {
+ try
+ {
+ ((css::frame::XTitleChangeListener*)pIt.next())->titleChanged( aEvent );
+ }
+ catch(const css::uno::Exception&)
+ {
+ pIt.remove();
+ }
+ }
+}
+
+//-----------------------------------------------
+void TitleHelper::impl_updateTitle ()
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ css::uno::Reference< css::frame::XModel > xModel (m_xOwner.get(), css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XController > xController(m_xOwner.get(), css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XFrame > xFrame (m_xOwner.get(), css::uno::UNO_QUERY);
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if (xModel.is ())
+ {
+ impl_updateTitleForModel (xModel);
+ return;
+ }
+
+ if (xController.is ())
+ {
+ impl_updateTitleForController (xController);
+ return;
+ }
+
+ if (xFrame.is ())
+ {
+ impl_updateTitleForFrame (xFrame);
+ return;
+ }
+}
+
+//-----------------------------------------------
+void TitleHelper::impl_updateTitleForModel (const css::uno::Reference< css::frame::XModel >& xModel)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ // external title wont be updated internaly !
+ // It has to be set from outside new.
+ if (m_bExternalTitle)
+ return;
+
+ css::uno::Reference< css::uno::XInterface > xOwner (m_xOwner.get() , css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XUntitledNumbers > xNumbers (m_xUntitledNumbers.get(), css::uno::UNO_QUERY);
+ ::sal_Int32 nLeasedNumber = m_nLeasedNumber;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if (
+ ( ! xOwner.is ()) ||
+ ( ! xNumbers.is ()) ||
+ ( ! xModel.is ())
+ )
+ return;
+
+ ::rtl::OUString sTitle;
+ ::rtl::OUString sURL ;
+
+ css::uno::Reference< css::frame::XStorable > xURLProvider(xModel , css::uno::UNO_QUERY);
+ if (xURLProvider.is())
+ sURL = xURLProvider->getLocation ();
+
+ if (sURL.getLength () > 0)
+ {
+ sTitle = impl_convertURL2Title(sURL);
+ if (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER)
+ xNumbers->releaseNumber (nLeasedNumber);
+ nLeasedNumber = css::frame::UntitledNumbersConst::INVALID_NUMBER;
+ }
+ else
+ {
+ if (nLeasedNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER)
+ nLeasedNumber = xNumbers->leaseNumber (xOwner);
+
+ ::rtl::OUStringBuffer sNewTitle(256);
+ sNewTitle.append (xNumbers->getUntitledPrefix ());
+ if (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER)
+ sNewTitle.append ((::sal_Int32)nLeasedNumber);
+ else
+ sNewTitle.appendAscii ("?");
+
+ sTitle = sNewTitle.makeStringAndClear ();
+ }
+
+ // SYNCHRONIZED ->
+ aLock.reset ();
+
+ // WORKAROUND: the notification is currently sent always,
+ // can be changed after shared mode is supported per UNO API
+ sal_Bool bChanged = sal_True; // (! m_sTitle.equals(sTitle));
+
+ m_sTitle = sTitle;
+ m_nLeasedNumber = nLeasedNumber;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if (bChanged)
+ impl_sendTitleChangedEvent ();
+}
+
+//-----------------------------------------------
+void TitleHelper::impl_updateTitleForController (const css::uno::Reference< css::frame::XController >& xController)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ // external title wont be updated internaly !
+ // It has to be set from outside new.
+ if (m_bExternalTitle)
+ return;
+
+ css::uno::Reference< css::uno::XInterface > xOwner (m_xOwner.get() , css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XUntitledNumbers > xNumbers (m_xUntitledNumbers.get(), css::uno::UNO_QUERY);
+ ::sal_Int32 nLeasedNumber = m_nLeasedNumber;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if (
+ ( ! xOwner.is ()) ||
+ ( ! xNumbers.is ()) ||
+ ( ! xController.is ())
+ )
+ return;
+
+ ::rtl::OUStringBuffer sTitle(256);
+
+ if (nLeasedNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER)
+ nLeasedNumber = xNumbers->leaseNumber (xOwner);
+
+ css::uno::Reference< css::frame::XTitle > xModelTitle(xController->getModel (), css::uno::UNO_QUERY);
+ if (!xModelTitle.is ())
+ xModelTitle.set(xController, css::uno::UNO_QUERY);
+ if (xModelTitle.is ())
+ {
+ sTitle.append (xModelTitle->getTitle ());
+ if ( nLeasedNumber > 1 )
+ {
+ sTitle.appendAscii (" : ");
+ sTitle.append ((::sal_Int32)nLeasedNumber);
+ }
+ }
+ else
+ {
+ sTitle.append (xNumbers->getUntitledPrefix ());
+ if ( nLeasedNumber > 1 )
+ {
+ sTitle.append ((::sal_Int32)nLeasedNumber );
+ }
+ }
+
+ // SYNCHRONIZED ->
+ aLock.reset ();
+
+ ::rtl::OUString sNewTitle = sTitle.makeStringAndClear ();
+ sal_Bool bChanged = (! m_sTitle.equals(sNewTitle));
+ m_sTitle = sNewTitle;
+ m_nLeasedNumber = nLeasedNumber;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if (bChanged)
+ impl_sendTitleChangedEvent ();
+}
+
+//-----------------------------------------------
+void TitleHelper::impl_updateTitleForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ if ( ! xFrame.is ())
+ return;
+
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ // external title wont be updated internaly !
+ // It has to be set from outside new.
+ if (m_bExternalTitle)
+ return;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ css::uno::Reference< css::uno::XInterface > xComponent;
+ xComponent = xFrame->getController ();
+ if ( ! xComponent.is ())
+ xComponent = xFrame->getComponentWindow ();
+
+ ::rtl::OUStringBuffer sTitle (256);
+
+ impl_appendComponentTitle (sTitle, xComponent);
+ impl_appendProductName (sTitle);
+ impl_appendModuleName (sTitle);
+ impl_appendProductExtension (sTitle);
+ impl_appendDebugVersion (sTitle);
+
+ // SYNCHRONIZED ->
+ aLock.reset ();
+
+ ::rtl::OUString sNewTitle = sTitle.makeStringAndClear ();
+ sal_Bool bChanged = (! m_sTitle.equals(sNewTitle));
+ m_sTitle = sNewTitle;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if (bChanged)
+ impl_sendTitleChangedEvent ();
+}
+
+//*****************************************************************************************************************
+void TitleHelper::impl_appendComponentTitle ( ::rtl::OUStringBuffer& sTitle ,
+ const css::uno::Reference< css::uno::XInterface >& xComponent)
+{
+ css::uno::Reference< css::frame::XTitle > xTitle(xComponent, css::uno::UNO_QUERY);
+
+ // Note: Title has to be used (even if it's empty) if the right interface is supported.
+ if (xTitle.is ())
+ sTitle.append (xTitle->getTitle ());
+}
+
+//*****************************************************************************************************************
+void TitleHelper::impl_appendProductName (::rtl::OUStringBuffer& sTitle)
+{
+ ::rtl::OUString sProductName;
+ ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::PRODUCTNAME) >>= sProductName;
+
+ if (sProductName.getLength ())
+ {
+ if (sTitle.getLength() > 0)
+ sTitle.appendAscii (" - ");
+
+ sTitle.append (sProductName);
+ }
+}
+
+//*****************************************************************************************************************
+void TitleHelper::impl_appendProductExtension (::rtl::OUStringBuffer& sTitle)
+{
+ ::rtl::OUString sProductExtension;
+ ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::PRODUCTEXTENSION) >>= sProductExtension;
+
+ if (sProductExtension.getLength ())
+ {
+ sTitle.appendAscii (" ");
+ sTitle.append (sProductExtension);
+ }
+}
+
+//*****************************************************************************************************************
+void TitleHelper::impl_appendModuleName (::rtl::OUStringBuffer& sTitle)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ css::uno::Reference< css::uno::XInterface > xOwner = m_xOwner.get();
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ try
+ {
+ css::uno::Reference< css::frame::XModuleManager > xModuleManager(
+ xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
+ css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::container::XNameAccess > xConfig(
+ xModuleManager,
+ css::uno::UNO_QUERY_THROW);
+
+ const ::rtl::OUString sID = xModuleManager->identify(xOwner);
+ ::comphelper::SequenceAsHashMap lProps = xConfig->getByName (sID);
+ const ::rtl::OUString sUIName = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_UINAME, ::rtl::OUString());
+
+ // An UIname property is an optional value !
+ // So please add it to the title in case it does realy exists only.
+ if (sUIName.getLength() > 0)
+ {
+ sTitle.appendAscii (" " );
+ sTitle.append (sUIName);
+ }
+ }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+//*****************************************************************************************************************
+#ifdef DBG_UTIL
+void TitleHelper::impl_appendDebugVersion (::rtl::OUStringBuffer& sTitle)
+{
+ ::rtl::OUString sDefault ;
+ ::rtl::OUString sVersion = ::utl::Bootstrap::getBuildIdData( sDefault );
+
+ sTitle.appendAscii (" [" );
+ sTitle.append (sVersion);
+ sTitle.appendAscii ("]" );
+}
+#else
+void TitleHelper::impl_appendDebugVersion (::rtl::OUStringBuffer&)
+{
+}
+#endif
+
+//-----------------------------------------------
+void TitleHelper::impl_startListeningForModel (const css::uno::Reference< css::frame::XModel >& xModel)
+{
+ css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xModel, css::uno::UNO_QUERY);
+ if ( ! xBroadcaster.is ())
+ return;
+
+ xBroadcaster->addEventListener (static_cast< css::document::XEventListener* >(this));
+}
+
+//-----------------------------------------------
+void TitleHelper::impl_startListeningForController (const css::uno::Reference< css::frame::XController >& xController)
+{
+ css::uno::Reference< css::frame::XTitle > xSubTitle(xController->getModel (), css::uno::UNO_QUERY);
+ impl_setSubTitle (xSubTitle);
+}
+
+//-----------------------------------------------
+void TitleHelper::impl_startListeningForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ xFrame->addFrameActionListener(this );
+ impl_updateListeningForFrame (xFrame);
+}
+
+//-----------------------------------------------
+void TitleHelper::impl_updateListeningForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ css::uno::Reference< css::frame::XTitle > xSubTitle(xFrame->getController (), css::uno::UNO_QUERY);
+ impl_setSubTitle (xSubTitle);
+}
+
+//-----------------------------------------------
+void TitleHelper::impl_setSubTitle (const css::uno::Reference< css::frame::XTitle >& xSubTitle)
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ // ignore duplicate calls. Makes outside using of this helper more easy :-)
+ css::uno::Reference< css::frame::XTitle > xOldSubTitle(m_xSubTitle.get(), css::uno::UNO_QUERY);
+ if (xOldSubTitle == xSubTitle)
+ return;
+
+ m_xSubTitle = xSubTitle;
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xOldBroadcaster(xOldSubTitle , css::uno::UNO_QUERY );
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xNewBroadcaster(xSubTitle , css::uno::UNO_QUERY );
+ css::uno::Reference< css::frame::XTitleChangeListener > xThis (static_cast< css::frame::XTitleChangeListener* >(this), css::uno::UNO_QUERY_THROW);
+
+ if (xOldBroadcaster.is())
+ xOldBroadcaster->removeTitleChangeListener (xThis);
+
+ if (xNewBroadcaster.is())
+ xNewBroadcaster->addTitleChangeListener (xThis);
+}
+
+//-----------------------------------------------
+::rtl::OUString TitleHelper::impl_getSubTitle ()
+{
+ // SYNCHRONIZED ->
+ ::osl::ResettableMutexGuard aLock(m_aMutex);
+
+ css::uno::Reference< css::frame::XTitle > xSubTitle(m_xSubTitle.get (), css::uno::UNO_QUERY);
+
+ aLock.clear ();
+ // <- SYNCHRONIZED
+
+ if (xSubTitle.is ())
+ return xSubTitle->getTitle ();
+
+ return ::rtl::OUString ();
+}
+
+//-----------------------------------------------
+::rtl::OUString TitleHelper::impl_convertURL2Title(const ::rtl::OUString& sURL)
+{
+ INetURLObject aURL (sURL);
+ ::rtl::OUString sTitle;
+
+ if (aURL.GetProtocol() == INET_PROT_FILE)
+ {
+ if (aURL.HasMark())
+ aURL = INetURLObject(aURL.GetURLNoMark());
+
+ sTitle = aURL.getName(INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::DECODE_WITH_CHARSET);
+ }
+ else
+ {
+ if (aURL.hasExtension(INetURLObject::LAST_SEGMENT))
+ sTitle = aURL.getName(INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::DECODE_WITH_CHARSET);
+
+ if ( ! sTitle.getLength() )
+ sTitle = aURL.GetHostPort(INetURLObject::DECODE_WITH_CHARSET);
+
+ if ( ! sTitle.getLength() )
+ sTitle = aURL.GetURLNoPass(INetURLObject::DECODE_WITH_CHARSET);
+ }
+
+ return sTitle;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/helper/undomanagerhelper.cxx b/framework/source/fwe/helper/undomanagerhelper.cxx
new file mode 100644
index 000000000000..891504adbe71
--- /dev/null
+++ b/framework/source/fwe/helper/undomanagerhelper.cxx
@@ -0,0 +1,1165 @@
+/*************************************************************************
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_framework.hxx"
+
+#include "framework/undomanagerhelper.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/lang/XComponent.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <comphelper/flagguard.hxx>
+#include <comphelper/asyncnotification.hxx>
+#include <svl/undo.hxx>
+#include <tools/diagnose_ex.h>
+#include <osl/conditn.hxx>
+
+#include <stack>
+#include <queue>
+#include <boost/function.hpp>
+
+//......................................................................................................................
+namespace framework
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::document::XUndoManagerListener;
+ using ::com::sun::star::document::UndoManagerEvent;
+ using ::com::sun::star::document::EmptyUndoStackException;
+ using ::com::sun::star::document::UndoContextNotClosedException;
+ using ::com::sun::star::document::UndoFailedException;
+ using ::com::sun::star::util::NotLockedException;
+ using ::com::sun::star::lang::EventObject;
+ using ::com::sun::star::document::XUndoAction;
+ using ::com::sun::star::lang::XComponent;
+ using ::com::sun::star::document::XUndoManager;
+ using ::com::sun::star::util::InvalidStateException;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::util::XModifyListener;
+ /** === end UNO using === **/
+ using ::svl::IUndoManager;
+
+ //==================================================================================================================
+ //= UndoActionWrapper
+ //==================================================================================================================
+ class UndoActionWrapper : public SfxUndoAction
+ {
+ public:
+ UndoActionWrapper(
+ Reference< XUndoAction > const& i_undoAction
+ );
+ virtual ~UndoActionWrapper();
+
+ virtual String GetComment() const;
+ virtual void Undo();
+ virtual void Redo();
+ virtual sal_Bool CanRepeat(SfxRepeatTarget&) const;
+
+ private:
+ const Reference< XUndoAction > m_xUndoAction;
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ UndoActionWrapper::UndoActionWrapper( Reference< XUndoAction > const& i_undoAction )
+ :SfxUndoAction()
+ ,m_xUndoAction( i_undoAction )
+ {
+ ENSURE_OR_THROW( m_xUndoAction.is(), "illegal undo action" );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ UndoActionWrapper::~UndoActionWrapper()
+ {
+ try
+ {
+ Reference< XComponent > xComponent( m_xUndoAction, UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ String UndoActionWrapper::GetComment() const
+ {
+ String sComment;
+ try
+ {
+ sComment = m_xUndoAction->getTitle();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return sComment;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoActionWrapper::Undo()
+ {
+ m_xUndoAction->undo();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoActionWrapper::Redo()
+ {
+ m_xUndoAction->redo();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Bool UndoActionWrapper::CanRepeat(SfxRepeatTarget&) const
+ {
+ return sal_False;
+ }
+
+ //==================================================================================================================
+ //= UndoManagerRequest
+ //==================================================================================================================
+ class UndoManagerRequest : public ::comphelper::AnyEvent
+ {
+ public:
+ UndoManagerRequest( ::boost::function0< void > const& i_request )
+ :m_request( i_request )
+ ,m_caughtException()
+ ,m_finishCondition()
+ {
+ m_finishCondition.reset();
+ }
+
+ void execute()
+ {
+ try
+ {
+ m_request();
+ }
+ catch( const Exception& )
+ {
+ m_caughtException = ::cppu::getCaughtException();
+ }
+ m_finishCondition.set();
+ }
+
+ void wait()
+ {
+ m_finishCondition.wait();
+ if ( m_caughtException.hasValue() )
+ ::cppu::throwException( m_caughtException );
+ }
+
+ void cancel( const Reference< XInterface >& i_context )
+ {
+ m_caughtException <<= RuntimeException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Concurrency error: an ealier operation on the stack failed." ) ),
+ i_context
+ );
+ m_finishCondition.set();
+ }
+
+ protected:
+ ~UndoManagerRequest()
+ {
+ }
+
+ private:
+ ::boost::function0< void > m_request;
+ Any m_caughtException;
+ ::osl::Condition m_finishCondition;
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+
+ //==================================================================================================================
+ //= UndoManagerHelper_Impl
+ //==================================================================================================================
+ class UndoManagerHelper_Impl : public SfxUndoListener
+ {
+ private:
+ ::osl::Mutex m_aMutex;
+ ::osl::Mutex m_aQueueMutex;
+ bool m_disposed;
+ bool m_bAPIActionRunning;
+ bool m_bProcessingEvents;
+ ::cppu::OInterfaceContainerHelper m_aUndoListeners;
+ ::cppu::OInterfaceContainerHelper m_aModifyListeners;
+ IUndoManagerImplementation& m_rUndoManagerImplementation;
+ UndoManagerHelper& m_rAntiImpl;
+ ::std::stack< bool > m_aContextVisibilities;
+#if OSL_DEBUG_LEVEL > 0
+ ::std::stack< bool > m_aContextAPIFlags;
+#endif
+ ::std::queue< ::rtl::Reference< UndoManagerRequest > >
+ m_aEventQueue;
+
+ public:
+ ::osl::Mutex& getMutex() { return m_aMutex; }
+
+ public:
+ UndoManagerHelper_Impl( UndoManagerHelper& i_antiImpl, IUndoManagerImplementation& i_undoManagerImpl )
+ :m_aMutex()
+ ,m_aQueueMutex()
+ ,m_disposed( false )
+ ,m_bAPIActionRunning( false )
+ ,m_bProcessingEvents( false )
+ ,m_aUndoListeners( m_aMutex )
+ ,m_aModifyListeners( m_aMutex )
+ ,m_rUndoManagerImplementation( i_undoManagerImpl )
+ ,m_rAntiImpl( i_antiImpl )
+ {
+ getUndoManager().AddUndoListener( *this );
+ }
+
+ virtual ~UndoManagerHelper_Impl()
+ {
+ }
+
+ //..............................................................................................................
+ IUndoManager& getUndoManager() const
+ {
+ return m_rUndoManagerImplementation.getImplUndoManager();
+ }
+
+ //..............................................................................................................
+ Reference< XUndoManager > getXUndoManager() const
+ {
+ return m_rUndoManagerImplementation.getThis();
+ }
+
+ // SfxUndoListener
+ virtual void actionUndone( const String& i_actionComment );
+ virtual void actionRedone( const String& i_actionComment );
+ virtual void undoActionAdded( const String& i_actionComment );
+ virtual void cleared();
+ virtual void clearedRedo();
+ virtual void resetAll();
+ virtual void listActionEntered( const String& i_comment );
+ virtual void listActionLeft( const String& i_comment );
+ virtual void listActionLeftAndMerged();
+ virtual void listActionCancelled();
+ virtual void undoManagerDying();
+
+ // public operations
+ void disposing();
+
+ void enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden, IMutexGuard& i_instanceLock );
+ void leaveUndoContext( IMutexGuard& i_instanceLock );
+ void addUndoAction( const Reference< XUndoAction >& i_action, IMutexGuard& i_instanceLock );
+ void undo( IMutexGuard& i_instanceLock );
+ void redo( IMutexGuard& i_instanceLock );
+ void clear( IMutexGuard& i_instanceLock );
+ void clearRedo( IMutexGuard& i_instanceLock );
+ void reset( IMutexGuard& i_instanceLock );
+
+ void addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
+ {
+ m_aUndoListeners.addInterface( i_listener );
+ }
+
+ void removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
+ {
+ m_aUndoListeners.removeInterface( i_listener );
+ }
+
+ void addModifyListener( const Reference< XModifyListener >& i_listener )
+ {
+ m_aModifyListeners.addInterface( i_listener );
+ }
+
+ void removeModifyListener( const Reference< XModifyListener >& i_listener )
+ {
+ m_aModifyListeners.removeInterface( i_listener );
+ }
+
+ UndoManagerEvent
+ buildEvent( ::rtl::OUString const& i_title ) const;
+
+ void impl_notifyModified();
+ void notify( ::rtl::OUString const& i_title,
+ void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& )
+ );
+ void notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& ) )
+ {
+ notify( ::rtl::OUString(), i_notificationMethod );
+ }
+
+ void notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const EventObject& ) );
+
+ private:
+ /// adds a function to be called to the request processor's queue
+ void impl_processRequest( ::boost::function0< void > const& i_request, IMutexGuard& i_instanceLock );
+
+ /// impl-versions of the XUndoManager API.
+ void impl_enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden );
+ void impl_leaveUndoContext();
+ void impl_addUndoAction( const Reference< XUndoAction >& i_action );
+ void impl_doUndoRedo( IMutexGuard& i_externalLock, const bool i_undo );
+ void impl_clear();
+ void impl_clearRedo();
+ void impl_reset();
+ };
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::disposing()
+ {
+ EventObject aEvent;
+ aEvent.Source = getXUndoManager();
+ m_aUndoListeners.disposeAndClear( aEvent );
+ m_aModifyListeners.disposeAndClear( aEvent );
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ getUndoManager().RemoveUndoListener( *this );
+
+ m_disposed = true;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ UndoManagerEvent UndoManagerHelper_Impl::buildEvent( ::rtl::OUString const& i_title ) const
+ {
+ UndoManagerEvent aEvent;
+ aEvent.Source = getXUndoManager();
+ aEvent.UndoActionTitle = i_title;
+ aEvent.UndoContextDepth = getUndoManager().GetListActionDepth();
+ return aEvent;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_notifyModified()
+ {
+ const EventObject aEvent( getXUndoManager() );
+ m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvent );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::notify( ::rtl::OUString const& i_title,
+ void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const UndoManagerEvent& ) )
+ {
+ const UndoManagerEvent aEvent( buildEvent( i_title ) );
+
+ // TODO: this notification method here is used by UndoManagerHelper_Impl, to multiplex the notifications we
+ // receive from the IUndoManager. Those notitications are sent with a locked SolarMutex, which means
+ // we're doing the multiplexing here with a locked SM, too. Which is Bad (TM).
+ // Fixing this properly would require outsourcing all the notifications into an own thread - which might lead
+ // to problems of its own, since clients might expect synchronous notifications.
+
+ m_aUndoListeners.notifyEach( i_notificationMethod, aEvent );
+ impl_notifyModified();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::notify( void ( SAL_CALL XUndoManagerListener::*i_notificationMethod )( const EventObject& ) )
+ {
+ const EventObject aEvent( getXUndoManager() );
+
+ // TODO: the same comment as in the other notify, regarding SM locking applies here ...
+
+ m_aUndoListeners.notifyEach( i_notificationMethod, aEvent );
+ impl_notifyModified();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden, IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_enterUndoContext,
+ this,
+ ::boost::cref( i_title ),
+ i_hidden
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::leaveUndoContext( IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_leaveUndoContext,
+ this
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::addUndoAction( const Reference< XUndoAction >& i_action, IMutexGuard& i_instanceLock )
+ {
+ if ( !i_action.is() )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal undo action object" ) ),
+ getXUndoManager(),
+ 1
+ );
+
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_addUndoAction,
+ this,
+ ::boost::ref( i_action )
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::clear( IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_clear,
+ this
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::clearRedo( IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_clearRedo,
+ this
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::reset( IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_reset,
+ this
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_processRequest( ::boost::function0< void > const& i_request, IMutexGuard& i_instanceLock )
+ {
+ // create the request, and add it to our queue
+ ::rtl::Reference< UndoManagerRequest > pRequest( new UndoManagerRequest( i_request ) );
+ {
+ ::osl::MutexGuard aQueueGuard( m_aQueueMutex );
+ m_aEventQueue.push( pRequest );
+ }
+
+ i_instanceLock.clear();
+
+ if ( m_bProcessingEvents )
+ {
+ // another thread is processing the event queue currently => it will also process the event which we just added
+ pRequest->wait();
+ return;
+ }
+
+ m_bProcessingEvents = true;
+ do
+ {
+ pRequest.clear();
+ {
+ ::osl::MutexGuard aQueueGuard( m_aQueueMutex );
+ if ( m_aEventQueue.empty() )
+ {
+ // reset the flag before releasing the queue mutex, otherwise it's possible that another thread
+ // could add an event after we release the mutex, but before we reset the flag. If then this other
+ // thread checks the flag before be reset it, this thread's event would starve.
+ m_bProcessingEvents = false;
+ return;
+ }
+ pRequest = m_aEventQueue.front();
+ m_aEventQueue.pop();
+ }
+ try
+ {
+ pRequest->execute();
+ pRequest->wait();
+ }
+ catch( ... )
+ {
+ {
+ // no chance to process further requests, if the current one failed
+ // => discard them
+ ::osl::MutexGuard aQueueGuard( m_aQueueMutex );
+ while ( !m_aEventQueue.empty() )
+ {
+ pRequest = m_aEventQueue.front();
+ m_aEventQueue.pop();
+ pRequest->cancel( getXUndoManager() );
+ }
+ m_bProcessingEvents = false;
+ }
+ // re-throw the error
+ throw;
+ }
+ }
+ while ( true );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_enterUndoContext( const ::rtl::OUString& i_title, const bool i_hidden )
+ {
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ if ( !rUndoManager.IsUndoEnabled() )
+ // ignore this request if the manager is locked
+ return;
+
+ if ( i_hidden && ( rUndoManager.GetUndoActionCount( IUndoManager::CurrentLevel ) == 0 ) )
+ throw EmptyUndoStackException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "can't enter a hidden context without a previous Undo action" ) ),
+ m_rUndoManagerImplementation.getThis()
+ );
+
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ rUndoManager.EnterListAction( i_title, ::rtl::OUString() );
+ }
+
+ m_aContextVisibilities.push( i_hidden );
+
+ const UndoManagerEvent aEvent( buildEvent( i_title ) );
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( i_hidden ? &XUndoManagerListener::enteredHiddenContext : &XUndoManagerListener::enteredContext, aEvent );
+ impl_notifyModified();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_leaveUndoContext()
+ {
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ if ( !rUndoManager.IsUndoEnabled() )
+ // ignore this request if the manager is locked
+ return;
+
+ if ( !rUndoManager.IsInListAction() )
+ throw InvalidStateException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no active undo context" ) ),
+ getXUndoManager()
+ );
+
+ size_t nContextElements = 0;
+
+ const bool isHiddenContext = m_aContextVisibilities.top();;
+ m_aContextVisibilities.pop();
+
+ const bool bHadRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::TopLevel ) > 0 );
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ if ( isHiddenContext )
+ nContextElements = rUndoManager.LeaveAndMergeListAction();
+ else
+ nContextElements = rUndoManager.LeaveListAction();
+ }
+ const bool bHasRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::TopLevel ) > 0 );
+
+ // prepare notification
+ void ( SAL_CALL XUndoManagerListener::*notificationMethod )( const UndoManagerEvent& ) = NULL;
+
+ UndoManagerEvent aContextEvent( buildEvent( ::rtl::OUString() ) );
+ const EventObject aClearedEvent( getXUndoManager() );
+ if ( nContextElements == 0 )
+ {
+ notificationMethod = &XUndoManagerListener::cancelledContext;
+ }
+ else if ( isHiddenContext )
+ {
+ notificationMethod = &XUndoManagerListener::leftHiddenContext;
+ }
+ else
+ {
+ aContextEvent.UndoActionTitle = rUndoManager.GetUndoActionComment( 0, IUndoManager::CurrentLevel );
+ notificationMethod = &XUndoManagerListener::leftContext;
+ }
+
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ if ( bHadRedoActions && !bHasRedoActions )
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared, aClearedEvent );
+ m_aUndoListeners.notifyEach( notificationMethod, aContextEvent );
+ impl_notifyModified();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_doUndoRedo( IMutexGuard& i_externalLock, const bool i_undo )
+ {
+ ::osl::Guard< ::framework::IMutex > aExternalGuard( i_externalLock.getGuardedMutex() );
+ // note that this assumes that the mutex has been released in the thread which added the
+ // Undo/Redo request, so we can successfully acquire it
+
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ if ( rUndoManager.IsInListAction() )
+ throw UndoContextNotClosedException( ::rtl::OUString(), getXUndoManager() );
+
+ const size_t nElements = i_undo
+ ? rUndoManager.GetUndoActionCount( IUndoManager::TopLevel )
+ : rUndoManager.GetRedoActionCount( IUndoManager::TopLevel );
+ if ( nElements == 0 )
+ throw EmptyUndoStackException( ::rtl::OUString::createFromAscii( "stack is empty" ), getXUndoManager() );
+
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ try
+ {
+ if ( i_undo )
+ rUndoManager.Undo();
+ else
+ rUndoManager.Redo();
+ }
+ catch( const RuntimeException& ) { /* allowed to leave here */ throw; }
+ catch( const UndoFailedException& ) { /* allowed to leave here */ throw; }
+ catch( const Exception& )
+ {
+ // not allowed to leave
+ const Any aError( ::cppu::getCaughtException() );
+ throw UndoFailedException( ::rtl::OUString(), getXUndoManager(), aError );
+ }
+
+ // note that in opposite to all of the other methods, we do *not* have our mutex locked when calling
+ // into the IUndoManager implementation. This ensures that an actual XUndoAction::undo/redo is also
+ // called without our mutex being locked.
+ // As a consequence, we do not set m_bAPIActionRunning here. Instead, our actionUndone/actionRedone methods
+ // *always* multiplex the event to our XUndoManagerListeners, not only when m_bAPIActionRunning is FALSE (This
+ // again is different from all other SfxUndoListener methods).
+ // So, we do not need to do this notification here ourself.
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_addUndoAction( const Reference< XUndoAction >& i_action )
+ {
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ if ( !rUndoManager.IsUndoEnabled() )
+ // ignore the request if the manager is locked
+ return;
+
+ const UndoManagerEvent aEventAdd( buildEvent( i_action->getTitle() ) );
+ const EventObject aEventClear( getXUndoManager() );
+
+ const bool bHadRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::CurrentLevel ) > 0 );
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ rUndoManager.AddUndoAction( new UndoActionWrapper( i_action ) );
+ }
+ const bool bHasRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::CurrentLevel ) > 0 );
+
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::undoActionAdded, aEventAdd );
+ if ( bHadRedoActions && !bHasRedoActions )
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared, aEventClear );
+ impl_notifyModified();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_clear()
+ {
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ if ( rUndoManager.IsInListAction() )
+ throw UndoContextNotClosedException( ::rtl::OUString(), getXUndoManager() );
+
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ rUndoManager.Clear();
+ }
+
+ const EventObject aEvent( getXUndoManager() );
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::allActionsCleared, aEvent );
+ impl_notifyModified();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_clearRedo()
+ {
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ if ( rUndoManager.IsInListAction() )
+ throw UndoContextNotClosedException( ::rtl::OUString(), getXUndoManager() );
+
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ rUndoManager.ClearRedo();
+ }
+
+ const EventObject aEvent( getXUndoManager() );
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared, aEvent );
+ impl_notifyModified();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::impl_reset()
+ {
+ // SYNCHRONIZED --->
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ IUndoManager& rUndoManager = getUndoManager();
+ {
+ ::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
+ rUndoManager.Reset();
+ }
+
+ const EventObject aEvent( getXUndoManager() );
+ aGuard.clear();
+ // <--- SYNCHRONIZED
+
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::resetAll, aEvent );
+ impl_notifyModified();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::actionUndone( const String& i_actionComment )
+ {
+ UndoManagerEvent aEvent;
+ aEvent.Source = getXUndoManager();
+ aEvent.UndoActionTitle = i_actionComment;
+ aEvent.UndoContextDepth = 0; // Undo can happen on level 0 only
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::actionUndone, aEvent );
+ impl_notifyModified();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::actionRedone( const String& i_actionComment )
+ {
+ UndoManagerEvent aEvent;
+ aEvent.Source = getXUndoManager();
+ aEvent.UndoActionTitle = i_actionComment;
+ aEvent.UndoContextDepth = 0; // Redo can happen on level 0 only
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::actionRedone, aEvent );
+ impl_notifyModified();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::undoActionAdded( const String& i_actionComment )
+ {
+ if ( m_bAPIActionRunning )
+ return;
+
+ notify( i_actionComment, &XUndoManagerListener::undoActionAdded );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::cleared()
+ {
+ if ( m_bAPIActionRunning )
+ return;
+
+ notify( &XUndoManagerListener::allActionsCleared );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::clearedRedo()
+ {
+ if ( m_bAPIActionRunning )
+ return;
+
+ notify( &XUndoManagerListener::redoActionsCleared );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::resetAll()
+ {
+ if ( m_bAPIActionRunning )
+ return;
+
+ notify( &XUndoManagerListener::resetAll );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::listActionEntered( const String& i_comment )
+ {
+#if OSL_DEBUG_LEVEL > 0
+ m_aContextAPIFlags.push( m_bAPIActionRunning );
+#endif
+
+ if ( m_bAPIActionRunning )
+ return;
+
+ notify( i_comment, &XUndoManagerListener::enteredContext );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::listActionLeft( const String& i_comment )
+ {
+#if OSL_DEBUG_LEVEL > 0
+ const bool bCurrentContextIsAPIContext = m_aContextAPIFlags.top();
+ m_aContextAPIFlags.pop();
+ OSL_ENSURE( bCurrentContextIsAPIContext == m_bAPIActionRunning, "UndoManagerHelper_Impl::listActionLeft: API and non-API contexts interwoven!" );
+#endif
+
+ if ( m_bAPIActionRunning )
+ return;
+
+ notify( i_comment, &XUndoManagerListener::leftContext );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::listActionLeftAndMerged()
+ {
+#if OSL_DEBUG_LEVEL > 0
+ const bool bCurrentContextIsAPIContext = m_aContextAPIFlags.top();
+ m_aContextAPIFlags.pop();
+ OSL_ENSURE( bCurrentContextIsAPIContext == m_bAPIActionRunning, "UndoManagerHelper_Impl::listActionLeftAndMerged: API and non-API contexts interwoven!" );
+#endif
+
+ if ( m_bAPIActionRunning )
+ return;
+
+ notify( &XUndoManagerListener::leftHiddenContext );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::listActionCancelled()
+ {
+#if OSL_DEBUG_LEVEL > 0
+ const bool bCurrentContextIsAPIContext = m_aContextAPIFlags.top();
+ m_aContextAPIFlags.pop();
+ OSL_ENSURE( bCurrentContextIsAPIContext == m_bAPIActionRunning, "UndoManagerHelper_Impl::listActionCancelled: API and non-API contexts interwoven!" );
+#endif
+
+ if ( m_bAPIActionRunning )
+ return;
+
+ notify( &XUndoManagerListener::cancelledContext );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::undoManagerDying()
+ {
+ // TODO: do we need to care? Or is this the responsibility of our owner?
+ }
+
+ //==================================================================================================================
+ //= UndoManagerHelper
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ UndoManagerHelper::UndoManagerHelper( IUndoManagerImplementation& i_undoManagerImpl )
+ :m_pImpl( new UndoManagerHelper_Impl( *this, i_undoManagerImpl ) )
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ UndoManagerHelper::~UndoManagerHelper()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::disposing()
+ {
+ m_pImpl->disposing();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::enterUndoContext( const ::rtl::OUString& i_title, IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->enterUndoContext( i_title, false, i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::enterHiddenUndoContext( IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->enterUndoContext( ::rtl::OUString(), true, i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::leaveUndoContext( IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->leaveUndoContext( i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::undo( IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_doUndoRedo,
+ this,
+ ::boost::ref( i_instanceLock ),
+ true
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper_Impl::redo( IMutexGuard& i_instanceLock )
+ {
+ impl_processRequest(
+ ::boost::bind(
+ &UndoManagerHelper_Impl::impl_doUndoRedo,
+ this,
+ ::boost::ref( i_instanceLock ),
+ false
+ ),
+ i_instanceLock
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::addUndoAction( const Reference< XUndoAction >& i_action, IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->addUndoAction( i_action, i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::undo( IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->undo( i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::redo( IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->redo( i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Bool UndoManagerHelper::isUndoPossible() const
+ {
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( m_pImpl->getMutex() );
+ IUndoManager& rUndoManager = m_pImpl->getUndoManager();
+ if ( rUndoManager.IsInListAction() )
+ return sal_False;
+ return rUndoManager.GetUndoActionCount( IUndoManager::TopLevel ) > 0;
+ // <--- SYNCHRONIZED
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Bool UndoManagerHelper::isRedoPossible() const
+ {
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( m_pImpl->getMutex() );
+ const IUndoManager& rUndoManager = m_pImpl->getUndoManager();
+ if ( rUndoManager.IsInListAction() )
+ return sal_False;
+ return rUndoManager.GetRedoActionCount( IUndoManager::TopLevel ) > 0;
+ // <--- SYNCHRONIZED
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ namespace
+ {
+ //..............................................................................................................
+ ::rtl::OUString lcl_getCurrentActionTitle( UndoManagerHelper_Impl& i_impl, const bool i_undo )
+ {
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( i_impl.getMutex() );
+
+ const IUndoManager& rUndoManager = i_impl.getUndoManager();
+ const size_t nActionCount = i_undo
+ ? rUndoManager.GetUndoActionCount( IUndoManager::TopLevel )
+ : rUndoManager.GetRedoActionCount( IUndoManager::TopLevel );
+ if ( nActionCount == 0 )
+ throw EmptyUndoStackException(
+ i_undo ? ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no action on the undo stack" ) )
+ : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no action on the redo stack" ) ),
+ i_impl.getXUndoManager()
+ );
+ return i_undo
+ ? rUndoManager.GetUndoActionComment( 0, IUndoManager::TopLevel )
+ : rUndoManager.GetRedoActionComment( 0, IUndoManager::TopLevel );
+ // <--- SYNCHRONIZED
+ }
+
+ //..............................................................................................................
+ Sequence< ::rtl::OUString > lcl_getAllActionTitles( UndoManagerHelper_Impl& i_impl, const bool i_undo )
+ {
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( i_impl.getMutex() );
+
+ const IUndoManager& rUndoManager = i_impl.getUndoManager();
+ const size_t nCount = i_undo
+ ? rUndoManager.GetUndoActionCount( IUndoManager::TopLevel )
+ : rUndoManager.GetRedoActionCount( IUndoManager::TopLevel );
+
+ Sequence< ::rtl::OUString > aTitles( nCount );
+ for ( size_t i=0; i<nCount; ++i )
+ {
+ aTitles[i] = i_undo
+ ? rUndoManager.GetUndoActionComment( i, IUndoManager::TopLevel )
+ : rUndoManager.GetRedoActionComment( i, IUndoManager::TopLevel );
+ }
+ return aTitles;
+ // <--- SYNCHRONIZED
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString UndoManagerHelper::getCurrentUndoActionTitle() const
+ {
+ return lcl_getCurrentActionTitle( *m_pImpl, true );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString UndoManagerHelper::getCurrentRedoActionTitle() const
+ {
+ return lcl_getCurrentActionTitle( *m_pImpl, false );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Sequence< ::rtl::OUString > UndoManagerHelper::getAllUndoActionTitles() const
+ {
+ return lcl_getAllActionTitles( *m_pImpl, true );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Sequence< ::rtl::OUString > UndoManagerHelper::getAllRedoActionTitles() const
+ {
+ return lcl_getAllActionTitles( *m_pImpl, false );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::clear( IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->clear( i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::clearRedo( IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->clearRedo( i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::reset( IMutexGuard& i_instanceLock )
+ {
+ m_pImpl->reset( i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::lock()
+ {
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( m_pImpl->getMutex() );
+
+ IUndoManager& rUndoManager = m_pImpl->getUndoManager();
+ rUndoManager.EnableUndo( false );
+ // <--- SYNCHRONIZED
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::unlock()
+ {
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( m_pImpl->getMutex() );
+
+ IUndoManager& rUndoManager = m_pImpl->getUndoManager();
+ if ( rUndoManager.IsUndoEnabled() )
+ throw NotLockedException( ::rtl::OUString::createFromAscii( "Undo manager is not locked" ), m_pImpl->getXUndoManager() );
+ rUndoManager.EnableUndo( true );
+ // <--- SYNCHRONIZED
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Bool UndoManagerHelper::isLocked()
+ {
+ // SYNCHRONIZED --->
+ ::osl::MutexGuard aGuard( m_pImpl->getMutex() );
+
+ IUndoManager& rUndoManager = m_pImpl->getUndoManager();
+ return !rUndoManager.IsUndoEnabled();
+ // <--- SYNCHRONIZED
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
+ {
+ if ( i_listener.is() )
+ m_pImpl->addUndoManagerListener( i_listener );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
+ {
+ if ( i_listener.is() )
+ m_pImpl->removeUndoManagerListener( i_listener );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::addModifyListener( const Reference< XModifyListener >& i_listener )
+ {
+ if ( i_listener.is() )
+ m_pImpl->addModifyListener( i_listener );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void UndoManagerHelper::removeModifyListener( const Reference< XModifyListener >& i_listener )
+ {
+ if ( i_listener.is() )
+ m_pImpl->removeModifyListener( i_listener );
+ }
+
+//......................................................................................................................
+} // namespace framework
+//......................................................................................................................
diff --git a/framework/source/fwe/interaction/preventduplicateinteraction.cxx b/framework/source/fwe/interaction/preventduplicateinteraction.cxx
new file mode 100644
index 000000000000..c708502f19eb
--- /dev/null
+++ b/framework/source/fwe/interaction/preventduplicateinteraction.cxx
@@ -0,0 +1,297 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "framework/preventduplicateinteraction.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/task/XInteractionRetry.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+namespace css = ::com::sun::star;
+
+//_________________________________________________________________________________________________________________
+// exported const
+//_________________________________________________________________________________________________________________
+
+#define IMPLEMENTATIONNAME_UIINTERACTIONHANDLER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.uui.UUIInteractionHandler"))
+
+//_________________________________________________________________________________________________________________
+// exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+
+PreventDuplicateInteraction::PreventDuplicateInteraction(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase2()
+ , m_xSMGR(xSMGR)
+{
+}
+
+//_________________________________________________________________________________________________________________
+
+PreventDuplicateInteraction::~PreventDuplicateInteraction()
+{
+}
+
+//_________________________________________________________________________________________________________________
+
+void PreventDuplicateInteraction::setHandler(const css::uno::Reference< css::task::XInteractionHandler >& xHandler)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ m_xHandler = xHandler;
+ aLock.clear();
+ // <- SAFE
+}
+
+//_________________________________________________________________________________________________________________
+
+void PreventDuplicateInteraction::useDefaultUUIHandler()
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aLock.clear();
+ // <- SAFE
+
+ css::uno::Reference< css::task::XInteractionHandler > xHandler(
+ xSMGR->createInstance(IMPLEMENTATIONNAME_UIINTERACTIONHANDLER),
+ css::uno::UNO_QUERY_THROW);
+
+ // SAFE ->
+ aLock.reset();
+ m_xHandler = xHandler;
+ aLock.clear();
+ // <- SAFE
+}
+
+//_________________________________________________________________________________________________________________
+css::uno::Any SAL_CALL PreventDuplicateInteraction::queryInterface( const css::uno::Type& aType )
+ throw (css::uno::RuntimeException)
+{
+ if ( aType.equals( XInteractionHandler2::static_type() ) )
+ {
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::task::XInteractionHandler2 > xHandler( m_xHandler, css::uno::UNO_QUERY );
+ if ( !xHandler.is() )
+ return css::uno::Any();
+ }
+ return ::cppu::WeakImplHelper1< css::task::XInteractionHandler2 >::queryInterface( aType );
+}
+
+//_________________________________________________________________________________________________________________
+
+void SAL_CALL PreventDuplicateInteraction::handle(const css::uno::Reference< css::task::XInteractionRequest >& xRequest)
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Any aRequest = xRequest->getRequest();
+ sal_Bool bHandleIt = sal_True;
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ InteractionList::iterator pIt;
+ for ( pIt = m_lInteractionRules.begin();
+ pIt != m_lInteractionRules.end() ;
+ ++pIt )
+ {
+ InteractionInfo& rInfo = *pIt;
+
+ if (aRequest.isExtractableTo(rInfo.m_aInteraction))
+ {
+ ++rInfo.m_nCallCount;
+ rInfo.m_xRequest = xRequest;
+ bHandleIt = (rInfo.m_nCallCount <= rInfo.m_nMaxCount);
+ break;
+ }
+ }
+
+ css::uno::Reference< css::task::XInteractionHandler > xHandler = m_xHandler;
+
+ aLock.clear();
+ // <- SAFE
+
+ if (
+ (bHandleIt ) &&
+ (xHandler.is())
+ )
+ {
+ xHandler->handle(xRequest);
+ }
+ else
+ {
+ const css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations = xRequest->getContinuations();
+ sal_Int32 c = lContinuations.getLength();
+ sal_Int32 i = 0;
+ for (i=0; i<c; ++i)
+ {
+ css::uno::Reference< css::task::XInteractionAbort > xAbort(lContinuations[i], css::uno::UNO_QUERY);
+ if (xAbort.is())
+ {
+ xAbort->select();
+ break;
+ }
+ }
+ }
+}
+
+//_________________________________________________________________________________________________________________
+
+::sal_Bool SAL_CALL PreventDuplicateInteraction::handleInteractionRequest( const css::uno::Reference< css::task::XInteractionRequest >& xRequest )
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Any aRequest = xRequest->getRequest();
+ sal_Bool bHandleIt = sal_True;
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ InteractionList::iterator pIt;
+ for ( pIt = m_lInteractionRules.begin();
+ pIt != m_lInteractionRules.end() ;
+ ++pIt )
+ {
+ InteractionInfo& rInfo = *pIt;
+
+ if (aRequest.isExtractableTo(rInfo.m_aInteraction))
+ {
+ ++rInfo.m_nCallCount;
+ rInfo.m_xRequest = xRequest;
+ bHandleIt = (rInfo.m_nCallCount <= rInfo.m_nMaxCount);
+ break;
+ }
+ }
+
+ css::uno::Reference< css::task::XInteractionHandler2 > xHandler( m_xHandler, css::uno::UNO_QUERY );
+ OSL_ENSURE( xHandler.is() || !m_xHandler.is(),
+ "PreventDuplicateInteraction::handleInteractionRequest: inconsistency!" );
+
+ aLock.clear();
+ // <- SAFE
+
+ if (
+ (bHandleIt ) &&
+ (xHandler.is())
+ )
+ {
+ return xHandler->handleInteractionRequest(xRequest);
+ }
+ else
+ {
+ const css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations = xRequest->getContinuations();
+ sal_Int32 c = lContinuations.getLength();
+ sal_Int32 i = 0;
+ for (i=0; i<c; ++i)
+ {
+ css::uno::Reference< css::task::XInteractionAbort > xAbort(lContinuations[i], css::uno::UNO_QUERY);
+ if (xAbort.is())
+ {
+ xAbort->select();
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+//_________________________________________________________________________________________________________________
+
+void PreventDuplicateInteraction::addInteractionRule(const PreventDuplicateInteraction::InteractionInfo& aInteractionInfo)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ InteractionList::iterator pIt;
+ for ( pIt = m_lInteractionRules.begin();
+ pIt != m_lInteractionRules.end() ;
+ ++pIt )
+ {
+ InteractionInfo& rInfo = *pIt;
+ if (rInfo.m_aInteraction == aInteractionInfo.m_aInteraction)
+ {
+ rInfo.m_nMaxCount = aInteractionInfo.m_nMaxCount ;
+ rInfo.m_nCallCount = aInteractionInfo.m_nCallCount;
+ return;
+ }
+ }
+
+ m_lInteractionRules.push_back(aInteractionInfo);
+
+ aLock.clear();
+ // <- SAFE
+}
+
+//_________________________________________________________________________________________________________________
+
+sal_Bool PreventDuplicateInteraction::getInteractionInfo(const css::uno::Type& aInteraction,
+ PreventDuplicateInteraction::InteractionInfo* pReturn ) const
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+
+ PreventDuplicateInteraction::InteractionList::const_iterator pIt;
+ for ( pIt = m_lInteractionRules.begin();
+ pIt != m_lInteractionRules.end() ;
+ ++pIt )
+ {
+ const PreventDuplicateInteraction::InteractionInfo& rInfo = *pIt;
+ if (rInfo.m_aInteraction == aInteraction)
+ {
+ *pReturn = rInfo;
+ return sal_True;
+ }
+ }
+
+ aLock.clear();
+ // <- SAFE
+
+ return sal_False;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/eventsconfiguration.cxx b/framework/source/fwe/xml/eventsconfiguration.cxx
new file mode 100644
index 000000000000..fd68b3a0ca0a
--- /dev/null
+++ b/framework/source/fwe/xml/eventsconfiguration.cxx
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <framework/eventsconfiguration.hxx>
+#include <xml/eventsdocumenthandler.hxx>
+#include <services.h>
+
+#include <xml/saxnamespacefilter.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <comphelper/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <tools/debug.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::io;
+
+
+namespace framework
+{
+
+static Reference< XParser > GetSaxParser(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory
+ )
+{
+ return Reference< XParser >( xServiceFactory->createInstance( SERVICENAME_SAXPARSER), UNO_QUERY);
+}
+
+static Reference< XDocumentHandler > GetSaxWriter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory
+ )
+{
+ return Reference< XDocumentHandler >( xServiceFactory->createInstance( SERVICENAME_SAXWRITER), UNO_QUERY) ;
+}
+
+
+sal_Bool EventsConfiguration::LoadEventsConfig(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ SvStream& rInStream, EventsConfig& aItems )
+{
+ Reference< XParser > xParser( GetSaxParser( xServiceFactory ) );
+ Reference< XInputStream > xInputStream(
+ (::cppu::OWeakObject *)new utl::OInputStreamWrapper( rInStream ),
+ UNO_QUERY );
+
+ // connect stream to input stream to the parser
+ InputSource aInputSource;
+
+ aInputSource.aInputStream = xInputStream;
+
+ // create namespace filter and set events document handler inside to support xml namespaces
+ Reference< XDocumentHandler > xDocHandler( new OReadEventsDocumentHandler( aItems ));
+ Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler ));
+
+ // connect parser and filter
+ xParser->setDocumentHandler( xFilter );
+
+ try
+ {
+ xParser->parseStream( aInputSource );
+ return sal_True;
+ }
+ catch ( RuntimeException& )
+ {
+ return sal_False;
+ }
+ catch( SAXException& )
+ {
+ return sal_False;
+ }
+ catch( ::com::sun::star::io::IOException& )
+ {
+ return sal_False;
+ }
+}
+
+
+sal_Bool EventsConfiguration::StoreEventsConfig(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ SvStream& rOutStream, const EventsConfig& aItems )
+{
+ Reference< XDocumentHandler > xWriter( GetSaxWriter( xServiceFactory ) );
+
+ Reference< XOutputStream > xOutputStream(
+ (::cppu::OWeakObject *)new utl::OOutputStreamWrapper( rOutStream ),
+ UNO_QUERY );
+
+ Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY );
+ xDataSource->setOutputStream( xOutputStream );
+
+ try
+ {
+ OWriteEventsDocumentHandler aWriteEventsDocumentHandler( aItems, xWriter );
+ aWriteEventsDocumentHandler.WriteEventsDocument();
+ return sal_True;
+ }
+ catch ( RuntimeException& )
+ {
+ return sal_False;
+ }
+ catch ( SAXException& )
+ {
+ return sal_False;
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ return sal_False;
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/eventsdocumenthandler.cxx b/framework/source/fwe/xml/eventsdocumenthandler.cxx
new file mode 100644
index 000000000000..31a4ff7e11dd
--- /dev/null
+++ b/framework/source/fwe/xml/eventsdocumenthandler.cxx
@@ -0,0 +1,553 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <framework/fwedllapi.h>
+#include <stdio.h>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <threadhelp/resetableguard.hxx>
+#include <xml/eventsdocumenthandler.hxx>
+#include <macros/debug.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <sal/config.h>
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+
+#include <comphelper/attributelist.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::xml::sax;
+
+
+#define XMLNS_EVENT "http://openoffice.org/2001/event"
+#define XMLNS_XLINK "http://www.w3.org/1999/xlink"
+#define XMLNS_EVENT_PREFIX "event:"
+#define XMLNS_XLINK_PREFIX "xlink:"
+
+#define ATTRIBUTE_XMLNS_EVENT "xmlns:event"
+#define ATTRIBUTE_XMLNS_XLINK "xmlns:xlink"
+
+#define XMLNS_FILTER_SEPARATOR "^"
+
+#define ELEMENT_EVENTS "events"
+#define ELEMENT_EVENT "event"
+
+#define ATTRIBUTE_LANGUAGE "language"
+#define ATTRIBUTE_LIBRARY "library"
+#define ATTRIBUTE_NAME "name"
+#define ATTRIBUTE_HREF "href"
+#define ATTRIBUTE_TYPE "type"
+#define ATTRIBUTE_MACRONAME "macro-name"
+
+#define ELEMENT_NS_EVENTS "event:events"
+#define ELEMENT_NS_EVENT "event:event"
+
+#define ATTRIBUTE_TYPE_CDATA "CDATA"
+
+#define EVENTS_DOCTYPE "<!DOCTYPE event:events PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"event.dtd\">"
+
+// Property names for events
+#define PROP_EVENT_TYPE "EventType"
+#define PROP_LIBRARY "Library"
+#define PROP_SCRIPT "Script"
+#define PROP_MACRO_NAME "MacroName"
+#define STAR_BASIC "StarBasic"
+#define JAVA_SCRIPT "JavaScript"
+
+
+namespace framework
+{
+
+struct EventEntryProperty
+{
+ OReadEventsDocumentHandler::Event_XML_Namespace nNamespace;
+ char aEntryName[20];
+};
+
+static EventEntryProperty EventEntries[OReadEventsDocumentHandler::EV_XML_ENTRY_COUNT] =
+{
+ { OReadEventsDocumentHandler::EV_NS_EVENT, ELEMENT_EVENTS },
+ { OReadEventsDocumentHandler::EV_NS_EVENT, ELEMENT_EVENT },
+ { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_LANGUAGE },
+ { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_NAME },
+ { OReadEventsDocumentHandler::EV_NS_XLINK, ATTRIBUTE_HREF },
+ { OReadEventsDocumentHandler::EV_NS_XLINK, ATTRIBUTE_TYPE },
+ { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_MACRONAME },
+ { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_LIBRARY }
+};
+
+
+OReadEventsDocumentHandler::OReadEventsDocumentHandler( EventsConfig& aItems ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_aEventItems( aItems )
+{
+ ::rtl::OUString aNamespaceEvent( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT ));
+ ::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK ));
+ ::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR ));
+
+ // create hash map
+ for ( int i = 0; i < (int)EV_XML_ENTRY_COUNT; i++ )
+ {
+ if ( EventEntries[i].nNamespace == EV_NS_EVENT )
+ {
+ ::rtl::OUString temp( aNamespaceEvent );
+ temp += aSeparator;
+ temp += ::rtl::OUString::createFromAscii( EventEntries[i].aEntryName );
+ m_aEventsMap.insert( EventsHashMap::value_type( temp, (Events_XML_Entry)i ) );
+ }
+ else
+ {
+ ::rtl::OUString temp( aNamespaceXLink );
+ temp += aSeparator;
+ temp += ::rtl::OUString::createFromAscii( EventEntries[i].aEntryName );
+ m_aEventsMap.insert( EventsHashMap::value_type( temp, (Events_XML_Entry)i ) );
+ }
+ }
+
+ m_bEventsStartFound = sal_False;
+ m_bEventsEndFound = sal_False;
+ m_bEventStartFound = sal_False;
+}
+
+OReadEventsDocumentHandler::~OReadEventsDocumentHandler()
+{
+}
+
+// XDocumentHandler
+void SAL_CALL OReadEventsDocumentHandler::startDocument(void)
+throw ( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadEventsDocumentHandler::endDocument(void)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if (( m_bEventsStartFound && !m_bEventsEndFound ) ||
+ ( !m_bEventsStartFound && m_bEventsEndFound ) )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'event:events' found!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+}
+
+void SAL_CALL OReadEventsDocumentHandler::startElement(
+ const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ EventsHashMap::const_iterator pEventEntry = m_aEventsMap.find( aName );
+ if ( pEventEntry != m_aEventsMap.end() )
+ {
+ switch ( pEventEntry->second )
+ {
+ case EV_ELEMENT_EVENTS:
+ {
+ if ( m_bEventsStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'event:events' cannot be embeded into 'event:events'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bEventsStartFound = sal_True;
+ }
+ break;
+
+ case EV_ELEMENT_EVENT:
+ {
+ if ( !m_bEventsStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'event:event' must be embeded into element 'event:events'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ if ( m_bEventStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element event:event is not a container!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ ::rtl::OUString aLanguage;
+ ::rtl::OUString aURL;
+ ::rtl::OUString aMacroName;
+ ::rtl::OUString aLibrary;
+ ::rtl::OUString aEventName;
+
+ m_bEventStartFound = sal_True;
+
+ long nIndex = m_aEventItems.aEventNames.getLength();
+ long nPropCount = 2; // every event config entry needs at least 2 properties
+ Sequence< PropertyValue > aEventProperties( nPropCount );
+
+ m_aEventItems.aEventNames.realloc( nIndex + 1 );
+
+ for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
+ {
+ pEventEntry = m_aEventsMap.find( xAttribs->getNameByIndex( n ) );
+ if ( pEventEntry != m_aEventsMap.end() )
+ {
+ switch ( pEventEntry->second )
+ {
+ case EV_ATTRIBUTE_TYPE:
+ {
+ aLanguage = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case EV_ATTRIBUTE_NAME:
+ {
+ aEventName = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case XL_ATTRIBUTE_HREF:
+ {
+ aURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case EV_ATTRIBUTE_MACRONAME:
+ {
+ aMacroName = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case EV_ATTRIBUTE_LIBRARY:
+ {
+ aLibrary = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ default:
+ break; // nothing to do
+ }
+ }
+ } // for
+
+ ::rtl::OUString aRequiredAttributeName;
+ if ( aLanguage.getLength() == 0 )
+ aRequiredAttributeName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE ));
+ else if ( aEventName.getLength() == 0 )
+ aRequiredAttributeName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NAME ));
+
+ // check for missing attribute values
+ if ( aRequiredAttributeName.getLength() > 0 )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute "));
+ aErrorMessage += aRequiredAttributeName;
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " must have a value!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ Any a;
+
+ // set properties
+ a <<= aLanguage;
+ aEventProperties[0].Value <<= a;
+ aEventProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_EVENT_TYPE ));
+
+ a <<= aMacroName;
+ aEventProperties[1].Value <<= a;
+ aEventProperties[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_MACRO_NAME ));
+
+ if ( aLibrary.getLength() > 0 )
+ {
+ ++nPropCount;
+ aEventProperties.realloc( nPropCount );
+ a <<= aLibrary;
+ aEventProperties[nPropCount-1].Value <<= a;
+ aEventProperties[nPropCount-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_LIBRARY ));
+ }
+
+ if ( aURL.getLength() > 0 )
+ {
+ ++nPropCount;
+ aEventProperties.realloc( nPropCount );
+ a <<= aURL;
+ aEventProperties[nPropCount-1].Value <<= a;
+ aEventProperties[nPropCount-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_SCRIPT ));
+ }
+
+ // set event name
+ m_aEventItems.aEventNames[ nIndex ] = aEventName;
+
+ m_aEventItems.aEventsProperties.realloc( nIndex + 1 );
+ a <<= aEventProperties;
+ m_aEventItems.aEventsProperties[ nIndex ] = a;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void SAL_CALL OReadEventsDocumentHandler::endElement(const ::rtl::OUString& aName)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ EventsHashMap::const_iterator pEventEntry = m_aEventsMap.find( aName );
+ if ( pEventEntry != m_aEventsMap.end() )
+ {
+ switch ( pEventEntry->second )
+ {
+ case EV_ELEMENT_EVENTS:
+ {
+ if ( !m_bEventsStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'event:events' found, but no start element" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bEventsStartFound = sal_False;
+ }
+ break;
+
+ case EV_ELEMENT_EVENT:
+ {
+ if ( !m_bEventStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'event:event' found, but no start element" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bEventStartFound = sal_False;
+ }
+ break;
+
+ default:
+ break; // impossible case
+ }
+ }
+}
+
+void SAL_CALL OReadEventsDocumentHandler::characters(const ::rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadEventsDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadEventsDocumentHandler::processingInstruction(
+ const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadEventsDocumentHandler::setDocumentLocator(
+ const Reference< XLocator > &xLocator)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ m_xLocator = xLocator;
+}
+
+::rtl::OUString OReadEventsDocumentHandler::getErrorLineString()
+{
+ ResetableGuard aGuard( m_aLock );
+
+ char buffer[32];
+
+ if ( m_xLocator.is() )
+ {
+ snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>(m_xLocator->getLineNumber() ));
+ return ::rtl::OUString::createFromAscii( buffer );
+ }
+ else
+ return ::rtl::OUString();
+}
+
+
+//_________________________________________________________________________________________________________________
+// OWriteEventsDocumentHandler
+//_________________________________________________________________________________________________________________
+
+OWriteEventsDocumentHandler::OWriteEventsDocumentHandler(
+ const EventsConfig& aItems,
+ Reference< XDocumentHandler > rWriteDocumentHandler ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_aItems( aItems ),
+ m_xWriteDocumentHandler( rWriteDocumentHandler )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
+ m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
+ m_aXMLXlinkNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
+ m_aXMLEventNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT_PREFIX ));
+}
+
+OWriteEventsDocumentHandler::~OWriteEventsDocumentHandler()
+{
+}
+
+void OWriteEventsDocumentHandler::WriteEventsDocument() throw
+( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ m_xWriteDocumentHandler->startDocument();
+
+ // write DOCTYPE line!
+ Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
+ if ( xExtendedDocHandler.is() )
+ {
+ xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( EVENTS_DOCTYPE )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ }
+
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_EVENT )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT )) );
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
+
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENTS )), pList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ Sequence< PropertyValue > aEventProperties;
+
+ for ( int i = 0; i < m_aItems.aEventNames.getLength(); i++ )
+ {
+ if ( m_aItems.aEventsProperties[i] >>= aEventProperties )
+ WriteEvent( m_aItems.aEventNames[i], aEventProperties );
+ }
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENTS )) );
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endDocument();
+}
+
+//_________________________________________________________________________________________________________________
+// protected member functions
+//_________________________________________________________________________________________________________________
+
+void OWriteEventsDocumentHandler::WriteEvent( const ::rtl::OUString& aEventName, const Sequence< PropertyValue >& aPropertyValues ) throw
+( SAXException, RuntimeException )
+{
+ if ( aPropertyValues.getLength() > 0 )
+ {
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ if ( m_aAttributeURL.getLength() == 0 )
+ {
+ m_aAttributeURL = m_aXMLXlinkNS;
+ m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF ));
+ m_aAttributeLinkType = m_aXMLXlinkNS;
+ m_aAttributeLinkType += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE ));
+ m_aAttributeLanguage = m_aXMLEventNS;
+ m_aAttributeLanguage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_LANGUAGE ));
+ m_aAttributeMacroName = m_aXMLEventNS;
+ m_aAttributeMacroName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MACRONAME ));
+ m_aAttributeLibrary = m_aXMLEventNS;
+ m_aAttributeLibrary += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_LIBRARY ));
+ m_aAttributeName = m_aXMLEventNS;
+ m_aAttributeName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NAME ));
+ }
+
+ pList->AddAttribute( m_aAttributeName, m_aAttributeType, aEventName );
+
+ sal_Bool bURLSet = sal_False;
+ ::rtl::OUString aValue;
+ ::rtl::OUString aName;
+
+ // save attributes
+ for ( int i = 0; i < aPropertyValues.getLength(); i++ )
+ {
+ aPropertyValues[i].Value >>= aValue;
+ if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_EVENT_TYPE )))
+ pList->AddAttribute( m_aAttributeLanguage, m_aAttributeType, aValue );
+ else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_MACRO_NAME )) &&
+ aValue.getLength() > 0 )
+ pList->AddAttribute( m_aAttributeMacroName, m_aAttributeType, aValue );
+ else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_LIBRARY )) &&
+ aValue.getLength() > 0 )
+ pList->AddAttribute( m_aAttributeLibrary, m_aAttributeType, aValue );
+ else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_SCRIPT )))
+ {
+ pList->AddAttribute( m_aAttributeURL, m_aAttributeType, aValue );
+ bURLSet = sal_True;
+ }
+ }
+
+ if ( bURLSet )
+ pList->AddAttribute( m_aAttributeLinkType, m_aAttributeType, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "simple" )) );
+
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENT )), xList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENT )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/imagesconfiguration.cxx b/framework/source/fwe/xml/imagesconfiguration.cxx
new file mode 100644
index 000000000000..ebf4cff30e4c
--- /dev/null
+++ b/framework/source/fwe/xml/imagesconfiguration.cxx
@@ -0,0 +1,227 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <framework/imagesconfiguration.hxx>
+#include <services.h>
+
+#include <xml/imagesdocumenthandler.hxx>
+#include <xml/saxnamespacefilter.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <comphelper/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <tools/debug.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::io;
+
+
+namespace framework
+{
+
+SV_IMPL_PTRARR( ImageItemListDescriptor, ImageItemDescriptorPtr );
+SV_IMPL_PTRARR( ExternalImageItemListDescriptor, ExternalImageItemDescriptorPtr );
+SV_IMPL_PTRARR( ImageListDescriptor, ImageListItemDescriptorPtr );
+
+static Reference< XParser > GetSaxParser(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory
+ )
+{
+ return Reference< XParser >( xServiceFactory->createInstance( SERVICENAME_SAXPARSER), UNO_QUERY);
+}
+
+static Reference< XDocumentHandler > GetSaxWriter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory
+ )
+{
+ return Reference< XDocumentHandler >( xServiceFactory->createInstance( SERVICENAME_SAXWRITER), UNO_QUERY) ;
+}
+
+sal_Bool ImagesConfiguration::LoadImages(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ SvStream& rInStream, ImageListsDescriptor& aItems )
+{
+ Reference< XParser > xParser( GetSaxParser( xServiceFactory ) );
+ Reference< XInputStream > xInputStream(
+ (::cppu::OWeakObject *)new utl::OInputStreamWrapper( rInStream ),
+ UNO_QUERY );
+
+ // connect stream to input stream to the parser
+ InputSource aInputSource;
+
+ aInputSource.aInputStream = xInputStream;
+
+ // create namespace filter and set document handler inside to support xml namespaces
+ Reference< XDocumentHandler > xDocHandler( new OReadImagesDocumentHandler( aItems ));
+ Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler ));
+
+ // connect parser and filter
+ xParser->setDocumentHandler( xFilter );
+
+ try
+ {
+ xParser->parseStream( aInputSource );
+ return sal_True;
+ }
+ catch ( RuntimeException& )
+ {
+ return sal_False;
+ }
+ catch( SAXException& )
+ {
+ return sal_False;
+ }
+ catch( ::com::sun::star::io::IOException& )
+ {
+ return sal_False;
+ }
+}
+
+sal_Bool ImagesConfiguration::StoreImages(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ SvStream& rOutStream, const ImageListsDescriptor& aItems )
+{
+ Reference< XDocumentHandler > xWriter( GetSaxWriter( xServiceFactory ) );
+
+ Reference< XOutputStream > xOutputStream(
+ (::cppu::OWeakObject *)new utl::OOutputStreamWrapper( rOutStream ),
+ UNO_QUERY );
+
+ Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY );
+ xDataSource->setOutputStream( xOutputStream );
+
+ try
+ {
+ OWriteImagesDocumentHandler aWriteImagesDocumentHandler( aItems, xWriter );
+ aWriteImagesDocumentHandler.WriteImagesDocument();
+ return sal_True;
+ }
+ catch ( RuntimeException& )
+ {
+ return sal_False;
+ }
+ catch ( SAXException& )
+ {
+ return sal_False;
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ return sal_False;
+ }
+}
+
+sal_Bool ImagesConfiguration::LoadImages(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rInputStream,
+ ImageListsDescriptor& rItems )
+{
+ Reference< XParser > xParser( GetSaxParser( xServiceFactory ) );
+
+ // connect stream to input stream to the parser
+ InputSource aInputSource;
+
+ aInputSource.aInputStream = rInputStream;
+
+ // create namespace filter and set document handler inside to support xml namespaces
+ Reference< XDocumentHandler > xDocHandler( new OReadImagesDocumentHandler( rItems ));
+ Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler ));
+
+ // connect parser and filter
+ xParser->setDocumentHandler( xFilter );
+
+ try
+ {
+ xParser->parseStream( aInputSource );
+ return sal_True;
+ }
+ catch ( RuntimeException& )
+ {
+ return sal_False;
+ }
+ catch( SAXException& )
+ {
+ return sal_False;
+ }
+ catch( ::com::sun::star::io::IOException& )
+ {
+ return sal_False;
+ }
+}
+
+sal_Bool ImagesConfiguration::StoreImages(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& rOutputStream,
+ const ImageListsDescriptor& rItems )
+{
+ Reference< XDocumentHandler > xWriter( GetSaxWriter( xServiceFactory ) );
+
+ Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY );
+ xDataSource->setOutputStream( rOutputStream );
+
+ try
+ {
+ OWriteImagesDocumentHandler aWriteImagesDocumentHandler( rItems, xWriter );
+ aWriteImagesDocumentHandler.WriteImagesDocument();
+ return sal_True;
+ }
+ catch ( RuntimeException& )
+ {
+ return sal_False;
+ }
+ catch ( SAXException& )
+ {
+ return sal_False;
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ return sal_False;
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/imagesdocumenthandler.cxx b/framework/source/fwe/xml/imagesdocumenthandler.cxx
new file mode 100644
index 000000000000..2de8f244f778
--- /dev/null
+++ b/framework/source/fwe/xml/imagesdocumenthandler.cxx
@@ -0,0 +1,851 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <stdio.h>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <threadhelp/resetableguard.hxx>
+#include <xml/imagesdocumenthandler.hxx>
+#include <macros/debug.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <comphelper/attributelist.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+#define ELEMENT_IMAGECONTAINER "imagescontainer"
+#define ELEMENT_IMAGES "images"
+#define ELEMENT_ENTRY "entry"
+#define ELEMENT_EXTERNALIMAGES "externalimages"
+#define ELEMENT_EXTERNALENTRY "externalentry"
+
+#define ELEMENT_NS_IMAGESCONTAINER "image:imagescontainer"
+#define ELEMENT_NS_IMAGES "image:images"
+#define ELEMENT_NS_ENTRY "image:entry"
+#define ELEMENT_NS_EXTERNALIMAGES "image:externalimages"
+#define ELEMENT_NS_EXTERNALENTRY "image:externalentry"
+
+#define ATTRIBUTE_HREF "href"
+#define ATTRIBUTE_MASKCOLOR "maskcolor"
+#define ATTRIBUTE_COMMAND "command"
+#define ATTRIBUTE_BITMAPINDEX "bitmap-index"
+#define ATTRIBUTE_MASKURL "maskurl"
+#define ATTRIBUTE_MASKMODE "maskmode"
+#define ATTRIBUTE_HIGHCONTRASTURL "highcontrasturl"
+#define ATTRIBUTE_HIGHCONTRASTMASKURL "highcontrastmaskurl"
+#define ATTRIBUTE_TYPE_CDATA "CDATA"
+
+#define ATTRIBUTE_MASKMODE_BITMAP "maskbitmap"
+#define ATTRIBUTE_MASKMODE_COLOR "maskcolor"
+
+#define ATTRIBUTE_XMLNS_IMAGE "xmlns:image"
+#define ATTRIBUTE_XMLNS_XLINK "xmlns:xlink"
+
+#define ATTRIBUTE_XLINK_TYPE "xlink:type"
+#define ATTRIBUTE_XLINK_TYPE_VALUE "simple"
+
+#define XMLNS_IMAGE "http://openoffice.org/2001/image"
+#define XMLNS_XLINK "http://www.w3.org/1999/xlink"
+#define XMLNS_IMAGE_PREFIX "image:"
+#define XMLNS_XLINK_PREFIX "xlink:"
+
+#define XMLNS_FILTER_SEPARATOR "^"
+
+#define IMAGES_DOCTYPE "<!DOCTYPE image:imagecontainer PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"image.dtd\">"
+
+namespace framework
+{
+
+struct ImageXMLEntryProperty
+{
+ OReadImagesDocumentHandler::Image_XML_Namespace nNamespace;
+ char aEntryName[20];
+};
+
+ImageXMLEntryProperty ImagesEntries[OReadImagesDocumentHandler::IMG_XML_ENTRY_COUNT] =
+{
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_IMAGECONTAINER },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_IMAGES },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_ENTRY },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_EXTERNALIMAGES },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_EXTERNALENTRY },
+ { OReadImagesDocumentHandler::IMG_NS_XLINK, ATTRIBUTE_HREF },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKCOLOR },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_COMMAND },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_BITMAPINDEX },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKURL },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKMODE },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_HIGHCONTRASTURL },
+ { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_HIGHCONTRASTMASKURL }
+};
+
+
+OReadImagesDocumentHandler::OReadImagesDocumentHandler( ImageListsDescriptor& aItems ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_aImageList( aItems ),
+ m_pImages( 0 ),
+ m_pExternalImages( 0 )
+{
+ m_aImageList.pImageList = NULL;
+ m_aImageList.pExternalImageList = NULL;
+
+ m_nHashMaskModeBitmap = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_BITMAP )).hashCode();
+ m_nHashMaskModeColor = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_COLOR )).hashCode();
+
+ // create hash map to speed up lookup
+ for ( int i = 0; i < (int)IMG_XML_ENTRY_COUNT; i++ )
+ {
+ ::rtl::OUStringBuffer temp( 20 );
+
+ if ( ImagesEntries[i].nNamespace == IMG_NS_IMAGE )
+ temp.appendAscii( XMLNS_IMAGE );
+ else
+ temp.appendAscii( XMLNS_XLINK );
+
+ temp.appendAscii( XMLNS_FILTER_SEPARATOR );
+ temp.appendAscii( ImagesEntries[i].aEntryName );
+ m_aImageMap.insert( ImageHashMap::value_type( temp.makeStringAndClear(), (Image_XML_Entry)i ) );
+ }
+
+ // reset states
+ m_bImageContainerStartFound = sal_False;
+ m_bImageContainerEndFound = sal_False;
+ m_bImagesStartFound = sal_False;
+ m_bImagesEndFound = sal_False;
+ m_bImageStartFound = sal_False;
+ m_bExternalImagesStartFound = sal_False;
+ m_bExternalImagesEndFound = sal_False;
+ m_bExternalImageStartFound = sal_False;
+}
+
+OReadImagesDocumentHandler::~OReadImagesDocumentHandler()
+{
+}
+
+// XDocumentHandler
+void SAL_CALL OReadImagesDocumentHandler::startDocument(void)
+throw ( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadImagesDocumentHandler::endDocument(void)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if (( m_bImageContainerStartFound && !m_bImageContainerEndFound ) ||
+ ( !m_bImageContainerStartFound && m_bImageContainerEndFound ) )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'image:imagecontainer' found!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+}
+
+void SAL_CALL OReadImagesDocumentHandler::startElement(
+ const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName ) ;
+ if ( pImageEntry != m_aImageMap.end() )
+ {
+ switch ( pImageEntry->second )
+ {
+ case IMG_ELEMENT_IMAGECONTAINER:
+ {
+ // image:imagecontainer element (container element for all further image elements)
+ if ( m_bImageContainerStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:imagecontainer' cannot be embeded into 'image:imagecontainer'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bImageContainerStartFound = sal_True;
+ }
+ break;
+
+ case IMG_ELEMENT_IMAGES:
+ {
+ if ( !m_bImageContainerStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:images' must be embeded into element 'image:imagecontainer'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ if ( m_bImagesStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:images' cannot be embeded into 'image:images'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ if ( !m_aImageList.pImageList )
+ m_aImageList.pImageList = new ImageListDescriptor;
+
+ m_bImagesStartFound = sal_True;
+ m_pImages = new ImageListItemDescriptor;
+
+ for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
+ {
+ pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
+ if ( pImageEntry != m_aImageMap.end() )
+ {
+ switch ( pImageEntry->second )
+ {
+ case IMG_ATTRIBUTE_HREF:
+ {
+ m_pImages->aURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case IMG_ATTRIBUTE_MASKCOLOR:
+ {
+ ::rtl::OUString aColor = xAttribs->getValueByIndex( n );
+
+ if ( aColor.getLength() > 0 )
+ {
+ if ( aColor.getStr()[0] == '#' )
+ {
+ // the color value is given as #rrggbb and used the hexadecimal system!!
+ sal_uInt32 nColor = aColor.copy( 1 ).toInt32( 16 );
+
+ m_pImages->aMaskColor = Color( COLORDATA_RGB( nColor ) );
+ }
+ }
+ }
+ break;
+
+ case IMG_ATTRIBUTE_MASKURL:
+ {
+ m_pImages->aMaskURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case IMG_ATTRIBUTE_MASKMODE:
+ {
+ sal_Int32 nHashCode = xAttribs->getValueByIndex( n ).hashCode();
+ if ( nHashCode == m_nHashMaskModeBitmap )
+ m_pImages->nMaskMode = ImageMaskMode_Bitmap;
+ else if ( nHashCode == m_nHashMaskModeColor )
+ m_pImages->nMaskMode = ImageMaskMode_Color;
+ else
+ {
+ delete m_pImages;
+ m_pImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute image:maskmode must be 'maskcolor' or 'maskbitmap'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ break;
+
+ case IMG_ATTRIBUTE_HIGHCONTRASTURL:
+ {
+ m_pImages->aHighContrastURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case IMG_ATTRIBUTE_HIGHCONTRASTMASKURL:
+ {
+ m_pImages->aHighContrastMaskURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ } // for
+
+ if ( m_pImages->aURL.Len() == 0 )
+ {
+ delete m_pImages;
+ m_pImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute xlink:href must have a value!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ break;
+
+ case IMG_ELEMENT_ENTRY:
+ {
+ // Check that image:entry is embeded into image:images!
+ if ( !m_bImagesStartFound )
+ {
+ delete m_pImages;
+ m_pImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:entry' must be embeded into element 'image:images'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ if ( !m_pImages->pImageItemList )
+ m_pImages->pImageItemList = new ImageItemListDescriptor;
+
+ m_bImageStartFound = sal_True;
+
+ // Create new image item descriptor
+ ImageItemDescriptor* pItem = new ImageItemDescriptor;
+ pItem->nIndex = -1;
+
+ // Read attributes for this image definition
+ for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
+ {
+ pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
+ if ( pImageEntry != m_aImageMap.end() )
+ {
+ switch ( pImageEntry->second )
+ {
+ case IMG_ATTRIBUTE_COMMAND:
+ {
+ pItem->aCommandURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case IMG_ATTRIBUTE_BITMAPINDEX:
+ {
+ pItem->nIndex = xAttribs->getValueByIndex( n ).toInt32();
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // Check required attribute "bitmap-index"
+ if ( pItem->nIndex < 0 )
+ {
+ delete pItem;
+ delete m_pImages;
+ m_pImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:bitmap-index' must have a value >= 0!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ // Check required attribute "command"
+ if ( pItem->aCommandURL.Len() == 0 )
+ {
+ delete pItem;
+ delete m_pImages;
+ m_pImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:command' must have a value!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ if ( m_pImages )
+ m_pImages->pImageItemList->Insert( pItem, m_pImages->pImageItemList->Count() );
+ }
+ break;
+
+ case IMG_ELEMENT_EXTERNALIMAGES:
+ {
+ // Check that image:externalimages is embeded into image:imagecontainer
+ if ( !m_bImageContainerStartFound )
+ {
+ delete m_pImages;
+ m_pImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalimages' must be embeded into element 'image:imagecontainer'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ // Check that image:externalentry is NOT embeded into image:externalentry
+ if ( m_bExternalImagesStartFound )
+ {
+ delete m_pImages;
+ m_pImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalimages' cannot be embeded into 'image:externalimages'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ // Create unique external image container
+ m_bExternalImagesStartFound = sal_True;
+ m_pExternalImages = new ExternalImageItemListDescriptor;
+ }
+ break;
+
+ case IMG_ELEMENT_EXTERNALENTRY:
+ {
+ if ( !m_bExternalImagesStartFound )
+ {
+ delete m_pImages;
+ delete m_pExternalImages;
+ m_pImages = NULL;
+ m_pExternalImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalentry' must be embeded into 'image:externalimages'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ if ( m_bExternalImageStartFound )
+ {
+ delete m_pImages;
+ delete m_pExternalImages;
+ m_pImages = NULL;
+ m_pExternalImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalentry' cannot be embeded into 'image:externalentry'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bExternalImageStartFound = sal_True;
+
+ ExternalImageItemDescriptor* pItem = new ExternalImageItemDescriptor;
+
+ // Read attributes for this external image definition
+ for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
+ {
+ pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) );
+ if ( pImageEntry != m_aImageMap.end() )
+ {
+ switch ( pImageEntry->second )
+ {
+ case IMG_ATTRIBUTE_COMMAND:
+ {
+ pItem->aCommandURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case IMG_ATTRIBUTE_HREF:
+ {
+ pItem->aURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // Check required attribute "command"
+ if ( pItem->aCommandURL.Len() == 0 )
+ {
+ delete pItem;
+ delete m_pImages;
+ delete m_pExternalImages;
+ m_pImages = NULL;
+ m_pExternalImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:command' must have a value!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ // Check required attribute "href"
+ if ( pItem->aURL.Len() == 0 )
+ {
+ delete pItem;
+ delete m_pImages;
+ delete m_pExternalImages;
+ m_pImages = NULL;
+ m_pExternalImages = NULL;
+
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'xlink:href' must have a value!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ if ( m_pExternalImages )
+ m_pExternalImages->Insert( pItem, m_pExternalImages->Count() );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void SAL_CALL OReadImagesDocumentHandler::endElement(const ::rtl::OUString& aName)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName ) ;
+ if ( pImageEntry != m_aImageMap.end() )
+ {
+ switch ( pImageEntry->second )
+ {
+ case IMG_ELEMENT_IMAGECONTAINER:
+ {
+ m_bImageContainerEndFound = sal_True;
+ }
+ break;
+
+ case IMG_ELEMENT_IMAGES:
+ {
+ if ( m_pImages )
+ {
+ if ( m_aImageList.pImageList )
+ m_aImageList.pImageList->Insert( m_pImages, m_aImageList.pImageList->Count() );
+ m_pImages = NULL;
+ }
+ m_bImagesStartFound = sal_False;
+ }
+ break;
+
+ case IMG_ELEMENT_ENTRY:
+ {
+ m_bImageStartFound = sal_False;
+ }
+ break;
+
+ case IMG_ELEMENT_EXTERNALIMAGES:
+ {
+ if ( m_pExternalImages && !m_aImageList.pExternalImageList )
+ {
+ if ( !m_aImageList.pExternalImageList )
+ m_aImageList.pExternalImageList = m_pExternalImages;
+ }
+
+ m_bExternalImagesStartFound = sal_False;
+ m_pExternalImages = NULL;
+ }
+ break;
+
+ case IMG_ELEMENT_EXTERNALENTRY:
+ {
+ m_bExternalImageStartFound = sal_False;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void SAL_CALL OReadImagesDocumentHandler::characters(const ::rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadImagesDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadImagesDocumentHandler::processingInstruction(
+ const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadImagesDocumentHandler::setDocumentLocator(
+ const Reference< XLocator > &xLocator)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ m_xLocator = xLocator;
+}
+
+::rtl::OUString OReadImagesDocumentHandler::getErrorLineString()
+{
+ ResetableGuard aGuard( m_aLock );
+
+ char buffer[32];
+
+ if ( m_xLocator.is() )
+ {
+ snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
+ return ::rtl::OUString::createFromAscii( buffer );
+ }
+ else
+ return ::rtl::OUString();
+}
+
+
+//_________________________________________________________________________________________________________________
+// OWriteImagesDocumentHandler
+//_________________________________________________________________________________________________________________
+
+OWriteImagesDocumentHandler::OWriteImagesDocumentHandler(
+ const ImageListsDescriptor& aItems,
+ Reference< XDocumentHandler > rWriteDocumentHandler ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_aImageListsItems( aItems ),
+ m_xWriteDocumentHandler( rWriteDocumentHandler )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
+ m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
+ m_aXMLImageNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_IMAGE_PREFIX ));
+ m_aXMLXlinkNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
+ m_aAttributeXlinkType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XLINK_TYPE ));
+ m_aAttributeValueSimple = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XLINK_TYPE_VALUE ));
+}
+
+OWriteImagesDocumentHandler::~OWriteImagesDocumentHandler()
+{
+}
+
+void OWriteImagesDocumentHandler::WriteImagesDocument() throw
+( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ m_xWriteDocumentHandler->startDocument();
+
+ // write DOCTYPE line!
+ Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
+ if ( xExtendedDocHandler.is() )
+ {
+ xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMAGES_DOCTYPE )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ }
+
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_IMAGE )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_IMAGE )) );
+
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
+
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGESCONTAINER )), pList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ if ( m_aImageListsItems.pImageList )
+ {
+ ImageListDescriptor* pImageList = m_aImageListsItems.pImageList;
+
+ for ( sal_uInt16 i = 0; i < m_aImageListsItems.pImageList->Count(); i++ )
+ {
+ const ImageListItemDescriptor* pImageItems = (*pImageList)[i];
+ WriteImageList( pImageItems );
+ }
+ }
+
+ if ( m_aImageListsItems.pExternalImageList )
+ {
+ WriteExternalImageList( m_aImageListsItems.pExternalImageList );
+ }
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGESCONTAINER )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endDocument();
+}
+
+//_________________________________________________________________________________________________________________
+// protected member functions
+//_________________________________________________________________________________________________________________
+
+void OWriteImagesDocumentHandler::WriteImageList( const ImageListItemDescriptor* pImageList ) throw
+( SAXException, RuntimeException )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ // save required attributes
+ pList->AddAttribute( m_aAttributeXlinkType,
+ m_aAttributeType,
+ m_aAttributeValueSimple );
+
+ pList->AddAttribute( m_aXMLXlinkNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF )),
+ m_aAttributeType,
+ pImageList->aURL );
+
+ if ( pImageList->nMaskMode == ImageMaskMode_Bitmap )
+ {
+ pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_BITMAP )) );
+
+ pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKURL )),
+ m_aAttributeType,
+ pImageList->aMaskURL );
+
+ if ( pImageList->aHighContrastMaskURL.Len() > 0 )
+ {
+ pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HIGHCONTRASTMASKURL )),
+ m_aAttributeType,
+ pImageList->aHighContrastMaskURL );
+ }
+ }
+ else
+ {
+ ::rtl::OUStringBuffer aColorStrBuffer( 8 );
+ sal_Int64 nValue = pImageList->aMaskColor.GetRGBColor();
+
+ aColorStrBuffer.appendAscii( "#" );
+ aColorStrBuffer.append( ::rtl::OUString::valueOf( nValue, 16 ));
+
+ pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKCOLOR )),
+ m_aAttributeType,
+ aColorStrBuffer.makeStringAndClear() );
+
+ pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_COLOR )) );
+ }
+
+ if ( pImageList->aHighContrastURL.Len() > 0 )
+ {
+ pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HIGHCONTRASTURL )),
+ m_aAttributeType,
+ pImageList->aHighContrastURL );
+ }
+
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGES )), xList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ ImageItemListDescriptor* pImageItemList = pImageList->pImageItemList;
+ if ( pImageItemList )
+ {
+ for ( sal_uInt16 i = 0; i < pImageItemList->Count(); i++ )
+ WriteImage( (*pImageItemList)[i] );
+ }
+
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGES )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+}
+
+void OWriteImagesDocumentHandler::WriteImage( const ImageItemDescriptor* pImage ) throw
+( SAXException, RuntimeException )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BITMAPINDEX )),
+ m_aAttributeType,
+ ::rtl::OUString::valueOf( (sal_Int32)pImage->nIndex ) );
+
+ pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_COMMAND )),
+ m_aAttributeType,
+ pImage->aCommandURL );
+
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_ENTRY )), xList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_ENTRY )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+}
+
+void OWriteImagesDocumentHandler::WriteExternalImageList( const ExternalImageItemListDescriptor* pExternalImageList ) throw
+( SAXException, RuntimeException )
+{
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALIMAGES )), m_xEmptyList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ for ( sal_uInt16 i = 0; i < pExternalImageList->Count(); i++ )
+ {
+ ExternalImageItemDescriptor* pItem = (*pExternalImageList)[i];
+ WriteExternalImage( pItem );
+ }
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALIMAGES )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+}
+
+void OWriteImagesDocumentHandler::WriteExternalImage( const ExternalImageItemDescriptor* pExternalImage ) throw
+( SAXException, RuntimeException )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ // save required attributes
+ pList->AddAttribute( m_aAttributeXlinkType,
+ m_aAttributeType,
+ m_aAttributeValueSimple );
+
+ if ( pExternalImage->aURL.Len() > 0 )
+ {
+ pList->AddAttribute( m_aXMLXlinkNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF )),
+ m_aAttributeType,
+ pExternalImage->aURL );
+ }
+
+ if ( pExternalImage->aCommandURL.Len() > 0 )
+ {
+ pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_COMMAND )),
+ m_aAttributeType,
+ pExternalImage->aCommandURL );
+ }
+
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALENTRY )), xList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALENTRY )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+}
+
+} // namespace framework
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/menuconfiguration.cxx b/framework/source/fwe/xml/menuconfiguration.cxx
new file mode 100644
index 000000000000..c0feda7ec766
--- /dev/null
+++ b/framework/source/fwe/xml/menuconfiguration.cxx
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <framework/menuconfiguration.hxx>
+
+#include <framework/bmkmenu.hxx>
+#include <framework/addonmenu.hxx>
+#include <xml/menudocumenthandler.hxx>
+#include <xml/saxnamespacefilter.hxx>
+#include <services.h>
+
+#include <uielement/rootitemcontainer.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::io;
+
+namespace framework
+{
+
+sal_Bool MenuConfiguration::IsPickListItemId( sal_uInt16 nId )
+{
+ return (( START_ITEMID_PICKLIST <= nId ) && ( nId <= END_ITEMID_PICKLIST ));
+}
+
+sal_Bool MenuConfiguration::IsWindowListItemId( sal_uInt16 nId )
+{
+ return (( START_ITEMID_WINDOWLIST <= nId ) && ( nId <= END_ITEMID_WINDOWLIST ));
+}
+
+
+MenuConfiguration::MenuConfiguration(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager )
+: m_rxServiceManager( rServiceManager )
+{
+}
+
+
+MenuConfiguration::~MenuConfiguration()
+{
+}
+
+
+Reference< XIndexAccess > MenuConfiguration::CreateMenuBarConfigurationFromXML(
+ Reference< XInputStream >& rInputStream )
+throw ( WrappedTargetException )
+{
+ Reference< XParser > xParser( m_rxServiceManager->createInstance(SERVICENAME_SAXPARSER),UNO_QUERY);
+
+ // connect stream to input stream to the parser
+ InputSource aInputSource;
+
+ aInputSource.aInputStream = rInputStream;
+
+
+ // create menu bar
+ Reference< XIndexContainer > xItemContainer( static_cast< cppu::OWeakObject *>( new RootItemContainer()), UNO_QUERY );
+
+ // create namespace filter and set menudocument handler inside to support xml namespaces
+
+ Reference< XDocumentHandler > xDocHandler( new OReadMenuDocumentHandler( m_rxServiceManager, xItemContainer ));
+
+ Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler ));
+
+ // connect parser and filter
+ xParser->setDocumentHandler( xFilter );
+
+ try
+ {
+ xParser->parseStream( aInputSource );
+ return Reference< XIndexAccess >( xItemContainer, UNO_QUERY );
+ }
+ catch ( RuntimeException& e )
+ {
+ throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
+ }
+ catch( SAXException& e )
+ {
+ SAXException aWrappedSAXException;
+
+ if ( !( e.WrappedException >>= aWrappedSAXException ))
+ throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
+ else
+ throw WrappedTargetException( aWrappedSAXException.Message, Reference< XInterface >(), Any() );
+ }
+ catch( ::com::sun::star::io::IOException& e )
+ {
+ throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
+ }
+}
+
+PopupMenu* MenuConfiguration::CreateBookmarkMenu(
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame,
+ const ::rtl::OUString& aURL )
+throw ( ::com::sun::star::lang::WrappedTargetException )
+{
+ if ( aURL == BOOKMARK_NEWMENU )
+ return new BmkMenu( rFrame, BmkMenu::BMK_NEWMENU );
+ else if ( aURL == BOOKMARK_WIZARDMENU )
+ return new BmkMenu( rFrame, BmkMenu::BMK_WIZARDMENU );
+ else
+ return NULL;
+}
+
+void MenuConfiguration::StoreMenuBarConfigurationToXML(
+ Reference< XIndexAccess >& rMenuBarConfiguration,
+ Reference< XOutputStream >& rOutputStream )
+throw ( WrappedTargetException )
+{
+ Reference< XDocumentHandler > xWriter;
+
+ xWriter = Reference< XDocumentHandler >( m_rxServiceManager->createInstance(
+ SERVICENAME_SAXWRITER), UNO_QUERY) ;
+
+ Reference< XActiveDataSource> xDataSource( xWriter , UNO_QUERY );
+ xDataSource->setOutputStream( rOutputStream );
+
+ try
+ {
+ OWriteMenuDocumentHandler aWriteMenuDocumentHandler( rMenuBarConfiguration, xWriter );
+ aWriteMenuDocumentHandler.WriteMenuDocument();
+ }
+ catch ( RuntimeException& e )
+ {
+ throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
+ }
+ catch ( SAXException& e )
+ {
+ throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
+ }
+ catch ( ::com::sun::star::io::IOException& e )
+ {
+ throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/menudocumenthandler.cxx b/framework/source/fwe/xml/menudocumenthandler.cxx
new file mode 100644
index 000000000000..bb36e403cc9d
--- /dev/null
+++ b/framework/source/fwe/xml/menudocumenthandler.cxx
@@ -0,0 +1,1005 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <stdio.h>
+#include <sal/macros.h>
+
+#include <xml/menudocumenthandler.hxx>
+#include <framework/menuconfiguration.hxx>
+#include <framework/addonmenu.hxx>
+
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/ui/ItemStyle.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <rtl/logfile.hxx>
+#include <comphelper/attributelist.hxx>
+
+
+#define XMLNS_MENU "http://openoffice.org/2001/menu"
+#define XMLNS_PREFIX "menu:"
+
+#define ELEMENT_MENUBAR "http://openoffice.org/2001/menu^menubar"
+#define ELEMENT_MENU "http://openoffice.org/2001/menu^menu"
+#define ELEMENT_MENUPOPUP "http://openoffice.org/2001/menu^menupopup"
+#define ELEMENT_MENUITEM "http://openoffice.org/2001/menu^menuitem"
+#define ELEMENT_MENUSEPARATOR "http://openoffice.org/2001/menu^menuseparator"
+
+#define ELEMENT_NS_MENUBAR "menu:menubar"
+#define ELEMENT_NS_MENU "menu:menu"
+#define ELEMENT_NS_MENUPOPUP "menu:menupopup"
+#define ELEMENT_NS_MENUITEM "menu:menuitem"
+#define ELEMENT_NS_MENUSEPARATOR "menu:menuseparator"
+
+#define ATTRIBUTE_ID "http://openoffice.org/2001/menu^id"
+#define ATTRIBUTE_LABEL "http://openoffice.org/2001/menu^label"
+#define ATTRIBUTE_HELPID "http://openoffice.org/2001/menu^helpid"
+#define ATTRIBUTE_LINEBREAK "http://openoffice.org/2001/menu^linebreak"
+#define ATTRIBUTE_STYLE "http://openoffice.org/2001/menu^style"
+
+#define ATTRIBUTE_NS_ID "menu:id"
+#define ATTRIBUTE_NS_LABEL "menu:label"
+#define ATTRIBUTE_NS_HELPID "menu:helpid"
+#define ATTRIBUTE_NS_LINEBREAK "menu:linebreak"
+#define ATTRIBUTE_NS_STYLE "menu:style"
+
+#define ATTRIBUTE_XMLNS_MENU "xmlns:menu"
+
+#define ATTRIBUTE_TYPE_CDATA "CDATA"
+
+#define MENUBAR_DOCTYPE "<!DOCTYPE menu:menubar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"menubar.dtd\">"
+
+#define ATTRIBUTE_ITEMSTYLE_TEXT "text"
+#define ATTRIBUTE_ITEMSTYLE_IMAGE "image"
+#define ATTRIBUTE_ITEMSTYLE_RADIO "radio"
+
+// Property names of a menu/menu item ItemDescriptor
+static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
+static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL";
+static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer";
+static const char ITEM_DESCRIPTOR_LABEL[] = "Label";
+static const char ITEM_DESCRIPTOR_TYPE[] = "Type";
+static const char ITEM_DESCRIPTOR_STYLE[] = "Style";
+
+// special popup menus (filled during runtime) must be saved as an empty popup menu or menuitem!!!
+static const sal_Int32 CMD_PROTOCOL_SIZE = 5;
+static const char CMD_PROTOCOL[] = ".uno:";
+static const char ADDDIRECT_CMD[] = ".uno:AddDirect" ;
+static const char AUTOPILOTMENU_CMD[] = ".uno:AutoPilotMenu" ;
+static const char FILEMENU_CMD[] = ".uno:Picklist" ;
+static const char WINDOWMENU_CMD[] = ".uno:WindowList" ;
+
+//_________________________________________________________________________________________________________________
+// using namespaces
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+struct MenuStyleItem
+{
+ sal_Int16 nBit;
+ const char* attrName;
+};
+
+MenuStyleItem MenuItemStyles[ ] = {
+ { ::com::sun::star::ui::ItemStyle::ICON, ATTRIBUTE_ITEMSTYLE_IMAGE },
+ { ::com::sun::star::ui::ItemStyle::TEXT, ATTRIBUTE_ITEMSTYLE_TEXT },
+ { ::com::sun::star::ui::ItemStyle::RADIO_CHECK, ATTRIBUTE_ITEMSTYLE_RADIO }
+};
+
+
+sal_Int32 nMenuStyleItemEntries = SAL_N_ELEMENTS( MenuItemStyles );
+
+static void ExtractMenuParameters( const Sequence< PropertyValue > rProp,
+ ::rtl::OUString& rCommandURL,
+ ::rtl::OUString& rLabel,
+ ::rtl::OUString& rHelpURL,
+ Reference< XIndexAccess >& rSubMenu,
+ sal_Int16& rType,
+ sal_Int16& rStyle )
+{
+ for ( sal_Int32 i = 0; i < rProp.getLength(); i++ )
+ {
+ if ( rProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_COMMANDURL)) )
+ {
+ rProp[i].Value >>= rCommandURL;
+ rCommandURL = rCommandURL.intern();
+ }
+ else if ( rProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_HELPURL)) )
+ {
+ rProp[i].Value >>= rHelpURL;
+ }
+ else if ( rProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_CONTAINER)) )
+ {
+ rProp[i].Value >>= rSubMenu;
+ }
+ else if ( rProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_LABEL)) )
+ {
+ rProp[i].Value >>= rLabel;
+ }
+ else if ( rProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_TYPE)) )
+ {
+ rProp[i].Value >>= rType;
+ }
+ else if ( rProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_STYLE)) )
+ {
+ rProp[i].Value >>= rStyle;
+ }
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+// Base class implementation
+
+ReadMenuDocumentHandlerBase::ReadMenuDocumentHandlerBase() :
+ m_xLocator( 0 ),
+ m_xReader( 0 ),
+ m_aType( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )),
+ m_aLabel( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL )),
+ m_aContainer( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_CONTAINER )),
+ m_aHelpURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL )),
+ m_aCommandURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL )),
+ m_aStyle( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE ))
+{
+}
+
+ReadMenuDocumentHandlerBase::~ReadMenuDocumentHandlerBase()
+{
+}
+
+void SAL_CALL ReadMenuDocumentHandlerBase::ignorableWhitespace(
+ const ::rtl::OUString& )
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL ReadMenuDocumentHandlerBase::processingInstruction(
+ const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL ReadMenuDocumentHandlerBase::setDocumentLocator(
+ const Reference< XLocator > &xLocator)
+throw( SAXException, RuntimeException )
+{
+ m_xLocator = xLocator;
+}
+
+::rtl::OUString ReadMenuDocumentHandlerBase::getErrorLineString()
+{
+ char buffer[32];
+
+ if ( m_xLocator.is() )
+ {
+ snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
+ return ::rtl::OUString::createFromAscii( buffer );
+ }
+ else
+ return ::rtl::OUString();
+}
+
+void ReadMenuDocumentHandlerBase::initPropertyCommon(
+ Sequence< PropertyValue > &rProps, const rtl::OUString &rCommandURL,
+ const rtl::OUString &rHelpId, const rtl::OUString &rLabel, sal_Int16 nItemStyleBits )
+{
+ rProps[0].Name = m_aCommandURL;
+ rProps[1].Name = m_aHelpURL;
+ rProps[2].Name = m_aContainer;
+ rProps[3].Name = m_aLabel;
+ rProps[4].Name = m_aStyle;
+ rProps[5].Name = m_aType;
+
+ // Common values
+ rProps[0].Value <<= rCommandURL.intern();
+ rProps[1].Value <<= rHelpId;
+ rProps[2].Value <<= Reference< XIndexContainer >();
+ rProps[3].Value <<= rLabel;
+ rProps[4].Value <<= nItemStyleBits;
+ rProps[5].Value <<= ::com::sun::star::ui::ItemType::DEFAULT;
+}
+
+// -----------------------------------------------------------------------------
+
+OReadMenuDocumentHandler::OReadMenuDocumentHandler(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ const Reference< XIndexContainer >& rMenuBarContainer )
+: m_nElementDepth( 0 ),
+ m_bMenuBarMode( sal_False ),
+ m_xMenuBarContainer( rMenuBarContainer ),
+ m_xContainerFactory( rMenuBarContainer, UNO_QUERY ),
+ mxServiceFactory(xServiceFactory)
+{
+}
+
+const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuDocumentHandler::getServiceFactory()
+{
+ return mxServiceFactory;
+}
+
+OReadMenuDocumentHandler::~OReadMenuDocumentHandler()
+{
+}
+
+
+void SAL_CALL OReadMenuDocumentHandler::startDocument(void)
+ throw ( SAXException, RuntimeException )
+{
+}
+
+
+void SAL_CALL OReadMenuDocumentHandler::endDocument(void)
+ throw( SAXException, RuntimeException )
+{
+ if ( m_nElementDepth > 0 )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A closing element is missing!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+}
+
+
+void SAL_CALL OReadMenuDocumentHandler::startElement(
+ const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList )
+throw( SAXException, RuntimeException )
+{
+ if ( m_bMenuBarMode )
+ {
+ ++m_nElementDepth;
+ m_xReader->startElement( aName, xAttrList );
+ }
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR )))
+ {
+ ++m_nElementDepth;
+ m_bMenuBarMode = sal_True;
+ m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( getServiceFactory(), m_xMenuBarContainer, m_xContainerFactory ));
+
+ m_xReader->startDocument();
+ }
+}
+
+
+void SAL_CALL OReadMenuDocumentHandler::characters(const rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+
+void SAL_CALL OReadMenuDocumentHandler::endElement( const ::rtl::OUString& aName )
+ throw( SAXException, RuntimeException )
+{
+ if ( m_bMenuBarMode )
+ {
+ --m_nElementDepth;
+ m_xReader->endElement( aName );
+ if ( 0 == m_nElementDepth )
+ {
+ m_xReader->endDocument();
+ m_xReader = Reference< XDocumentHandler >();
+ m_bMenuBarMode = sal_False;
+ if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR )))
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menubar expected!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+
+OReadMenuBarHandler::OReadMenuBarHandler(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ const Reference< XIndexContainer >& rMenuBarContainer,
+ const Reference< XSingleComponentFactory >& rFactory )
+: m_nElementDepth( 0 ),
+ m_bMenuMode( sal_False ),
+ m_xMenuBarContainer( rMenuBarContainer ),
+ m_xContainerFactory( rFactory ),
+ mxServiceFactory( xServiceFactory )
+{
+}
+
+
+const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuBarHandler::getServiceFactory()
+{
+ return mxServiceFactory;
+}
+
+OReadMenuBarHandler::~OReadMenuBarHandler()
+{
+}
+
+
+void SAL_CALL OReadMenuBarHandler::startDocument(void)
+ throw ( SAXException, RuntimeException )
+{
+}
+
+
+void SAL_CALL OReadMenuBarHandler::endDocument(void)
+ throw( SAXException, RuntimeException )
+{
+}
+
+
+void SAL_CALL OReadMenuBarHandler::startElement(
+ const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList )
+throw( SAXException, RuntimeException )
+{
+ if ( m_bMenuMode )
+ {
+ ++m_nElementDepth;
+ m_xReader->startElement( rName, xAttrList );
+ }
+ else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
+ {
+ ++m_nElementDepth;
+
+ ::rtl::OUString aHelpId;
+ ::rtl::OUString aCommandId;
+ ::rtl::OUString aLabel;
+ sal_Int16 nItemBits(0);
+
+ m_bMenuMode = sal_True;
+
+ // Container must be factory to create sub container
+ Reference< XComponentContext > xComponentContext;
+ Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>=
+ xComponentContext;
+
+ Reference< XIndexContainer > xSubItemContainer;
+ if ( m_xContainerFactory.is() )
+ xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( xComponentContext ), UNO_QUERY );
+
+ if ( xSubItemContainer.is() )
+ {
+ // read attributes for menu
+ for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
+ {
+ ::rtl::OUString aName = xAttrList->getNameByIndex( i );
+ ::rtl::OUString aValue = xAttrList->getValueByIndex( i );
+ if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
+ aCommandId = aValue;
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
+ aLabel = aValue;
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
+ aHelpId = aValue;
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE )))
+ {
+ ::rtl::OUString aTemp( aValue );
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex );
+ if ( aToken.getLength() > 0 )
+ {
+ if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
+ else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
+ else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
+ }
+ }
+ while ( nIndex >= 0 );
+ }
+ }
+
+ if ( aCommandId.getLength() > 0 )
+ {
+ Sequence< PropertyValue > aSubMenuProp( 6 );
+ initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
+ aSubMenuProp[2].Value <<= xSubItemContainer;
+
+ m_xMenuBarContainer->insertByIndex( m_xMenuBarContainer->getCount(), makeAny( aSubMenuProp ) );
+ }
+ else
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
+ m_xReader->startDocument();
+ }
+ }
+ else
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "element menu expected!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+}
+
+
+void SAL_CALL OReadMenuBarHandler::characters(const rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+
+void OReadMenuBarHandler::endElement( const ::rtl::OUString& aName )
+ throw( SAXException, RuntimeException )
+{
+ if ( m_bMenuMode )
+ {
+ --m_nElementDepth;
+ if ( 0 == m_nElementDepth )
+ {
+ m_xReader->endDocument();
+ m_xReader = Reference< XDocumentHandler >();
+ m_bMenuMode = sal_False;
+ if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ else
+ m_xReader->endElement( aName );
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+
+
+OReadMenuHandler::OReadMenuHandler(
+ const Reference< XIndexContainer >& rMenuContainer,
+ const Reference< XSingleComponentFactory >& rFactory ) :
+ m_nElementDepth( 0 ),
+ m_bMenuPopupMode( sal_False ),
+ m_xMenuContainer( rMenuContainer ),
+ m_xContainerFactory( rFactory )
+{
+}
+
+
+OReadMenuHandler::~OReadMenuHandler()
+{
+}
+
+
+void SAL_CALL OReadMenuHandler::startDocument(void)
+ throw ( SAXException, RuntimeException )
+{
+}
+
+
+void SAL_CALL OReadMenuHandler::endDocument(void)
+ throw( SAXException, RuntimeException)
+{
+}
+
+
+void SAL_CALL OReadMenuHandler::startElement(
+ const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList )
+throw( SAXException, RuntimeException )
+{
+ if ( m_bMenuPopupMode )
+ {
+ ++m_nElementDepth;
+ m_xReader->startElement( aName, xAttrList );
+ }
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP )))
+ {
+ ++m_nElementDepth;
+ m_bMenuPopupMode = sal_True;
+ m_xReader = Reference< XDocumentHandler >( new OReadMenuPopupHandler( m_xMenuContainer, m_xContainerFactory ));
+ m_xReader->startDocument();
+ }
+ else
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+}
+
+
+void SAL_CALL OReadMenuHandler::characters(const rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+
+void SAL_CALL OReadMenuHandler::endElement( const ::rtl::OUString& aName )
+ throw( SAXException, RuntimeException )
+{
+ if ( m_bMenuPopupMode )
+ {
+ --m_nElementDepth;
+ if ( 0 == m_nElementDepth )
+ {
+ m_xReader->endDocument();
+ m_xReader = Reference< XDocumentHandler >();
+ m_bMenuPopupMode = sal_False;
+ if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP )))
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menupopup expected!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ else
+ m_xReader->endElement( aName );
+ }
+}
+
+
+// -----------------------------------------------------------------------------
+
+
+OReadMenuPopupHandler::OReadMenuPopupHandler(
+ const Reference< XIndexContainer >& rMenuContainer,
+ const Reference< XSingleComponentFactory >& rFactory ) :
+ m_nElementDepth( 0 ),
+ m_bMenuMode( sal_False ),
+ m_xMenuContainer( rMenuContainer ),
+ m_xContainerFactory( rFactory ),
+ m_nNextElementExpected( ELEM_CLOSE_NONE )
+{
+}
+
+
+OReadMenuPopupHandler::~OReadMenuPopupHandler()
+{
+}
+
+
+void SAL_CALL OReadMenuPopupHandler::startDocument(void)
+ throw ( SAXException, RuntimeException )
+{
+}
+
+
+void SAL_CALL OReadMenuPopupHandler::endDocument(void)
+ throw( SAXException, RuntimeException)
+{
+}
+
+void SAL_CALL OReadMenuPopupHandler::startElement(
+ const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList )
+throw( SAXException, RuntimeException )
+{
+ ++m_nElementDepth;
+
+ if ( m_bMenuMode )
+ m_xReader->startElement( rName, xAttrList );
+ else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
+ {
+ ::rtl::OUString aHelpId;
+ ::rtl::OUString aCommandId;
+ ::rtl::OUString aLabel;
+ sal_Int16 nItemBits(0);
+
+ m_bMenuMode = sal_True;
+
+ // Container must be factory to create sub container
+ if ( !m_xComponentContext.is() )
+ {
+ const Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
+ m_xComponentContext.set(xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), UNO_QUERY_THROW );
+ }
+
+ Reference< XIndexContainer > xSubItemContainer;
+ if ( m_xContainerFactory.is() )
+ xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( m_xComponentContext ), UNO_QUERY );
+
+ // read attributes for menu
+ for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
+ {
+ ::rtl::OUString aName = xAttrList->getNameByIndex( i );
+ ::rtl::OUString aValue = xAttrList->getValueByIndex( i );
+ if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
+ aCommandId = aValue;
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
+ aLabel = aValue;
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
+ aHelpId = aValue;
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE )))
+ {
+ ::rtl::OUString aTemp( aValue );
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex );
+ if ( aToken.getLength() > 0 )
+ {
+ if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
+ else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
+ else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
+ }
+ }
+ while ( nIndex >= 0 );
+ }
+
+ }
+
+ if ( aCommandId.getLength() > 0 )
+ {
+ Sequence< PropertyValue > aSubMenuProp( 6 );
+ initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits );
+ aSubMenuProp[2].Value <<= xSubItemContainer;
+
+ m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aSubMenuProp ) );
+ }
+ else
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory ));
+ m_xReader->startDocument();
+ }
+ else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM )))
+ {
+ ::rtl::OUString aHelpId;
+ ::rtl::OUString aCommandId;
+ ::rtl::OUString aLabel;
+ sal_Int16 nItemBits(0);
+ // read attributes for menu item
+ for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ )
+ {
+ ::rtl::OUString aName = xAttrList->getNameByIndex( i );
+ ::rtl::OUString aValue = xAttrList->getValueByIndex( i );
+ if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID )))
+ aCommandId = aValue;
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL )))
+ aLabel = aValue;
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID )))
+ aHelpId = aValue;
+ else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE )))
+ {
+ ::rtl::OUString aTemp( aValue );
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex );
+ if ( aToken.getLength() > 0 )
+ {
+ if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
+ else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
+ else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
+ }
+ }
+ while ( nIndex >= 0 );
+ }
+
+ }
+
+ if ( aCommandId.getLength() > 0 )
+ {
+ Sequence< PropertyValue > aMenuItem( 6 );
+ initPropertyCommon( aMenuItem, aCommandId, aHelpId, aLabel, nItemBits );
+ aMenuItem[2].Value <<= Reference< XIndexContainer >();
+
+ m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuItem ) );
+ }
+
+ m_nNextElementExpected = ELEM_CLOSE_MENUITEM;
+ }
+ else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR )))
+ {
+ Sequence< PropertyValue > aMenuSeparator( 1 );
+ aMenuSeparator[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE ));
+ aMenuSeparator[0].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
+
+ m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuSeparator ) );
+
+ m_nNextElementExpected = ELEM_CLOSE_MENUSEPARATOR;
+ }
+ else
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+}
+
+
+void SAL_CALL OReadMenuPopupHandler::characters(const rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+
+void SAL_CALL OReadMenuPopupHandler::endElement( const ::rtl::OUString& aName )
+ throw( SAXException, RuntimeException )
+{
+ --m_nElementDepth;
+ if ( m_bMenuMode )
+ {
+ if ( 0 == m_nElementDepth )
+ {
+ m_xReader->endDocument();
+ m_xReader = Reference< XDocumentHandler >();
+ m_bMenuMode = sal_False;
+ if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU )))
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ else
+ m_xReader->endElement( aName );
+ }
+ else
+ {
+ if ( m_nNextElementExpected == ELEM_CLOSE_MENUITEM )
+ {
+ if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM )))
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuitem expected!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ else if ( m_nNextElementExpected == ELEM_CLOSE_MENUSEPARATOR )
+ {
+ if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR )))
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuseparator expected!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+
+ m_nNextElementExpected = ELEM_CLOSE_NONE;
+ }
+}
+
+
+// --------------------------------- Write XML ---------------------------------
+
+
+OWriteMenuDocumentHandler::OWriteMenuDocumentHandler(
+ const Reference< XIndexAccess >& rMenuBarContainer,
+ const Reference< XDocumentHandler >& rDocumentHandler ) :
+ m_xMenuBarContainer( rMenuBarContainer ),
+ m_xWriteDocumentHandler( rDocumentHandler )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
+ m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
+}
+
+
+OWriteMenuDocumentHandler::~OWriteMenuDocumentHandler()
+{
+}
+
+
+void OWriteMenuDocumentHandler::WriteMenuDocument()
+throw ( SAXException, RuntimeException )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY );
+
+ m_xWriteDocumentHandler->startDocument();
+
+ // write DOCTYPE line!
+ Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
+ if ( xExtendedDocHandler.is() )
+ {
+ xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MENUBAR_DOCTYPE )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ }
+
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_MENU )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_MENU )) );
+
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "menubar" )) );
+
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )), pList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ WriteMenu( m_xMenuBarContainer );
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endDocument();
+}
+
+
+void OWriteMenuDocumentHandler::WriteMenu( const Reference< XIndexAccess >& rMenuContainer )
+throw ( SAXException, RuntimeException )
+{
+ sal_Int32 nItemCount = rMenuContainer->getCount();
+ sal_Bool bSeparator = sal_False;
+ Any aAny;
+
+ for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
+ {
+ Sequence< PropertyValue > aProps;
+ aAny = rMenuContainer->getByIndex( nItemPos );
+ if ( aAny >>= aProps )
+ {
+ ::rtl::OUString aCommandURL;
+ ::rtl::OUString aLabel;
+ ::rtl::OUString aHelpURL;
+ sal_Int16 nType( ::com::sun::star::ui::ItemType::DEFAULT );
+ sal_Int16 nItemBits( 0 );
+ Reference< XIndexAccess > xSubMenu;
+
+ ExtractMenuParameters( aProps, aCommandURL, aLabel, aHelpURL, xSubMenu, nType, nItemBits );
+ if ( xSubMenu.is() )
+ {
+ if ( aCommandURL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ADDDIRECT_CMD)) ||
+ aCommandURL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(AUTOPILOTMENU_CMD)) )
+ {
+ WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
+ bSeparator = sal_False;
+ }
+ else if (( aCommandURL.getLength() > 0 ) && !AddonPopupMenu::IsCommandURLPrefix ( aCommandURL ))
+ {
+ ::comphelper::AttributeList* pListMenu = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xListMenu( (XAttributeList *)pListMenu , UNO_QUERY );
+
+ pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
+ m_aAttributeType,
+ aCommandURL );
+
+ if ( !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(CMD_PROTOCOL))) )
+ pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )),
+ m_aAttributeType,
+ aLabel );
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )), xListMenu );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )), m_xEmptyList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ WriteMenu( xSubMenu );
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ bSeparator = sal_False;
+ }
+ }
+ else
+ {
+ if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
+ {
+ if ( aCommandURL.getLength() > 0 )
+ {
+ bSeparator = sal_False;
+ WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits );
+ }
+ }
+ else if ( !bSeparator )
+ {
+ // Don't write two separators together
+ WriteMenuSeparator();
+ bSeparator = sal_True;
+ }
+ }
+ }
+ }
+}
+
+
+void OWriteMenuDocumentHandler::WriteMenuItem( const ::rtl::OUString& aCommandURL, const ::rtl::OUString& aLabel, const ::rtl::OUString& aHelpURL, sal_Int16 nStyle )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )),
+ m_aAttributeType,
+ aCommandURL );
+
+ if ( aHelpURL.getLength() > 0 )
+ {
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_HELPID )),
+ m_aAttributeType,
+ aHelpURL );
+ }
+
+ if (( aLabel.getLength() > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(CMD_PROTOCOL)) ))
+ {
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )),
+ m_aAttributeType,
+ aLabel );
+ }
+ if (( nStyle > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(CMD_PROTOCOL)) ))
+ {
+ rtl::OUString aValue;
+ MenuStyleItem* pStyle = MenuItemStyles;
+
+ for ( sal_Int32 nIndex = 0; nIndex < nMenuStyleItemEntries; ++nIndex, ++pStyle )
+ {
+ if ( nStyle & pStyle->nBit )
+ {
+ if ( aValue.getLength() )
+ aValue = aValue.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("+") ) );
+ aValue += rtl::OUString::createFromAscii( pStyle->attrName );
+ }
+ }
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_STYLE )),
+ m_aAttributeType,
+ aValue );
+ }
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )), xList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )) );
+}
+
+
+void OWriteMenuDocumentHandler::WriteMenuSeparator()
+{
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )), m_xEmptyList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )) );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/saxnamespacefilter.cxx b/framework/source/fwe/xml/saxnamespacefilter.cxx
new file mode 100644
index 000000000000..18adde4faaf5
--- /dev/null
+++ b/framework/source/fwe/xml/saxnamespacefilter.cxx
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
+ with solaris headers ...
+*/
+#include <vector>
+
+#include <stdio.h>
+
+#include <xml/saxnamespacefilter.hxx>
+
+#include <comphelper/attributelist.hxx>
+
+#include <vcl/svapp.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+
+const ::rtl::OUString aXMLAttributeNamespace( RTL_CONSTASCII_USTRINGPARAM( "xmlns" ));
+const ::rtl::OUString aXMLAttributeType( RTL_CONSTASCII_USTRINGPARAM( "CDATA" ));
+
+namespace framework{
+
+
+SaxNamespaceFilter::SaxNamespaceFilter( Reference< XDocumentHandler >& rSax1DocumentHandler ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_xLocator( 0 ),
+ xDocumentHandler( rSax1DocumentHandler ),
+ m_nDepth( 0 )
+{
+}
+
+SaxNamespaceFilter::~SaxNamespaceFilter()
+{
+}
+
+// XDocumentHandler
+void SAL_CALL SaxNamespaceFilter::startDocument(void)
+ throw ( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL SaxNamespaceFilter::endDocument(void)
+ throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL SaxNamespaceFilter::startElement(
+ const rtl::OUString& rName, const Reference< XAttributeList > &xAttribs )
+ throw( SAXException, RuntimeException )
+{
+ XMLNamespaces aXMLNamespaces;
+ if ( !m_aNamespaceStack.empty() )
+ aXMLNamespaces = m_aNamespaceStack.top();
+
+ ::comphelper::AttributeList* pNewList = new ::comphelper::AttributeList();
+
+ // examine all namespaces for this level
+ ::std::vector< sal_Int16 > aAttributeIndexes;
+ {
+ for ( sal_Int16 i=0; i< xAttribs->getLength(); i++ )
+ {
+ ::rtl::OUString aName = xAttribs->getNameByIndex( i );
+ if ( aName.compareTo( aXMLAttributeNamespace, aXMLAttributeNamespace.getLength() ) == 0 )
+ aXMLNamespaces.addNamespace( aName, xAttribs->getValueByIndex( i ));
+ else
+ aAttributeIndexes.push_back( i );
+ }
+ }
+
+ // current namespaces for this level
+ m_aNamespaceStack.push( aXMLNamespaces );
+
+ try
+ {
+ // apply namespaces to all remaing attributes
+ for ( ::std::vector< sal_Int16 >::const_iterator i(
+ aAttributeIndexes.begin());
+ i != aAttributeIndexes.end(); ++i )
+ {
+ ::rtl::OUString aAttributeName = xAttribs->getNameByIndex( *i );
+ ::rtl::OUString aValue = xAttribs->getValueByIndex( *i );
+ ::rtl::OUString aNamespaceAttributeName = aXMLNamespaces.applyNSToAttributeName( aAttributeName );
+ pNewList->AddAttribute( aNamespaceAttributeName, aXMLAttributeType, aValue );
+ }
+ }
+ catch ( SAXException& e )
+ {
+ e.Message = ::rtl::OUString( getErrorLineString() + e.Message );
+ throw e;
+ }
+
+ ::rtl::OUString aNamespaceElementName;
+
+ try
+ {
+ aNamespaceElementName = aXMLNamespaces.applyNSToElementName( rName );
+ }
+ catch ( SAXException& e )
+ {
+ e.Message = ::rtl::OUString( getErrorLineString() + e.Message );
+ throw e;
+ }
+
+ xDocumentHandler->startElement( aNamespaceElementName, pNewList );
+}
+
+void SAL_CALL SaxNamespaceFilter::endElement(const rtl::OUString& aName)
+ throw( SAXException, RuntimeException )
+{
+ XMLNamespaces& aXMLNamespaces = m_aNamespaceStack.top();
+ ::rtl::OUString aNamespaceElementName;
+
+ try
+ {
+ aNamespaceElementName = aXMLNamespaces.applyNSToElementName( aName );
+ }
+ catch ( SAXException& e )
+ {
+ e.Message = ::rtl::OUString( getErrorLineString() + e.Message );
+ throw e;
+ }
+
+ xDocumentHandler->endElement( aNamespaceElementName );
+ m_aNamespaceStack.pop();
+}
+
+void SAL_CALL SaxNamespaceFilter::characters(const rtl::OUString& aChars)
+ throw( SAXException, RuntimeException )
+{
+ xDocumentHandler->characters( aChars );
+}
+
+void SAL_CALL SaxNamespaceFilter::ignorableWhitespace(const rtl::OUString& aWhitespaces)
+ throw( SAXException, RuntimeException )
+{
+ xDocumentHandler->ignorableWhitespace( aWhitespaces );
+}
+
+void SAL_CALL SaxNamespaceFilter::processingInstruction(
+ const rtl::OUString& aTarget, const rtl::OUString& aData)
+ throw( SAXException, RuntimeException )
+{
+ xDocumentHandler->processingInstruction( aTarget, aData );
+}
+
+void SAL_CALL SaxNamespaceFilter::setDocumentLocator(
+ const Reference< XLocator > &xLocator)
+ throw( SAXException, RuntimeException )
+{
+ m_xLocator = xLocator;
+ xDocumentHandler->setDocumentLocator( xLocator );
+}
+
+::rtl::OUString SaxNamespaceFilter::getErrorLineString()
+{
+ char buffer[32];
+
+ if ( m_xLocator.is() )
+ {
+ snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
+ return ::rtl::OUString::createFromAscii( buffer );
+ }
+ else
+ return ::rtl::OUString();
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/statusbarconfiguration.cxx b/framework/source/fwe/xml/statusbarconfiguration.cxx
new file mode 100644
index 000000000000..52643d238172
--- /dev/null
+++ b/framework/source/fwe/xml/statusbarconfiguration.cxx
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <framework/statusbarconfiguration.hxx>
+#include <xml/statusbardocumenthandler.hxx>
+#include <xml/saxnamespacefilter.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <comphelper/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <tools/debug.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::container;
+
+
+namespace framework
+{
+
+SV_IMPL_PTRARR( StatusBarDescriptor, StatusBarItemDescriptorPtr);
+
+static Reference< XParser > GetSaxParser(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory
+ )
+{
+ return Reference< XParser >( xServiceFactory->createInstance( SERVICENAME_SAXPARSER), UNO_QUERY);
+}
+
+static Reference< XDocumentHandler > GetSaxWriter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory
+ )
+{
+ return Reference< XDocumentHandler >( xServiceFactory->createInstance( SERVICENAME_SAXWRITER), UNO_QUERY) ;
+}
+
+sal_Bool StatusBarConfiguration::LoadStatusBar(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&,
+ SvStream&, StatusBarDescriptor& )
+{
+ // obsolete - only support linkage of binary filters!
+ return sal_True;
+}
+
+sal_Bool StatusBarConfiguration::StoreStatusBar(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&,
+ SvStream&, const StatusBarDescriptor& )
+{
+ // obsolete - only support linkage of binary filters!
+ return sal_True;
+}
+
+sal_Bool StatusBarConfiguration::LoadStatusBar(
+ const Reference< XMultiServiceFactory >& xServiceFactory,
+ const Reference< XInputStream >& xInputStream,
+ const Reference< XIndexContainer >& rStatusbarConfiguration )
+{
+ Reference< XParser > xParser( GetSaxParser( xServiceFactory ) );
+
+ // connect stream to input stream to the parser
+ InputSource aInputSource;
+ aInputSource.aInputStream = xInputStream;
+
+ // create namespace filter and set menudocument handler inside to support xml namespaces
+ Reference< XDocumentHandler > xDocHandler( new OReadStatusBarDocumentHandler( rStatusbarConfiguration ));
+ Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler ));
+
+ // connect parser and filter
+ xParser->setDocumentHandler( xFilter );
+
+ try
+ {
+ xParser->parseStream( aInputSource );
+ return sal_True;
+ }
+ catch ( RuntimeException& )
+ {
+ return sal_False;
+ }
+ catch( SAXException& )
+ {
+ return sal_False;
+ }
+ catch( ::com::sun::star::io::IOException& )
+ {
+ return sal_False;
+ }
+}
+
+sal_Bool StatusBarConfiguration::StoreStatusBar(
+ const Reference< XMultiServiceFactory >& xServiceFactory,
+ const Reference< XOutputStream >& xOutputStream,
+ const Reference< XIndexAccess >& rStatusbarConfiguration )
+{
+ Reference< XDocumentHandler > xWriter( GetSaxWriter( xServiceFactory ) );
+ Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY );
+ xDataSource->setOutputStream( xOutputStream );
+
+ try
+ {
+ OWriteStatusBarDocumentHandler aWriteStatusBarDocumentHandler( rStatusbarConfiguration, xWriter );
+ aWriteStatusBarDocumentHandler.WriteStatusBarDocument();
+ return sal_True;
+ }
+ catch ( RuntimeException& )
+ {
+ return sal_False;
+ }
+ catch ( SAXException& )
+ {
+ return sal_False;
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ return sal_False;
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/statusbardocumenthandler.cxx b/framework/source/fwe/xml/statusbardocumenthandler.cxx
new file mode 100644
index 000000000000..02c0c00aec9e
--- /dev/null
+++ b/framework/source/fwe/xml/statusbardocumenthandler.cxx
@@ -0,0 +1,698 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <stdio.h>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <threadhelp/resetableguard.hxx>
+#include <xml/statusbardocumenthandler.hxx>
+#include <macros/debug.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/ui/ItemStyle.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <vcl/status.hxx>
+
+#include <comphelper/attributelist.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::ui;
+using namespace ::com::sun::star::container;
+
+#define XMLNS_STATUSBAR "http://openoffice.org/2001/statusbar"
+#define XMLNS_XLINK "http://www.w3.org/1999/xlink"
+#define XMLNS_STATUSBAR_PREFIX "statusbar:"
+#define XMLNS_XLINK_PREFIX "xlink:"
+
+#define XMLNS_FILTER_SEPARATOR "^"
+
+#define ELEMENT_STATUSBAR "statusbar"
+#define ELEMENT_STATUSBARITEM "statusbaritem"
+
+#define ATTRIBUTE_ALIGN "align"
+#define ATTRIBUTE_STYLE "style"
+#define ATTRIBUTE_URL "href"
+#define ATTRIBUTE_WIDTH "width"
+#define ATTRIBUTE_OFFSET "offset"
+#define ATTRIBUTE_AUTOSIZE "autosize"
+#define ATTRIBUTE_OWNERDRAW "ownerdraw"
+#define ATTRIBUTE_HELPURL "helpid"
+
+#define ELEMENT_NS_STATUSBAR "statusbar:statusbar"
+#define ELEMENT_NS_STATUSBARITEM "statusbar:statusbaritem"
+
+#define ATTRIBUTE_XMLNS_STATUSBAR "xmlns:statusbar"
+#define ATTRIBUTE_XMLNS_XLINK "xmlns:xlink"
+
+#define ATTRIBUTE_TYPE_CDATA "CDATA"
+
+#define ATTRIBUTE_BOOLEAN_TRUE "true"
+#define ATTRIBUTE_BOOLEAN_FALSE "false"
+
+#define ATTRIBUTE_ALIGN_LEFT "left"
+#define ATTRIBUTE_ALIGN_RIGHT "right"
+#define ATTRIBUTE_ALIGN_CENTER "center"
+
+#define ATTRIBUTE_STYLE_IN "in"
+#define ATTRIBUTE_STYLE_OUT "out"
+#define ATTRIBUTE_STYLE_FLAT "flat"
+
+#define STATUSBAR_DOCTYPE "<!DOCTYPE statusbar:statusbar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"statusbar.dtd\">"
+
+namespace framework
+{
+
+// Property names of a menu/menu item ItemDescriptor
+static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
+static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL";
+static const char ITEM_DESCRIPTOR_OFFSET[] = "Offset";
+static const char ITEM_DESCRIPTOR_STYLE[] = "Style";
+static const char ITEM_DESCRIPTOR_WIDTH[] = "Width";
+static const char ITEM_DESCRIPTOR_TYPE[] = "Type";
+
+static void ExtractStatusbarItemParameters(
+ const Sequence< PropertyValue > rProp,
+ ::rtl::OUString& rCommandURL,
+ ::rtl::OUString& rHelpURL,
+ sal_Int16& rOffset,
+ sal_Int16& rStyle,
+ sal_Int16& rWidth )
+{
+ for ( sal_Int32 i = 0; i < rProp.getLength(); i++ )
+ {
+ if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL ))
+ {
+ rProp[i].Value >>= rCommandURL;
+ rCommandURL = rCommandURL.intern();
+ }
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL ))
+ {
+ rProp[i].Value >>= rHelpURL;
+ }
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_OFFSET ))
+ {
+ rProp[i].Value >>= rOffset;
+ }
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE ))
+ {
+ rProp[i].Value >>= rStyle;
+ }
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_WIDTH ))
+ {
+ rProp[i].Value >>= rWidth;
+ }
+ }
+}
+
+struct StatusBarEntryProperty
+{
+ OReadStatusBarDocumentHandler::StatusBar_XML_Namespace nNamespace;
+ char aEntryName[20];
+};
+
+StatusBarEntryProperty StatusBarEntries[OReadStatusBarDocumentHandler::SB_XML_ENTRY_COUNT] =
+{
+ { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ELEMENT_STATUSBAR },
+ { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ELEMENT_STATUSBARITEM },
+ { OReadStatusBarDocumentHandler::SB_NS_XLINK, ATTRIBUTE_URL },
+ { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_ALIGN },
+ { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_STYLE },
+ { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_AUTOSIZE },
+ { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_OWNERDRAW },
+ { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_WIDTH },
+ { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_OFFSET },
+ { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_HELPURL }
+};
+
+
+OReadStatusBarDocumentHandler::OReadStatusBarDocumentHandler(
+ const Reference< XIndexContainer >& rStatusBarItems ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_aStatusBarItems( rStatusBarItems )
+{
+ ::rtl::OUString aNamespaceStatusBar( RTL_CONSTASCII_USTRINGPARAM( XMLNS_STATUSBAR ));
+ ::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK ));
+ ::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR ));
+
+ // create hash map
+ for ( int i = 0; i < (int)SB_XML_ENTRY_COUNT; i++ )
+ {
+ if ( StatusBarEntries[i].nNamespace == SB_NS_STATUSBAR )
+ {
+ ::rtl::OUString temp( aNamespaceStatusBar );
+ temp += aSeparator;
+ temp += ::rtl::OUString::createFromAscii( StatusBarEntries[i].aEntryName );
+ m_aStatusBarMap.insert( StatusBarHashMap::value_type( temp, (StatusBar_XML_Entry)i ) );
+ }
+ else
+ {
+ ::rtl::OUString temp( aNamespaceXLink );
+ temp += aSeparator;
+ temp += ::rtl::OUString::createFromAscii( StatusBarEntries[i].aEntryName );
+ m_aStatusBarMap.insert( StatusBarHashMap::value_type( temp, (StatusBar_XML_Entry)i ) );
+ }
+ }
+
+ m_bStatusBarStartFound = sal_False;
+ m_bStatusBarEndFound = sal_False;
+ m_bStatusBarItemStartFound = sal_False;
+}
+
+OReadStatusBarDocumentHandler::~OReadStatusBarDocumentHandler()
+{
+}
+
+// XDocumentHandler
+void SAL_CALL OReadStatusBarDocumentHandler::startDocument(void)
+throw ( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadStatusBarDocumentHandler::endDocument(void)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if (( m_bStatusBarStartFound && !m_bStatusBarEndFound ) ||
+ ( !m_bStatusBarStartFound && m_bStatusBarEndFound ) )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'statusbar' found!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+}
+
+void SAL_CALL OReadStatusBarDocumentHandler::startElement(
+ const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ StatusBarHashMap::const_iterator pStatusBarEntry = m_aStatusBarMap.find( aName ) ;
+ if ( pStatusBarEntry != m_aStatusBarMap.end() )
+ {
+ switch ( pStatusBarEntry->second )
+ {
+ case SB_ELEMENT_STATUSBAR:
+ {
+ if ( m_bStatusBarStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'statusbar:statusbar' cannot be embeded into 'statusbar:statusbar'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bStatusBarStartFound = sal_True;
+ }
+ break;
+
+ case SB_ELEMENT_STATUSBARITEM:
+ {
+ if ( !m_bStatusBarStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'statusbar:statusbaritem' must be embeded into element 'statusbar:statusbar'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ if ( m_bStatusBarItemStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element statusbar:statusbaritem is not a container!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ ::rtl::OUString aCommandURL;
+ ::rtl::OUString aHelpURL;
+ sal_Int16 nItemBits( ItemStyle::ALIGN_CENTER|ItemStyle::DRAW_IN3D );
+ sal_Int16 nWidth( 0 );
+ sal_Int16 nOffset( STATUSBAR_OFFSET );
+ sal_Bool bCommandURL( sal_False );
+
+ m_bStatusBarItemStartFound = sal_True;
+ for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
+ {
+ pStatusBarEntry = m_aStatusBarMap.find( xAttribs->getNameByIndex( n ) );
+ if ( pStatusBarEntry != m_aStatusBarMap.end() )
+ {
+ switch ( pStatusBarEntry->second )
+ {
+ case SB_ATTRIBUTE_URL:
+ {
+ bCommandURL = sal_True;
+ aCommandURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case SB_ATTRIBUTE_ALIGN:
+ {
+ if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ALIGN_LEFT )) )
+ {
+ nItemBits |= ItemStyle::ALIGN_LEFT;
+ nItemBits &= ~ItemStyle::ALIGN_CENTER;
+ }
+ else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ALIGN_CENTER )) )
+ {
+ nItemBits |= ItemStyle::ALIGN_CENTER;
+ nItemBits &= ~ItemStyle::ALIGN_LEFT;
+ }
+ else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ALIGN_RIGHT )) )
+ {
+ nItemBits |= ItemStyle::ALIGN_RIGHT;
+ }
+ else
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:align must have one value of 'left','right' or 'center'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ break;
+
+ case SB_ATTRIBUTE_STYLE:
+ {
+ if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE_IN )) )
+ {
+ nItemBits |= ItemStyle::DRAW_IN3D;
+ nItemBits &= ~ItemStyle::DRAW_OUT3D;
+ }
+ else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE_OUT )) )
+ {
+ nItemBits |= ItemStyle::DRAW_OUT3D;
+ nItemBits &= ~ItemStyle::DRAW_IN3D;
+ }
+ else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE_FLAT )) )
+ {
+ nItemBits |= ItemStyle::DRAW_FLAT;
+ }
+ else
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:autosize must have value 'true' or 'false'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ break;
+
+ case SB_ATTRIBUTE_AUTOSIZE:
+ {
+ if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) )
+ nItemBits |= ItemStyle::AUTO_SIZE;
+ else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) )
+ nItemBits &= ~ItemStyle::AUTO_SIZE;
+ else
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:autosize must have value 'true' or 'false'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ break;
+
+ case SB_ATTRIBUTE_OWNERDRAW:
+ {
+ if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) )
+ nItemBits |= ItemStyle::OWNER_DRAW;
+ else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) )
+ nItemBits &= ~ItemStyle::OWNER_DRAW;
+ else
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:ownerdraw must have value 'true' or 'false'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ break;
+
+ case SB_ATTRIBUTE_WIDTH:
+ {
+ nWidth = (sal_Int16)(xAttribs->getValueByIndex( n ).toInt32());
+ }
+ break;
+
+ case SB_ATTRIBUTE_OFFSET:
+ {
+ nOffset = (sal_Int16)(xAttribs->getValueByIndex( n ).toInt32());
+ }
+ break;
+
+ case SB_ATTRIBUTE_HELPURL:
+ {
+ aHelpURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ } // for
+
+ if ( !bCommandURL )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute statusbar:url must have a value!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ else
+ {
+ Sequence< PropertyValue > aStatusbarItemProp( 6 );
+ aStatusbarItemProp[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL ));
+ aStatusbarItemProp[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL ));
+ aStatusbarItemProp[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_OFFSET ));
+ aStatusbarItemProp[3].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE ));
+ aStatusbarItemProp[4].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_WIDTH ));
+ aStatusbarItemProp[5].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE ));
+
+ aStatusbarItemProp[0].Value <<= aCommandURL;
+ aStatusbarItemProp[1].Value <<= aHelpURL;
+ aStatusbarItemProp[2].Value <<= nOffset;
+ aStatusbarItemProp[3].Value <<= nItemBits;
+ aStatusbarItemProp[4].Value <<= nWidth;
+ aStatusbarItemProp[5].Value = makeAny( ::com::sun::star::ui::ItemType::DEFAULT );
+
+ m_aStatusBarItems->insertByIndex( m_aStatusBarItems->getCount(), makeAny( aStatusbarItemProp ) );
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void SAL_CALL OReadStatusBarDocumentHandler::endElement(const ::rtl::OUString& aName)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ StatusBarHashMap::const_iterator pStatusBarEntry = m_aStatusBarMap.find( aName ) ;
+ if ( pStatusBarEntry != m_aStatusBarMap.end() )
+ {
+ switch ( pStatusBarEntry->second )
+ {
+ case SB_ELEMENT_STATUSBAR:
+ {
+ if ( !m_bStatusBarStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'statusbar' found, but no start element 'statusbar'" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bStatusBarStartFound = sal_False;
+ }
+ break;
+
+ case SB_ELEMENT_STATUSBARITEM:
+ {
+ if ( !m_bStatusBarItemStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'statusbar:statusbaritem' found, but no start element 'statusbar:statusbaritem'" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bStatusBarItemStartFound = sal_False;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void SAL_CALL OReadStatusBarDocumentHandler::characters(const ::rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadStatusBarDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadStatusBarDocumentHandler::processingInstruction(
+ const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadStatusBarDocumentHandler::setDocumentLocator(
+ const Reference< XLocator > &xLocator)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ m_xLocator = xLocator;
+}
+
+::rtl::OUString OReadStatusBarDocumentHandler::getErrorLineString()
+{
+ ResetableGuard aGuard( m_aLock );
+
+ char buffer[32];
+
+ if ( m_xLocator.is() )
+ {
+ snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
+ return ::rtl::OUString::createFromAscii( buffer );
+ }
+ else
+ return ::rtl::OUString();
+}
+
+
+//_________________________________________________________________________________________________________________
+// OWriteStatusBarDocumentHandler
+//_________________________________________________________________________________________________________________
+
+OWriteStatusBarDocumentHandler::OWriteStatusBarDocumentHandler(
+ const Reference< XIndexAccess >& aStatusBarItems,
+ const Reference< XDocumentHandler >& rWriteDocumentHandler ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_aStatusBarItems( aStatusBarItems ),
+ m_xWriteDocumentHandler( rWriteDocumentHandler )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
+ m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
+ m_aXMLXlinkNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
+ m_aXMLStatusBarNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_STATUSBAR_PREFIX ));
+}
+
+OWriteStatusBarDocumentHandler::~OWriteStatusBarDocumentHandler()
+{
+}
+
+void OWriteStatusBarDocumentHandler::WriteStatusBarDocument() throw
+( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ m_xWriteDocumentHandler->startDocument();
+
+ // write DOCTYPE line!
+ Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
+ if ( xExtendedDocHandler.is() )
+ {
+ xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATUSBAR_DOCTYPE )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ }
+
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_STATUSBAR )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_STATUSBAR )) );
+
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
+
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBAR )), pList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ sal_Int32 nItemCount = m_aStatusBarItems->getCount();
+ Any aAny;
+
+ for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
+ {
+ Sequence< PropertyValue > aProps;
+ aAny = m_aStatusBarItems->getByIndex( nItemPos );
+ if ( aAny >>= aProps )
+ {
+ ::rtl::OUString aCommandURL;
+ ::rtl::OUString aHelpURL;
+ sal_Int16 nStyle( ItemStyle::ALIGN_CENTER|ItemStyle::DRAW_IN3D );
+ sal_Int16 nWidth( 0 );
+ sal_Int16 nOffset( STATUSBAR_OFFSET );
+
+ ExtractStatusbarItemParameters(
+ aProps,
+ aCommandURL,
+ aHelpURL,
+ nOffset,
+ nStyle,
+ nWidth );
+
+ if ( aCommandURL.getLength() > 0 )
+ WriteStatusBarItem( aCommandURL, aHelpURL, nOffset, nStyle, nWidth );
+ }
+ }
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBAR )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endDocument();
+}
+
+//_________________________________________________________________________________________________________________
+// protected member functions
+//_________________________________________________________________________________________________________________
+
+void OWriteStatusBarDocumentHandler::WriteStatusBarItem(
+ const rtl::OUString& rCommandURL,
+ const rtl::OUString& /*rHelpURL*/,
+ sal_Int16 nOffset,
+ sal_Int16 nStyle,
+ sal_Int16 nWidth )
+throw ( SAXException, RuntimeException )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ if ( m_aAttributeURL.getLength() == 0 )
+ {
+ m_aAttributeURL = m_aXMLXlinkNS;
+ m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL ));
+ }
+
+ // save required attribute (URL)
+ pList->AddAttribute( m_aAttributeURL, m_aAttributeType, rCommandURL );
+
+ // alignment
+ if ( nStyle & ItemStyle::ALIGN_RIGHT )
+ {
+ pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN_RIGHT )) );
+ }
+ else if ( nStyle & ItemStyle::ALIGN_CENTER )
+ {
+ pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN_CENTER )) );
+ }
+ else
+ {
+ pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN_LEFT )) );
+ }
+
+ // style ( SIB_IN is default )
+ if ( nStyle & ItemStyle::DRAW_FLAT )
+ {
+ pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE_FLAT )) );
+ }
+ else if ( nStyle & ItemStyle::DRAW_OUT3D )
+ {
+ pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE_OUT )) );
+ }
+
+ // autosize (default sal_False)
+ if ( nStyle & ItemStyle::AUTO_SIZE )
+ {
+ pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_AUTOSIZE )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) );
+ }
+
+ // ownerdraw (default sal_False)
+ if ( nStyle & ItemStyle::OWNER_DRAW )
+ {
+ pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_OWNERDRAW )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) );
+ }
+
+ // width (default 0)
+ if ( nWidth > 0 )
+ {
+ pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_WIDTH )),
+ m_aAttributeType,
+ ::rtl::OUString::valueOf( (sal_Int32)nWidth ) );
+ }
+
+ // offset (default STATUSBAR_OFFSET)
+ if ( nOffset != STATUSBAR_OFFSET )
+ {
+ pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_OFFSET )),
+ m_aAttributeType,
+ ::rtl::OUString::valueOf( (sal_Int32)nOffset ) );
+ }
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBARITEM )), xList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBARITEM )) );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/toolboxconfiguration.cxx b/framework/source/fwe/xml/toolboxconfiguration.cxx
new file mode 100644
index 000000000000..165694a962a5
--- /dev/null
+++ b/framework/source/fwe/xml/toolboxconfiguration.cxx
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <framework/toolboxconfiguration.hxx>
+#include <xml/toolboxdocumenthandler.hxx>
+#include <xml/saxnamespacefilter.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <comphelper/processfactory.hxx>
+#include <unotools/streamwrap.hxx>
+#include <tools/debug.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::container;
+
+
+namespace framework
+{
+
+static Reference< XParser > GetSaxParser(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory
+ )
+{
+ return Reference< XParser >( xServiceFactory->createInstance( SERVICENAME_SAXPARSER), UNO_QUERY);
+}
+
+static Reference< XDocumentHandler > GetSaxWriter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory
+ )
+{
+ return Reference< XDocumentHandler >( xServiceFactory->createInstance( SERVICENAME_SAXWRITER), UNO_QUERY) ;
+}
+
+sal_Bool ToolBoxConfiguration::LoadToolBox(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rInputStream,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >& rToolbarConfiguration )
+{
+ Reference< XParser > xParser( GetSaxParser( xServiceFactory ) );
+
+ // connect stream to input stream to the parser
+ InputSource aInputSource;
+
+ aInputSource.aInputStream = rInputStream;
+
+ // create namespace filter and set menudocument handler inside to support xml namespaces
+ Reference< XDocumentHandler > xDocHandler( new OReadToolBoxDocumentHandler( rToolbarConfiguration ));
+ Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler ));
+
+ // connect parser and filter
+ xParser->setDocumentHandler( xFilter );
+
+ try
+ {
+ xParser->parseStream( aInputSource );
+ return sal_True;
+ }
+ catch ( RuntimeException& )
+ {
+ return sal_False;
+ }
+ catch( SAXException& )
+ {
+ return sal_False;
+ }
+ catch( ::com::sun::star::io::IOException& )
+ {
+ return sal_False;
+ }
+}
+
+
+sal_Bool ToolBoxConfiguration::StoreToolBox(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& rOutputStream,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& rToolbarConfiguration )
+{
+ Reference< XDocumentHandler > xWriter( GetSaxWriter( xServiceFactory ) );
+
+ Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY );
+ xDataSource->setOutputStream( rOutputStream );
+
+ try
+ {
+ OWriteToolBoxDocumentHandler aWriteToolBoxDocumentHandler( rToolbarConfiguration, xWriter );
+ aWriteToolBoxDocumentHandler.WriteToolBoxDocument();
+ return sal_True;
+ }
+ catch ( RuntimeException& )
+ {
+ return sal_False;
+ }
+ catch ( SAXException& )
+ {
+ return sal_False;
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ return sal_False;
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/toolboxdocumenthandler.cxx b/framework/source/fwe/xml/toolboxdocumenthandler.cxx
new file mode 100644
index 000000000000..71cf378d65bf
--- /dev/null
+++ b/framework/source/fwe/xml/toolboxdocumenthandler.cxx
@@ -0,0 +1,880 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <stdio.h>
+
+#include <threadhelp/resetableguard.hxx>
+#include <xml/toolboxdocumenthandler.hxx>
+#include <macros/debug.hxx>
+#include <xml/toolboxconfigurationdefines.hxx>
+
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/ui/ItemStyle.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <sal/config.h>
+#include <sal/macros.h>
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <comphelper/attributelist.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::xml::sax;
+
+
+#define TOOLBAR_DOCTYPE "<!DOCTYPE toolbar:toolbar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"toolbar.dtd\">"
+
+namespace framework
+{
+
+// Property names of a menu/menu item ItemDescriptor
+static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
+static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL";
+static const char ITEM_DESCRIPTOR_TOOLTIP[] = "Tooltip";
+static const char ITEM_DESCRIPTOR_LABEL[] = "Label";
+static const char ITEM_DESCRIPTOR_TYPE[] = "Type";
+static const char ITEM_DESCRIPTOR_STYLE[] = "Style";
+static const char ITEM_DESCRIPTOR_VISIBLE[] = "IsVisible";
+static const char ITEM_DESCRIPTOR_WIDTH[] = "Width";
+
+static void ExtractToolbarParameters( const Sequence< PropertyValue > rProp,
+ ::rtl::OUString& rCommandURL,
+ ::rtl::OUString& rLabel,
+ ::rtl::OUString& rHelpURL,
+ ::rtl::OUString& rTooltip,
+ sal_Int16& rStyle,
+ sal_Int16& rWidth,
+ sal_Bool& rVisible,
+ sal_Int16& rType )
+{
+ for ( sal_Int32 i = 0; i < rProp.getLength(); i++ )
+ {
+ if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL ))
+ {
+ rProp[i].Value >>= rCommandURL;
+ rCommandURL = rCommandURL.intern();
+ }
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL ))
+ rProp[i].Value >>= rHelpURL;
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TOOLTIP ))
+ rProp[i].Value >>= rTooltip;
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL ))
+ rProp[i].Value >>= rLabel;
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE ))
+ rProp[i].Value >>= rType;
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_VISIBLE ))
+ rProp[i].Value >>= rVisible;
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_WIDTH ))
+ rProp[i].Value >>= rWidth;
+ else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE ))
+ rProp[i].Value >>= rStyle;
+ }
+}
+
+struct ToolboxStyleItem
+{
+ sal_Int16 nBit;
+ const char* attrName;
+};
+
+ToolboxStyleItem Styles[ ] = {
+ { ::com::sun::star::ui::ItemStyle::RADIO_CHECK, ATTRIBUTE_ITEMSTYLE_RADIO },
+ { ::com::sun::star::ui::ItemStyle::ALIGN_LEFT, ATTRIBUTE_ITEMSTYLE_LEFT },
+ { ::com::sun::star::ui::ItemStyle::AUTO_SIZE, ATTRIBUTE_ITEMSTYLE_AUTO },
+ { ::com::sun::star::ui::ItemStyle::REPEAT, ATTRIBUTE_ITEMSTYLE_REPEAT },
+ { ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY, ATTRIBUTE_ITEMSTYLE_DROPDOWNONLY },
+ { ::com::sun::star::ui::ItemStyle::DROP_DOWN, ATTRIBUTE_ITEMSTYLE_DROPDOWN },
+ { ::com::sun::star::ui::ItemStyle::ICON, ATTRIBUTE_ITEMSTYLE_IMAGE },
+ { ::com::sun::star::ui::ItemStyle::TEXT, ATTRIBUTE_ITEMSTYLE_TEXT },
+};
+
+sal_Int32 nStyleItemEntries = SAL_N_ELEMENTS( Styles );
+
+struct ToolBarEntryProperty
+{
+ OReadToolBoxDocumentHandler::ToolBox_XML_Namespace nNamespace;
+ char aEntryName[20];
+};
+
+ToolBarEntryProperty ToolBoxEntries[OReadToolBoxDocumentHandler::TB_XML_ENTRY_COUNT] =
+{
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ELEMENT_TOOLBAR },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ELEMENT_TOOLBARITEM },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ELEMENT_TOOLBARSPACE },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ELEMENT_TOOLBARBREAK },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ELEMENT_TOOLBARSEPARATOR },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_TEXT },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_BITMAP },
+ { OReadToolBoxDocumentHandler::TB_NS_XLINK, ATTRIBUTE_URL },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_ITEMBITS },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_VISIBLE },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_WIDTH },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_USER },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_HELPID },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_ITEMSTYLE },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_UINAME },
+ { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_TOOLTIP },
+};
+
+OReadToolBoxDocumentHandler::OReadToolBoxDocumentHandler( const Reference< XIndexContainer >& rItemContainer ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_rItemContainer( rItemContainer ),
+ m_aType( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )),
+ m_aLabel( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL )),
+ m_aStyle( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE )),
+ m_aHelpURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL )),
+ m_aTooltip( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TOOLTIP )),
+ m_aIsVisible( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_VISIBLE )),
+ m_aCommandURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL ))
+ {
+ ::rtl::OUString aNamespaceToolBar( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR ));
+ ::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK ));
+ ::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR ));
+
+ // create hash map
+ for ( int i = 0; i < (int)TB_XML_ENTRY_COUNT; i++ )
+ {
+ if ( ToolBoxEntries[i].nNamespace == TB_NS_TOOLBAR )
+ {
+ ::rtl::OUString temp( aNamespaceToolBar );
+ temp += aSeparator;
+ temp += ::rtl::OUString::createFromAscii( ToolBoxEntries[i].aEntryName );
+ m_aToolBoxMap.insert( ToolBoxHashMap::value_type( temp, (ToolBox_XML_Entry)i ) );
+ }
+ else
+ {
+ ::rtl::OUString temp( aNamespaceXLink );
+ temp += aSeparator;
+ temp += ::rtl::OUString::createFromAscii( ToolBoxEntries[i].aEntryName );
+ m_aToolBoxMap.insert( ToolBoxHashMap::value_type( temp, (ToolBox_XML_Entry)i ) );
+ }
+ }
+
+ // pre-calculate a hash code for all style strings to speed up xml read process
+ m_nHashCode_Style_Radio = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO )).hashCode();
+ m_nHashCode_Style_Auto = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE_AUTO )).hashCode();
+ m_nHashCode_Style_Left = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE_LEFT )).hashCode();
+ m_nHashCode_Style_AutoSize = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE_AUTOSIZE )).hashCode();
+ m_nHashCode_Style_DropDown = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE_DROPDOWN )).hashCode();
+ m_nHashCode_Style_Repeat = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE_REPEAT )).hashCode();
+ m_nHashCode_Style_DropDownOnly = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE_DROPDOWNONLY )).hashCode();
+ m_nHashCode_Style_Text = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT )).hashCode();
+ m_nHashCode_Style_Image = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE )).hashCode();
+
+ m_bToolBarStartFound = sal_False;
+ m_bToolBarEndFound = sal_False;
+ m_bToolBarItemStartFound = sal_False;
+ m_bToolBarSpaceStartFound = sal_False;
+ m_bToolBarBreakStartFound = sal_False;
+ m_bToolBarSeparatorStartFound = sal_False;
+}
+
+OReadToolBoxDocumentHandler::~OReadToolBoxDocumentHandler()
+{
+}
+
+// XDocumentHandler
+void SAL_CALL OReadToolBoxDocumentHandler::startDocument(void)
+throw ( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadToolBoxDocumentHandler::endDocument(void)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if (( m_bToolBarStartFound && !m_bToolBarEndFound ) ||
+ ( !m_bToolBarStartFound && m_bToolBarEndFound ) )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'toolbar' found!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+}
+
+void SAL_CALL OReadToolBoxDocumentHandler::startElement(
+ const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ ToolBoxHashMap::const_iterator pToolBoxEntry = m_aToolBoxMap.find( aName ) ;
+ if ( pToolBoxEntry != m_aToolBoxMap.end() )
+ {
+ switch ( pToolBoxEntry->second )
+ {
+ case TB_ELEMENT_TOOLBAR:
+ {
+ if ( m_bToolBarStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'toolbar:toolbar' cannot be embeded into 'toolbar:toolbar'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ else
+ {
+ // Check if we have a UI name set in our XML file
+ ::rtl::OUString aUIName;
+ for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
+ {
+ pToolBoxEntry = m_aToolBoxMap.find( xAttribs->getNameByIndex( n ) );
+ if ( pToolBoxEntry != m_aToolBoxMap.end() )
+ {
+ switch ( pToolBoxEntry->second )
+ {
+ case TB_ATTRIBUTE_UINAME:
+ aUIName = xAttribs->getValueByIndex( n );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if ( aUIName.getLength() > 0 )
+ {
+ // Try to set UI name as a container property
+ Reference< XPropertySet > xPropSet( m_rItemContainer, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" )), makeAny( aUIName ) );
+ }
+ catch ( UnknownPropertyException& )
+ {
+ }
+ }
+ }
+ }
+
+ m_bToolBarStartFound = sal_True;
+ }
+ break;
+
+ case TB_ELEMENT_TOOLBARITEM:
+ {
+ if ( !m_bToolBarStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'toolbar:toolbaritem' must be embeded into element 'toolbar:toolbar'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ if ( m_bToolBarSeparatorStartFound ||
+ m_bToolBarBreakStartFound ||
+ m_bToolBarSpaceStartFound ||
+ m_bToolBarItemStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbaritem is not a container!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ ::rtl::OUString aAttribute;
+ sal_Bool bAttributeURL = sal_False;
+
+ m_bToolBarItemStartFound = sal_True;
+ ::rtl::OUString aLabel;
+ ::rtl::OUString aCommandURL;
+ ::rtl::OUString aHelpURL;
+ ::rtl::OUString aTooltip;
+ ::rtl::OUString aBitmapName;
+ sal_uInt16 nItemBits( 0 );
+ sal_Bool bVisible( sal_True );
+
+ for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ )
+ {
+ pToolBoxEntry = m_aToolBoxMap.find( xAttribs->getNameByIndex( n ) );
+ if ( pToolBoxEntry != m_aToolBoxMap.end() )
+ {
+ switch ( pToolBoxEntry->second )
+ {
+ case TB_ATTRIBUTE_TEXT:
+ {
+ aLabel = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case TB_ATTRIBUTE_BITMAP:
+ {
+ aBitmapName = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case TB_ATTRIBUTE_URL:
+ {
+ bAttributeURL = sal_True;
+ aCommandURL = xAttribs->getValueByIndex( n ).intern();
+ }
+ break;
+
+ case TB_ATTRIBUTE_ITEMBITS:
+ {
+ nItemBits = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32());
+ }
+ break;
+
+ case TB_ATTRIBUTE_VISIBLE:
+ {
+ if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) )
+ bVisible = sal_True;
+ else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) )
+ bVisible = sal_False;
+ else
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute toolbar:visible must have value 'true' or 'false'!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ break;
+
+ case TB_ATTRIBUTE_HELPID:
+ {
+ aHelpURL = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case TB_ATTRIBUTE_TOOLTIP:
+ {
+ aTooltip = xAttribs->getValueByIndex( n );
+ }
+ break;
+
+ case TB_ATTRIBUTE_STYLE:
+ {
+ // read space seperated item style list
+ ::rtl::OUString aTemp = xAttribs->getValueByIndex( n );
+ sal_Int32 nIndex = 0;
+
+ do
+ {
+ ::rtl::OUString aToken = aTemp.getToken( 0, ' ', nIndex );
+ if ( aToken.getLength() > 0 )
+ {
+ sal_Int32 nHashCode = aToken.hashCode();
+ if ( nHashCode == m_nHashCode_Style_Radio )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK;
+ else if ( nHashCode == m_nHashCode_Style_Left )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::ALIGN_LEFT;
+ else if ( nHashCode == m_nHashCode_Style_AutoSize )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::AUTO_SIZE;
+ else if ( nHashCode == m_nHashCode_Style_DropDown )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::DROP_DOWN;
+ else if ( nHashCode == m_nHashCode_Style_Repeat )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::REPEAT;
+ else if ( nHashCode == m_nHashCode_Style_DropDownOnly )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY;
+ else if ( nHashCode == m_nHashCode_Style_DropDown )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::DROP_DOWN;
+ else if ( nHashCode == m_nHashCode_Style_Text )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT;
+ else if ( nHashCode == m_nHashCode_Style_Image )
+ nItemBits |= ::com::sun::star::ui::ItemStyle::ICON;
+ }
+ }
+ while ( nIndex >= 0 );
+ }
+ break;
+ case TB_ATTRIBUTE_USER:
+ case TB_ATTRIBUTE_WIDTH:
+ default:
+ break;
+ }
+ }
+ } // for
+
+ if ( !bAttributeURL )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute toolbar:url must have a value!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ if ( aCommandURL.getLength() > 0 )
+ {
+ Sequence< PropertyValue > aToolbarItemProp( 7 );
+ aToolbarItemProp[0].Name = m_aCommandURL;
+ aToolbarItemProp[1].Name = m_aHelpURL;
+ aToolbarItemProp[2].Name = m_aLabel;
+ aToolbarItemProp[3].Name = m_aType;
+ aToolbarItemProp[4].Name = m_aStyle;
+ aToolbarItemProp[5].Name = m_aIsVisible;
+ aToolbarItemProp[6].Name = m_aTooltip;
+
+ aToolbarItemProp[0].Value <<= aCommandURL;
+ aToolbarItemProp[1].Value <<= aHelpURL;
+ aToolbarItemProp[2].Value <<= aLabel;
+ aToolbarItemProp[3].Value = makeAny( ::com::sun::star::ui::ItemType::DEFAULT );
+ aToolbarItemProp[4].Value <<= nItemBits;
+ aToolbarItemProp[5].Value <<= bVisible;
+ aToolbarItemProp[6].Value <<= aTooltip;
+
+ m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
+ }
+ }
+ break;
+
+ case TB_ELEMENT_TOOLBARSPACE:
+ {
+ if ( m_bToolBarSeparatorStartFound ||
+ m_bToolBarBreakStartFound ||
+ m_bToolBarSpaceStartFound ||
+ m_bToolBarItemStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarspace is not a container!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bToolBarSpaceStartFound = sal_True;
+
+ Sequence< PropertyValue > aToolbarItemProp( 2 );
+ aToolbarItemProp[0].Name = m_aCommandURL;
+ aToolbarItemProp[1].Name = m_aType;
+
+ aToolbarItemProp[0].Value <<= rtl::OUString();
+ aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_SPACE;
+
+ m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
+ }
+ break;
+
+ case TB_ELEMENT_TOOLBARBREAK:
+ {
+ if ( m_bToolBarSeparatorStartFound ||
+ m_bToolBarBreakStartFound ||
+ m_bToolBarSpaceStartFound ||
+ m_bToolBarItemStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarbreak is not a container!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bToolBarBreakStartFound = sal_True;
+
+ Sequence< PropertyValue > aToolbarItemProp( 2 );
+ aToolbarItemProp[0].Name = m_aCommandURL;
+ aToolbarItemProp[1].Name = m_aType;
+
+ aToolbarItemProp[0].Value <<= rtl::OUString();
+ aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK;
+
+ m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
+ }
+ break;
+
+ case TB_ELEMENT_TOOLBARSEPARATOR:
+ {
+ if ( m_bToolBarSeparatorStartFound ||
+ m_bToolBarBreakStartFound ||
+ m_bToolBarSpaceStartFound ||
+ m_bToolBarItemStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarseparator is not a container!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bToolBarSeparatorStartFound = sal_True;
+
+ Sequence< PropertyValue > aToolbarItemProp( 2 );
+ aToolbarItemProp[0].Name = m_aCommandURL;
+ aToolbarItemProp[1].Name = m_aType;
+
+ aToolbarItemProp[0].Value <<= rtl::OUString();
+ aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE;
+
+ m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) );
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void SAL_CALL OReadToolBoxDocumentHandler::endElement(const ::rtl::OUString& aName)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ ToolBoxHashMap::const_iterator pToolBoxEntry = m_aToolBoxMap.find( aName ) ;
+ if ( pToolBoxEntry != m_aToolBoxMap.end() )
+ {
+ switch ( pToolBoxEntry->second )
+ {
+ case TB_ELEMENT_TOOLBAR:
+ {
+ if ( !m_bToolBarStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar' found, but no start element 'toolbar'" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bToolBarStartFound = sal_False;
+ }
+ break;
+
+ case TB_ELEMENT_TOOLBARITEM:
+ {
+ if ( !m_bToolBarItemStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbaritem' found, but no start element 'toolbar:toolbaritem'" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bToolBarItemStartFound = sal_False;
+ }
+ break;
+
+ case TB_ELEMENT_TOOLBARBREAK:
+ {
+ if ( !m_bToolBarBreakStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarbreak' found, but no start element 'toolbar:toolbarbreak'" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bToolBarBreakStartFound = sal_False;
+ }
+ break;
+
+ case TB_ELEMENT_TOOLBARSPACE:
+ {
+ if ( !m_bToolBarSpaceStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarspace' found, but no start element 'toolbar:toolbarspace'" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bToolBarSpaceStartFound = sal_False;
+ }
+ break;
+
+ case TB_ELEMENT_TOOLBARSEPARATOR:
+ {
+ if ( !m_bToolBarSeparatorStartFound )
+ {
+ ::rtl::OUString aErrorMessage = getErrorLineString();
+ aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarseparator' found, but no start element 'toolbar:toolbarseparator'" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+
+ m_bToolBarSeparatorStartFound = sal_False;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void SAL_CALL OReadToolBoxDocumentHandler::characters(const ::rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadToolBoxDocumentHandler::ignorableWhitespace(const ::rtl::OUString&)
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadToolBoxDocumentHandler::processingInstruction(
+ const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
+throw( SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL OReadToolBoxDocumentHandler::setDocumentLocator(
+ const Reference< XLocator > &xLocator)
+throw( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ m_xLocator = xLocator;
+}
+
+::rtl::OUString OReadToolBoxDocumentHandler::getErrorLineString()
+{
+ ResetableGuard aGuard( m_aLock );
+
+ char buffer[32];
+
+ if ( m_xLocator.is() )
+ {
+ snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() ));
+ return ::rtl::OUString::createFromAscii( buffer );
+ }
+ else
+ return ::rtl::OUString();
+}
+
+
+//_________________________________________________________________________________________________________________
+// OWriteToolBoxDocumentHandler
+//_________________________________________________________________________________________________________________
+
+OWriteToolBoxDocumentHandler::OWriteToolBoxDocumentHandler(
+ const Reference< XIndexAccess >& rItemAccess,
+ Reference< XDocumentHandler >& rWriteDocumentHandler ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_xWriteDocumentHandler( rWriteDocumentHandler ),
+ m_rItemAccess( rItemAccess )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY );
+ m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA ));
+ m_aXMLXlinkNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX ));
+ m_aXMLToolbarNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR_PREFIX ));
+}
+
+OWriteToolBoxDocumentHandler::~OWriteToolBoxDocumentHandler()
+{
+}
+
+void OWriteToolBoxDocumentHandler::WriteToolBoxDocument() throw
+( SAXException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ m_xWriteDocumentHandler->startDocument();
+
+ // write DOCTYPE line!
+ Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY );
+ if ( xExtendedDocHandler.is() )
+ {
+ xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( TOOLBAR_DOCTYPE )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ }
+
+ ::rtl::OUString aUIName;
+ Reference< XPropertySet > xPropSet( m_rItemAccess, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= aUIName;
+ }
+ catch ( UnknownPropertyException& )
+ {
+ }
+ }
+
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_TOOLBAR )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR )) );
+
+ pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) );
+
+ if ( aUIName.getLength() > 0 )
+ pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_UINAME )),
+ m_aAttributeType,
+ aUIName );
+
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBAR )), pList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+
+ sal_Int32 nItemCount = m_rItemAccess->getCount();
+ Any aAny;
+
+ for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ )
+ {
+ Sequence< PropertyValue > aProps;
+ aAny = m_rItemAccess->getByIndex( nItemPos );
+ if ( aAny >>= aProps )
+ {
+ ::rtl::OUString aCommandURL;
+ ::rtl::OUString aLabel;
+ ::rtl::OUString aHelpURL;
+ ::rtl::OUString aTooltip;
+ sal_Bool bVisible( sal_True );
+ sal_Int16 nType( ::com::sun::star::ui::ItemType::DEFAULT );
+ sal_Int16 nWidth( 0 );
+ sal_Int16 nStyle( 0 );
+
+ ExtractToolbarParameters( aProps, aCommandURL, aLabel, aHelpURL, aTooltip, nStyle, nWidth, bVisible, nType );
+ if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
+ WriteToolBoxItem( aCommandURL, aLabel, aHelpURL, aTooltip, nStyle, nWidth, bVisible );
+ else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_SPACE )
+ WriteToolBoxSpace();
+ else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINE )
+ WriteToolBoxSeparator();
+ else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK )
+ WriteToolBoxBreak();
+ }
+ }
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBAR )) );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endDocument();
+}
+
+//_________________________________________________________________________________________________________________
+// protected member functions
+//_________________________________________________________________________________________________________________
+
+void OWriteToolBoxDocumentHandler::WriteToolBoxItem(
+ const ::rtl::OUString& rCommandURL,
+ const ::rtl::OUString& rLabel,
+ const ::rtl::OUString& rHelpURL,
+ const ::rtl::OUString& rTooltip,
+ sal_Int16 nStyle,
+ sal_Int16 nWidth,
+ sal_Bool bVisible )
+throw ( SAXException, RuntimeException )
+{
+ ::comphelper::AttributeList* pList = new ::comphelper::AttributeList;
+ Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY );
+
+ if ( m_aAttributeURL.getLength() == 0 )
+ {
+ m_aAttributeURL = m_aXMLXlinkNS;
+ m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL ));
+ }
+
+ // save required attribute (URL)
+ pList->AddAttribute( m_aAttributeURL, m_aAttributeType, rCommandURL );
+
+ if ( rLabel.getLength() > 0 )
+ {
+ pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TEXT )),
+ m_aAttributeType,
+ rLabel );
+ }
+
+ if ( bVisible == sal_False )
+ {
+ pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_VISIBLE )),
+ m_aAttributeType,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) );
+ }
+
+ if ( rHelpURL.getLength() > 0 )
+ {
+ pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HELPID )),
+ m_aAttributeType,
+ rHelpURL );
+ }
+
+ if ( rTooltip.getLength() > 0 )
+ {
+ pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TOOLTIP )),
+ m_aAttributeType,
+ rTooltip );
+ }
+
+ if ( nStyle > 0 )
+ {
+ rtl::OUString aValue;
+ ToolboxStyleItem* pStyle = Styles;
+
+ for ( sal_Int32 nIndex = 0; nIndex < nStyleItemEntries; ++nIndex, ++pStyle )
+ {
+ if ( nStyle & pStyle->nBit )
+ {
+ if ( aValue.getLength() )
+ aValue = aValue.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" ") ) );
+ aValue += rtl::OUString::createFromAscii( pStyle->attrName );
+ }
+ }
+ pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE )),
+ m_aAttributeType,
+ aValue );
+ }
+
+ if ( nWidth > 0 )
+ {
+ pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_WIDTH )),
+ m_aAttributeType,
+ ::rtl::OUString::valueOf( sal_Int32( nWidth )) );
+ }
+
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARITEM )), xList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARITEM )) );
+}
+
+void OWriteToolBoxDocumentHandler::WriteToolBoxSpace() throw
+( SAXException, RuntimeException )
+{
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSPACE )), m_xEmptyList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSPACE )) );
+}
+
+void OWriteToolBoxDocumentHandler::WriteToolBoxBreak() throw
+( SAXException, RuntimeException )
+{
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARBREAK )), m_xEmptyList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARBREAK )) );
+}
+
+void OWriteToolBoxDocumentHandler::WriteToolBoxSeparator() throw
+( SAXException, RuntimeException )
+{
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSEPARATOR )), m_xEmptyList );
+ m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() );
+ m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSEPARATOR )) );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwe/xml/toolboxlayoutdocumenthandler.cxx b/framework/source/fwe/xml/toolboxlayoutdocumenthandler.cxx
new file mode 100644
index 000000000000..645750dc3f51
--- /dev/null
+++ b/framework/source/fwe/xml/toolboxlayoutdocumenthandler.cxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <stdio.h>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <threadhelp/resetableguard.hxx>
+#include <xml/toolboxlayoutdocumenthandler.hxx>
+#include <macros/debug.hxx>
+#include <xml/toolboxconfigurationdefines.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#ifndef __COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#endif
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
diff --git a/framework/source/fwe/xml/xmlnamespaces.cxx b/framework/source/fwe/xml/xmlnamespaces.cxx
new file mode 100644
index 000000000000..2352192138b2
--- /dev/null
+++ b/framework/source/fwe/xml/xmlnamespaces.cxx
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <xml/xmlnamespaces.hxx>
+
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+
+const ::rtl::OUString aXMLAttributeNamespace( RTL_CONSTASCII_USTRINGPARAM( "xmlns" ));
+
+namespace framework
+{
+
+XMLNamespaces::XMLNamespaces()
+{
+}
+
+XMLNamespaces::XMLNamespaces( const XMLNamespaces& aXMLNamespaces )
+{
+ m_aDefaultNamespace = aXMLNamespaces.m_aDefaultNamespace;
+ m_aNamespaceMap = aXMLNamespaces.m_aNamespaceMap;
+}
+
+XMLNamespaces::~XMLNamespaces()
+{
+}
+
+void XMLNamespaces::addNamespace( const ::rtl::OUString& aName, const ::rtl::OUString& aValue ) throw( SAXException )
+{
+ NamespaceMap::iterator p;
+ ::rtl::OUString aNamespaceName( aName );
+ sal_Int32 nXMLNamespaceLength = aXMLAttributeNamespace.getLength();
+
+ // delete preceding "xmlns"
+ if ( aNamespaceName.compareTo( aXMLAttributeNamespace, nXMLNamespaceLength ) == 0 )
+ {
+ if ( aNamespaceName.getLength() == nXMLNamespaceLength )
+ {
+ aNamespaceName = ::rtl::OUString();
+ }
+ else if ( aNamespaceName.getLength() >= nXMLNamespaceLength+2 )
+ {
+ aNamespaceName = aNamespaceName.copy( nXMLNamespaceLength+1 );
+ }
+ else
+ {
+ // a xml namespace without name is not allowed (e.g. "xmlns:" )
+ ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "A xml namespace without name is not allowed!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+
+ if ( aValue.getLength() == 0 && aNamespaceName.getLength() > 0 )
+ {
+ // namespace should be reseted - as xml draft states this is only allowed
+ // for the default namespace - check and throw exception if check fails
+ ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Clearing xml namespace only allowed for default namespace!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ else
+ {
+ if ( aNamespaceName.getLength() == 0 )
+ m_aDefaultNamespace = aValue;
+ else
+ {
+ p = m_aNamespaceMap.find( aNamespaceName );
+ if ( p != m_aNamespaceMap.end() )
+ {
+ // replace current namespace definition
+ m_aNamespaceMap.erase( p );
+ m_aNamespaceMap.insert( NamespaceMap::value_type( aNamespaceName, aValue ));
+ }
+ else
+ {
+ m_aNamespaceMap.insert( NamespaceMap::value_type( aNamespaceName, aValue ));
+ }
+ }
+ }
+}
+
+::rtl::OUString XMLNamespaces::applyNSToAttributeName( const ::rtl::OUString& aName ) const throw( SAXException )
+{
+ // xml draft: there is no default namespace for attributes!
+
+ int index;
+ if (( index = aName.indexOf( ':' )) > 0 )
+ {
+ if ( aName.getLength() > index+1 )
+ {
+ ::rtl::OUString aAttributeName = getNamespaceValue( aName.copy( 0, index ) );
+ aAttributeName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("^"));
+ aAttributeName += aName.copy( index+1 );
+ return aAttributeName;
+ }
+ else
+ {
+ // attribute with namespace but without name "namespace:" is not allowed!!
+ ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Attribute has no name only preceding namespace!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+
+ return aName;
+}
+
+::rtl::OUString XMLNamespaces::applyNSToElementName( const ::rtl::OUString& aName ) const throw( SAXException )
+{
+ // xml draft: element names can have a default namespace
+
+ int index = aName.indexOf( ':' );
+ ::rtl::OUString aNamespace;
+ ::rtl::OUString aElementName = aName;
+
+ if ( index > 0 )
+ aNamespace = getNamespaceValue( aName.copy( 0, index ) );
+ else
+ aNamespace = m_aDefaultNamespace;
+
+ if ( aNamespace.getLength() > 0 )
+ {
+ aElementName = aNamespace;
+ aElementName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("^"));
+ }
+ else
+ return aName;
+
+ if ( index > 0 )
+ {
+ if ( aName.getLength() > index+1 )
+ aElementName += aName.copy( index+1 );
+ else
+ {
+ // attribute with namespace but without a name is not allowed (e.g. "cfg:" )
+ ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Attribute has no name only preceding namespace!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+ else
+ aElementName += aName;
+
+ return aElementName;
+}
+
+::rtl::OUString XMLNamespaces::getNamespaceValue( const ::rtl::OUString& aNamespace ) const throw( SAXException )
+{
+ if ( aNamespace.getLength() == 0 )
+ return m_aDefaultNamespace;
+ else
+ {
+ NamespaceMap::const_iterator p;
+ p = m_aNamespaceMap.find( aNamespace );
+ if ( p != m_aNamespaceMap.end() )
+ return p->second;
+ else
+ {
+ // namespace not defined => throw exception!
+ ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "XML namespace used but not defined!" ));
+ throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
+ }
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/classes/converter.cxx b/framework/source/fwi/classes/converter.cxx
new file mode 100644
index 000000000000..e824d5471ff4
--- /dev/null
+++ b/framework/source/fwi/classes/converter.cxx
@@ -0,0 +1,319 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <classes/converter.hxx>
+#include <rtl/ustrbuf.hxx>
+
+namespace framework{
+
+//-----------------------------------------------------------------------------
+/**
+ * pack every property item of source list into an any entry of destination list
+ * Resulting list will have follow format then: "sequence< Any(PropertyValue) >".
+ * If one item couldn't be converted it will be ignored - means target list can
+ * be smaller then source list. Source list isn't changed anytime.
+ *
+ * algorithm:
+ * (a) reserve enough space on destination list for all possible entries of
+ * source list
+ * (b) try to pack every property of source into an any of destination list
+ * (b1) count successfully packed entries only
+ * (c) use this count of packed entries to resize destination list
+ * Because we getted enough space before - that will remove unused items
+ * of destination list at the end of it only.
+ */
+css::uno::Sequence< css::uno::Any > Converter::convert_seqProp2seqAny( const css::uno::Sequence< css::beans::PropertyValue >& lSource )
+{
+ sal_Int32 nCount = lSource.getLength();
+ css::uno::Sequence< css::uno::Any > lDestination(nCount);
+
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem)
+ lDestination[nItem]<<=lSource[nItem];
+
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * do the same like convert_seqProp2seqAny() before - but reverse.
+ * It try to unpack PropertyValue items from given Any's.
+ */
+css::uno::Sequence< css::beans::PropertyValue > Converter::convert_seqAny2seqProp( const css::uno::Sequence< css::uno::Any >& lSource )
+{
+ sal_Int32 nCount = lSource.getLength();
+ sal_Int32 nRealCount = 0;
+ css::uno::Sequence< css::beans::PropertyValue > lDestination(nCount);
+
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem)
+ {
+ if (lSource[nItem]>>=lDestination[nItem])
+ ++nRealCount;
+ }
+
+ if (nRealCount!=nCount)
+ lDestination.realloc(nRealCount);
+
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts a sequence of NamedValue to a sequence of PropertyValue.
+ */
+css::uno::Sequence< css::beans::PropertyValue > Converter::convert_seqNamedVal2seqPropVal( const css::uno::Sequence< css::beans::NamedValue >& lSource )
+{
+ sal_Int32 nCount = lSource.getLength();
+ css::uno::Sequence< css::beans::PropertyValue > lDestination(nCount);
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem)
+ {
+ lDestination[nItem].Name = lSource[nItem].Name ;
+ lDestination[nItem].Value = lSource[nItem].Value;
+ }
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts a sequence of PropertyValue to a sequence of NamedValue.
+ */
+css::uno::Sequence< css::beans::NamedValue > Converter::convert_seqPropVal2seqNamedVal( const css::uno::Sequence< css::beans::PropertyValue >& lSource )
+{
+ sal_Int32 nCount = lSource.getLength();
+ css::uno::Sequence< css::beans::NamedValue > lDestination(nCount);
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem)
+ {
+ lDestination[nItem].Name = lSource[nItem].Name ;
+ lDestination[nItem].Value = lSource[nItem].Value;
+ }
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts a sequence of unicode strings into a vector of such items
+ */
+OUStringList Converter::convert_seqOUString2OUStringList( const css::uno::Sequence< ::rtl::OUString >& lSource )
+{
+ OUStringList lDestination;
+ sal_Int32 nCount = lSource.getLength();
+
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem )
+ {
+ lDestination.push_back(lSource[nItem]);
+ }
+
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts a vector of unicode strings into a sequence of such items
+ */
+css::uno::Sequence< ::rtl::OUString > Converter::convert_OUStringList2seqOUString( const OUStringList& lSource )
+{
+ css::uno::Sequence< ::rtl::OUString > lDestination(lSource.size());
+ sal_uInt32 nItem = 0;
+ for (OUStringList::const_iterator pIterator=lSource.begin(); pIterator!=lSource.end(); ++pIterator)
+ {
+ lDestination[nItem] = *pIterator;
+ ++nItem;
+ }
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts an unicode string hash to a sequence<PropertyValue>, where names and values match to key and values.
+ */
+css::uno::Sequence< css::beans::PropertyValue > Converter::convert_OUStringHash2seqProp( const OUStringHash& lSource )
+{
+ css::uno::Sequence< css::beans::PropertyValue > lDestination (lSource.size());
+ css::beans::PropertyValue* pDestination = lDestination.getArray();
+ sal_Int32 nItem = 0;
+ for (OUStringHash::const_iterator pItem=lSource.begin(); pItem!=lSource.end(); ++pItem)
+ {
+ pDestination[nItem].Name = pItem->first ;
+ pDestination[nItem].Value <<= pItem->second;
+ ++nItem;
+ }
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts a sequence<PropertyValue> to an unicode string hash, where keys and values match to names and values.
+ */
+OUStringHash Converter::convert_seqProp2OUStringHash( const css::uno::Sequence< css::beans::PropertyValue >& lSource )
+{
+ OUStringHash lDestination;
+ sal_Int32 nCount = lSource.getLength();
+ const css::beans::PropertyValue* pSource = lSource.getConstArray();
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem)
+ {
+ pSource[nItem].Value >>= lDestination[pSource[nItem].Name];
+ }
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ @short convert timestamp from String to tools::DateTime notation
+ @descr Format: "<day>.<month>.<year>/<hour>:<min>:<sec>"
+ e.g. : "1.11.2001/13:45:16"
+
+ @param sString
+ timestamp in string notation
+
+ @return timestamp in DateTime notation
+ */
+DateTime Converter::convert_String2DateTime( /*IN*/ const ::rtl::OUString& sSource )
+{
+ DateTime aStamp ;
+ sal_Int32 nIndex = 0;
+
+ sal_uInt16 nDay = (sal_uInt16)(sSource.getToken( 0, (sal_Unicode)'.', nIndex ).toInt32());
+ if( nIndex>0 )
+ {
+ sal_uInt16 nMonth = (sal_uInt16)(sSource.getToken( 0, (sal_Unicode)'.', nIndex ).toInt32());
+ if( nIndex>0 )
+ {
+ sal_uInt16 nYear = (sal_uInt16)(sSource.getToken( 0, (sal_Unicode)'/', nIndex ).toInt32());
+ if( nIndex>0 )
+ {
+ sal_uInt32 nHour = sSource.getToken( 0, (sal_Unicode)':', nIndex ).toInt32();
+ if( nIndex>0 )
+ {
+ sal_uInt32 nMin = sSource.getToken( 0, (sal_Unicode)':', nIndex ).toInt32();
+ if( nIndex>0 && nIndex<sSource.getLength() )
+ {
+ sal_uInt32 nSec = sSource.copy( nIndex, sSource.getLength()-nIndex ).toInt32();
+
+ Date aDate( nDay , nMonth, nYear );
+ Time aTime( nHour, nMin , nSec );
+ aStamp = DateTime( aDate, aTime );
+ }
+ }
+ }
+ }
+ }
+ return aStamp;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ @short convert timestamp from DateTime to String notation
+ @descr Format: "<day>.<month>.<year>/<hour>:<min>:<sec>"
+ e.g. : "1.11.2001/13:45:16"
+
+ @param aStamp
+ timestamp in DateTime notation
+
+ @return timestamp in String notation
+ */
+::rtl::OUString Converter::convert_DateTime2String( /*IN*/ const DateTime& aSource )
+{
+ ::rtl::OUStringBuffer sBuffer(25);
+
+ sBuffer.append( (sal_Int32)aSource.GetDay() );
+ sBuffer.append( (sal_Unicode)'.' );
+ sBuffer.append( (sal_Int32)aSource.GetMonth() );
+ sBuffer.append( (sal_Unicode)'.' );
+ sBuffer.append( (sal_Int32)aSource.GetYear() );
+ sBuffer.append( (sal_Unicode)'/' );
+ sBuffer.append( (sal_Int32)aSource.GetHour() );
+ sBuffer.append( (sal_Unicode)':' );
+ sBuffer.append( (sal_Int32)aSource.GetMin() );
+ sBuffer.append( (sal_Unicode)':' );
+ sBuffer.append( (sal_Int32)aSource.GetSec() );
+
+ return sBuffer.makeStringAndClear();
+}
+
+::rtl::OUString Converter::convert_DateTime2ISO8601( const DateTime& aSource )
+{
+ ::rtl::OUStringBuffer sBuffer(25);
+
+ sal_Int32 nYear = aSource.GetYear();
+ sal_Int32 nMonth = aSource.GetMonth();
+ sal_Int32 nDay = aSource.GetDay();
+
+ sal_Int32 nHour = aSource.GetHour();
+ sal_Int32 nMin = aSource.GetMin();
+ sal_Int32 nSec = aSource.GetSec();
+
+ // write year formated as "YYYY"
+ if (nYear<10)
+ sBuffer.appendAscii("000");
+ else
+ if (nYear<100)
+ sBuffer.appendAscii("00");
+ else
+ if (nYear<1000)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nYear );
+
+ sBuffer.appendAscii("-");
+ // write month formated as "MM"
+ if (nMonth<10)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nMonth );
+
+ sBuffer.appendAscii("-");
+ // write day formated as "DD"
+ if (nDay<10)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nDay );
+
+ sBuffer.appendAscii("T");
+ // write hours formated as "hh"
+ if (nHour<10)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nHour );
+
+ sBuffer.appendAscii(":");
+ // write min formated as "mm"
+ if (nMin<10)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nMin );
+
+ sBuffer.appendAscii(":");
+ // write sec formated as "ss"
+ if (nSec<10)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nSec );
+
+ sBuffer.appendAscii("Z");
+
+ return sBuffer.makeStringAndClear();
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/classes/propertysethelper.cxx b/framework/source/fwi/classes/propertysethelper.cxx
new file mode 100644
index 000000000000..68f190a95f44
--- /dev/null
+++ b/framework/source/fwi/classes/propertysethelper.cxx
@@ -0,0 +1,448 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+
+#include <classes/propertysethelper.hxx>
+#include <threadhelp/transactionguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+
+//_________________________________________________________________________________________________________________
+// other includes
+
+//_________________________________________________________________________________________________________________
+// namespace
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+
+//-----------------------------------------------------------------------------
+PropertySetHelper::PropertySetHelper(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ LockHelper* pExternalLock ,
+ TransactionManager* pExternalTransactionManager ,
+ sal_Bool bReleaseLockOnCall )
+ : m_xSMGR (xSMGR )
+ , m_lSimpleChangeListener(pExternalLock->getShareableOslMutex())
+ , m_lVetoChangeListener (pExternalLock->getShareableOslMutex())
+ , m_bReleaseLockOnCall (bReleaseLockOnCall )
+ , m_rLock (*pExternalLock )
+ , m_rTransactionManager (*pExternalTransactionManager )
+{
+}
+
+//-----------------------------------------------------------------------------
+PropertySetHelper::~PropertySetHelper()
+{
+}
+
+//-----------------------------------------------------------------------------
+void PropertySetHelper::impl_setPropertyChangeBroadcaster(const css::uno::Reference< css::uno::XInterface >& xBroadcaster)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+ m_xBroadcaster = xBroadcaster;
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_addPropertyInfo(const css::beans::Property& aProperty)
+ throw(css::beans::PropertyExistException,
+ css::uno::Exception )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(aProperty.Name);
+ if (pIt != m_lProps.end())
+ throw css::beans::PropertyExistException();
+
+ m_lProps[aProperty.Name] = aProperty;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_removePropertyInfo(const ::rtl::OUString& sProperty)
+ throw(css::beans::UnknownPropertyException,
+ css::uno::Exception )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ m_lProps.erase(pIt);
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_enablePropertySet()
+{
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_disablePropertySet()
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ css::uno::Reference< css::uno::XInterface > xThis(static_cast< css::beans::XPropertySet* >(this), css::uno::UNO_QUERY);
+ css::lang::EventObject aEvent(xThis);
+
+ m_lSimpleChangeListener.disposeAndClear(aEvent);
+ m_lVetoChangeListener.disposeAndClear(aEvent);
+ m_lProps.free();
+
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool PropertySetHelper::impl_existsVeto(const css::beans::PropertyChangeEvent& aEvent)
+{
+ /* Dont use the lock here!
+ The used helper is threadsafe and it lives for the whole lifetime of
+ our own object.
+ */
+ ::cppu::OInterfaceContainerHelper* pVetoListener = m_lVetoChangeListener.getContainer(aEvent.PropertyName);
+ if (! pVetoListener)
+ return sal_False;
+
+ ::cppu::OInterfaceIteratorHelper pListener(*pVetoListener);
+ while (pListener.hasMoreElements())
+ {
+ try
+ {
+ css::uno::Reference< css::beans::XVetoableChangeListener > xListener(
+ ((css::beans::XVetoableChangeListener*)pListener.next()),
+ css::uno::UNO_QUERY_THROW);
+ xListener->vetoableChange(aEvent);
+ }
+ catch(const css::uno::RuntimeException&)
+ { pListener.remove(); }
+ catch(const css::beans::PropertyVetoException&)
+ { return sal_True; }
+ }
+
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+void PropertySetHelper::impl_notifyChangeListener(const css::beans::PropertyChangeEvent& aEvent)
+{
+ /* Dont use the lock here!
+ The used helper is threadsafe and it lives for the whole lifetime of
+ our own object.
+ */
+ ::cppu::OInterfaceContainerHelper* pSimpleListener = m_lSimpleChangeListener.getContainer(aEvent.PropertyName);
+ if (! pSimpleListener)
+ return;
+
+ ::cppu::OInterfaceIteratorHelper pListener(*pSimpleListener);
+ while (pListener.hasMoreElements())
+ {
+ try
+ {
+ css::uno::Reference< css::beans::XPropertyChangeListener > xListener(
+ ((css::beans::XVetoableChangeListener*)pListener.next()),
+ css::uno::UNO_QUERY_THROW);
+ xListener->propertyChange(aEvent);
+ }
+ catch(const css::uno::RuntimeException&)
+ { pListener.remove(); }
+ }
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PropertySetHelper::getPropertySetInfo()
+ throw(css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ css::uno::Reference< css::beans::XPropertySetInfo > xInfo(static_cast< css::beans::XPropertySetInfo* >(this), css::uno::UNO_QUERY_THROW);
+ return xInfo;
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::setPropertyValue(const ::rtl::OUString& sProperty,
+ const css::uno::Any& aValue )
+ throw(css::beans::UnknownPropertyException,
+ css::beans::PropertyVetoException ,
+ css::lang::IllegalArgumentException ,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ // TODO look for e.g. readonly props and reject setProp() call!
+
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ css::beans::Property aPropInfo = pIt->second;
+
+ sal_Bool bLocked = sal_True;
+ if (m_bReleaseLockOnCall)
+ {
+ aWriteLock.unlock();
+ bLocked = sal_False;
+ // <- SAFE
+ }
+
+ css::uno::Any aCurrentValue = impl_getPropertyValue(aPropInfo.Name, aPropInfo.Handle);
+
+ if (! bLocked)
+ {
+ // SAFE ->
+ aWriteLock.lock();
+ bLocked = sal_True;
+ }
+
+ sal_Bool bWillBeChanged = (aCurrentValue != aValue);
+ if (! bWillBeChanged)
+ return;
+
+ css::beans::PropertyChangeEvent aEvent;
+ aEvent.PropertyName = aPropInfo.Name;
+ aEvent.Further = sal_False;
+ aEvent.PropertyHandle = aPropInfo.Handle;
+ aEvent.OldValue = aCurrentValue;
+ aEvent.NewValue = aValue;
+ aEvent.Source = css::uno::Reference< css::uno::XInterface >(m_xBroadcaster.get(), css::uno::UNO_QUERY);
+
+ if (m_bReleaseLockOnCall)
+ {
+ aWriteLock.unlock();
+ bLocked = sal_False;
+ // <- SAFE
+ }
+
+ if (impl_existsVeto(aEvent))
+ throw css::beans::PropertyVetoException();
+
+ impl_setPropertyValue(aPropInfo.Name, aPropInfo.Handle, aValue);
+
+ impl_notifyChangeListener(aEvent);
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Any SAL_CALL PropertySetHelper::getPropertyValue(const ::rtl::OUString& sProperty)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ css::beans::Property aPropInfo = pIt->second;
+
+ if (m_bReleaseLockOnCall)
+ aReadLock.unlock();
+
+ return impl_getPropertyValue(aPropInfo.Name, aPropInfo.Handle);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::addPropertyChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lSimpleChangeListener.addInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::removePropertyChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lSimpleChangeListener.removeInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::addVetoableChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lVetoChangeListener.addInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::removeVetoableChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lVetoChangeListener.removeInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Sequence< css::beans::Property > SAL_CALL PropertySetHelper::getProperties()
+ throw(css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ sal_Int32 c = (sal_Int32)m_lProps.size();
+ css::uno::Sequence< css::beans::Property > lProps(c);
+ PropertySetHelper::TPropInfoHash::const_iterator pIt ;
+
+ for ( pIt = m_lProps.begin();
+ pIt != m_lProps.end() ;
+ ++pIt )
+ {
+ lProps[--c] = pIt->second;
+ }
+
+ return lProps;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+css::beans::Property SAL_CALL PropertySetHelper::getPropertyByName(const ::rtl::OUString& sName)
+ throw(css::beans::UnknownPropertyException,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sName);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ return pIt->second;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL PropertySetHelper::hasPropertyByName(const ::rtl::OUString& sName)
+ throw(css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::iterator pIt = m_lProps.find(sName);
+ sal_Bool bExist = (pIt != m_lProps.end());
+
+ return bExist;
+ // <- SAFE
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/classes/protocolhandlercache.cxx b/framework/source/fwi/classes/protocolhandlercache.cxx
new file mode 100644
index 000000000000..1a7ddf2e2be6
--- /dev/null
+++ b/framework/source/fwi/classes/protocolhandlercache.cxx
@@ -0,0 +1,364 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+/*TODO
+ - change "singleton" behaviour by using new helper ::comhelper::SingletonRef
+ - rename method exist() to existHandlerForURL() or similar one
+ - may its a good idea to replace struct ProtocolHandler by css::beans::NamedValue type?!
+*/
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <classes/protocolhandlercache.hxx>
+#include <classes/converter.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/lockhelper.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <tools/wldcrd.hxx>
+#include <unotools/configpathes.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+/**
+ @short overloaded index operator of hash map to support pattern key search
+ @descr All keys inside this hash map are URL pattern which points to an uno
+ implementation name of a protocol handler service which is registered
+ for this pattern. This operator makes it easy to find such registered
+ handler by using a full qualified URL and compare it with all pattern
+ keys.
+
+ @param sURL
+ the full qualified URL which should match to a registered pattern
+
+ @return An iterator which points to the found item inside the hash or PatternHash::end()
+ if no pattern match this given <var>sURL</var>.
+
+ @modified 30.04.2002 09:52, as96863
+ */
+PatternHash::iterator PatternHash::findPatternKey( const ::rtl::OUString& sURL )
+{
+ PatternHash::iterator pItem = this->begin();
+ while( pItem!=this->end() )
+ {
+ WildCard aPattern(pItem->first);
+ if (aPattern.Matches(sURL))
+ break;
+ ++pItem;
+ }
+ return pItem;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short initialize static member of class HandlerCache
+ @descr We use a singleton pattern to implement this handler cache.
+ That means it use two static member list to hold all neccessary informations
+ and a ref count mechanism to create/destroy it on demand.
+
+ @modified 30.04.2002 11:13, as96863
+ */
+HandlerHash* HandlerCache::m_pHandler = NULL;
+PatternHash* HandlerCache::m_pPattern = NULL;
+sal_Int32 HandlerCache::m_nRefCount = 0 ;
+HandlerCFGAccess* HandlerCache::m_pConfig = NULL;
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short ctor of the cache of all registered protoco handler
+ @descr It tries to open the right configuration package automaticly
+ and fill the internal structures. After that the cache can be
+ used for read access on this data and perform some search
+ operations on it.
+
+ @modified 30.04.2002 10:02, as96863
+ */
+HandlerCache::HandlerCache()
+{
+ /* SAFE */{
+ WriteGuard aGlobalLock( LockHelper::getGlobalLock() );
+
+ if (m_nRefCount==0)
+ {
+ m_pHandler = new HandlerHash();
+ m_pPattern = new PatternHash();
+ m_pConfig = new HandlerCFGAccess(PACKAGENAME_PROTOCOLHANDLER);
+ m_pConfig->read(&m_pHandler,&m_pPattern);
+ m_pConfig->setCache(this);
+ }
+
+ ++m_nRefCount;
+ /* SAFE */}
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short dtor of the cache
+ @descr It frees all used memory. In further implementations (may if we support write access too)
+ it's a good place to flush changes back to the configuration - but not needed yet.
+
+ @modified 30.04.2002 09:54, as96863
+ */
+HandlerCache::~HandlerCache()
+{
+ /* SAFE */{
+ WriteGuard aGlobalLock( LockHelper::getGlobalLock() );
+
+ if( m_nRefCount==1)
+ {
+ m_pConfig->setCache(NULL);
+ m_pHandler->free();
+ m_pPattern->free();
+
+ delete m_pConfig;
+ delete m_pHandler;
+ delete m_pPattern;
+ m_pConfig = NULL;
+ m_pHandler= NULL;
+ m_pPattern= NULL;
+ }
+
+ --m_nRefCount;
+ /* SAFE */}
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short dtor of the cache
+ @descr It frees all used memory. In further implementations (may if we support write access too)
+ it's a good place to flush changes back to the configuration - but not needed yet.
+
+ @modified 30.04.2002 09:54, as96863
+ */
+sal_Bool HandlerCache::search( const ::rtl::OUString& sURL, ProtocolHandler* pReturn ) const
+{
+ sal_Bool bFound = sal_False;
+ /* SAFE */{
+ ReadGuard aReadLock( LockHelper::getGlobalLock() );
+ PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL);
+ if (pItem!=m_pPattern->end())
+ {
+ *pReturn = (*m_pHandler)[pItem->second];
+ bFound = sal_True;
+ }
+ /* SAFE */}
+ return bFound;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short search for a registered handler by using an URL struct
+ @descr We combine neccessary parts of this struct to a valid URL string
+ and call our other search method ...
+ It's a helper for outside code.
+
+ @modified 30.04.2002 09:54, as96863
+ */
+sal_Bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const
+{
+ return search( aURL.Complete, pReturn );
+}
+
+//_________________________________________________________________________________________________________________
+
+sal_Bool HandlerCache::exists( const ::rtl::OUString& sURL ) const
+{
+ sal_Bool bFound = sal_False;
+ /* SAFE */{
+ ReadGuard aReadLock( LockHelper::getGlobalLock() );
+ PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL);
+ bFound = pItem!=m_pPattern->end();
+ /* SAFE */}
+ return bFound;
+}
+
+//_________________________________________________________________________________________________________________
+void HandlerCache::takeOver(HandlerHash* pHandler, PatternHash* pPattern)
+{
+ // SAFE ->
+ WriteGuard aWriteLock( LockHelper::getGlobalLock() );
+
+ HandlerHash* pOldHandler = m_pHandler;
+ PatternHash* pOldPattern = m_pPattern;
+
+ m_pHandler = pHandler;
+ m_pPattern = pPattern;
+
+ pOldHandler->free();
+ pOldPattern->free();
+ delete pOldHandler;
+ delete pOldPattern;
+
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short dtor of the config access class
+ @descr It opens the configuration package automaticly by using base class mechanism.
+ After that "read()" method of this class should be called to use it.
+
+ @param sPackage
+ specifies the package name of the configuration data which should be used
+
+ @modified 30.04.2002 10:06, as96863
+ */
+HandlerCFGAccess::HandlerCFGAccess( const ::rtl::OUString& sPackage )
+ : ConfigItem( sPackage )
+{
+ css::uno::Sequence< ::rtl::OUString > lListenPathes(1);
+ lListenPathes[0] = SETNAME_HANDLER;
+ EnableNotification(lListenPathes);
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short use base class mechanism to fill given structures
+ @descr User use us as a wrapper between configuration api and his internal structures.
+ He give us some pointer to his member and we fill it.
+
+ @param pHandler
+ pointer to a list of protocol handler infos
+
+ @param pPattern
+ reverse map of handler pattern to her uno names
+
+ @modified 30.04.2002 09:54, as96863
+ */
+void HandlerCFGAccess::read( HandlerHash** ppHandler ,
+ PatternHash** ppPattern )
+{
+ // list of all uno implementation names without encoding
+ css::uno::Sequence< ::rtl::OUString > lNames = GetNodeNames( SETNAME_HANDLER, ::utl::CONFIG_NAME_LOCAL_PATH );
+ sal_Int32 nSourceCount = lNames.getLength();
+ sal_Int32 nTargetCount = nSourceCount;
+ // list of all full qualified path names of configuration entries
+ css::uno::Sequence< ::rtl::OUString > lFullNames ( nTargetCount );
+
+ // expand names to full path names
+ sal_Int32 nSource=0;
+ sal_Int32 nTarget=0;
+ for( nSource=0; nSource<nSourceCount; ++nSource )
+ {
+ ::rtl::OUStringBuffer sPath( SETNAME_HANDLER );
+ sPath.append(CFG_PATH_SEPERATOR);
+ sPath.append(lNames[nSource]);
+ sPath.append(CFG_PATH_SEPERATOR);
+ sPath.append(PROPERTY_PROTOCOLS);
+
+ lFullNames[nTarget] = sPath.makeStringAndClear();
+ ++nTarget;
+ }
+
+ // get values at all
+ css::uno::Sequence< css::uno::Any > lValues = GetProperties( lFullNames );
+ LOG_ASSERT2( lFullNames.getLength()!=lValues.getLength(), "HandlerCFGAccess::read()", "Miss some configuration values of handler set!" )
+
+ // fill structures
+ nSource = 0;
+ for( nTarget=0; nTarget<nTargetCount; ++nTarget )
+ {
+ // create it new for every loop to guarantee a real empty object!
+ ProtocolHandler aHandler;
+ aHandler.m_sUNOName = ::utl::extractFirstFromConfigurationPath(lNames[nSource]);
+
+ // unpack all values of this handler
+ css::uno::Sequence< ::rtl::OUString > lTemp;
+ lValues[nTarget] >>= lTemp;
+ aHandler.m_lProtocols = Converter::convert_seqOUString2OUStringList(lTemp);
+
+ // register his pattern into the performance search hash
+ for (OUStringList::iterator pItem =aHandler.m_lProtocols.begin();
+ pItem!=aHandler.m_lProtocols.end() ;
+ ++pItem )
+ {
+ (**ppPattern)[*pItem] = lNames[nSource];
+ }
+
+ // ï¿œnsert the handler info into the normal handler cache
+ (**ppHandler)[lNames[nSource]] = aHandler;
+ ++nSource;
+ }
+}
+
+//_________________________________________________________________________________________________________________
+void HandlerCFGAccess::Notify(const css::uno::Sequence< rtl::OUString >& /*lPropertyNames*/)
+{
+ HandlerHash* pHandler = new HandlerHash;
+ PatternHash* pPattern = new PatternHash;
+
+ read(&pHandler, &pPattern);
+ if (m_pCache)
+ m_pCache->takeOver(pHandler, pPattern);
+ else
+ {
+ delete pHandler;
+ delete pPattern;
+ }
+}
+
+void HandlerCFGAccess::Commit()
+{
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/helper/mischelper.cxx b/framework/source/fwi/helper/mischelper.cxx
new file mode 100644
index 000000000000..5d1b0631b219
--- /dev/null
+++ b/framework/source/fwi/helper/mischelper.cxx
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/document/XDocumentLanguages.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+#include <tools/debug.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <i18npool/mslangid.hxx>
+#include <svtools/langtab.hxx>
+#include <comphelper/processfactory.hxx>
+#include <helper/mischelper.hxx>
+#include <services.h>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+
+using ::rtl::OUString;
+
+
+namespace framework
+{
+
+uno::Reference< linguistic2::XLanguageGuessing > LanguageGuessingHelper::GetGuesser() const
+{
+ if (!m_xLanguageGuesser.is())
+ {
+ try
+ {
+ m_xLanguageGuesser = uno::Reference< linguistic2::XLanguageGuessing >(
+ m_xServiceManager->createInstance(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.linguistic2.LanguageGuessing")) ),
+ uno::UNO_QUERY );
+ }
+ catch (uno::Exception &r)
+ {
+ (void) r;
+ DBG_ASSERT( 0, "failed to get language guessing component" );
+ }
+ }
+ return m_xLanguageGuesser;
+}
+
+
+::rtl::OUString RetrieveLabelFromCommand(
+ const ::rtl::OUString& aCmdURL,
+ const uno::Reference< lang::XMultiServiceFactory >& _xServiceFactory,
+ uno::Reference< container::XNameAccess >& _xUICommandLabels,
+ const uno::Reference< frame::XFrame >& _xFrame,
+ ::rtl::OUString& _rModuleIdentifier,
+ sal_Bool& _rIni,
+ const sal_Char* _pName)
+{
+ ::rtl::OUString aLabel;
+
+ // Retrieve popup menu labels
+ if ( !_xUICommandLabels.is() )
+ {
+ try
+ {
+ if ( !_rIni )
+ {
+ _rIni = sal_True;
+ Reference< XModuleManager > xModuleManager( _xServiceFactory->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
+
+ try
+ {
+ _rModuleIdentifier = xModuleManager->identify( _xFrame );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ Reference< XNameAccess > xNameAccess( _xServiceFactory->createInstance( SERVICENAME_UICOMMANDDESCRIPTION ), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ xNameAccess->getByName( _rModuleIdentifier ) >>= _xUICommandLabels;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ if ( _xUICommandLabels.is() )
+ {
+ try
+ {
+ if ( aCmdURL.getLength() > 0 )
+ {
+ rtl::OUString aStr;
+ Sequence< PropertyValue > aPropSeq;
+ if( _xUICommandLabels->hasByName( aCmdURL ) )
+ {
+ if ( _xUICommandLabels->getByName( aCmdURL ) >>= aPropSeq )
+ {
+ for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
+ {
+ if ( aPropSeq[i].Name.equalsAscii( _pName/*"Label"*/ ))
+ {
+ aPropSeq[i].Value >>= aStr;
+ break;
+ }
+ }
+ }
+ }
+ aLabel = aStr;
+ }
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+
+ return aLabel;
+}
+
+
+void FillLangItems( std::set< OUString > &rLangItems,
+ const SvtLanguageTable & rLanguageTable,
+ const uno::Reference< frame::XFrame > & rxFrame,
+ const LanguageGuessingHelper & rLangGuessHelper,
+ sal_Int16 nScriptType,
+ const OUString & rCurLang,
+ const OUString & rKeyboardLang,
+ const OUString & rGuessedTextLang )
+{
+ rLangItems.clear();
+
+ //1--add current language
+ if( rCurLang != OUString() &&
+ LANGUAGE_DONTKNOW != rLanguageTable.GetType( rCurLang ))
+ rLangItems.insert( rCurLang );
+
+ //2--System
+ const AllSettings& rAllSettings = Application::GetSettings();
+ LanguageType rSystemLanguage = rAllSettings.GetLanguage();
+ if( rSystemLanguage != LANGUAGE_DONTKNOW )
+ {
+ if ( IsScriptTypeMatchingToLanguage( nScriptType, rSystemLanguage ))
+ rLangItems.insert( OUString( rLanguageTable.GetString( rSystemLanguage )) );
+ }
+
+ //3--UI
+ LanguageType rUILanguage = rAllSettings.GetUILanguage();
+ if( rUILanguage != LANGUAGE_DONTKNOW )
+ {
+ if ( IsScriptTypeMatchingToLanguage( nScriptType, rUILanguage ))
+ rLangItems.insert( OUString( rLanguageTable.GetString( rUILanguage )) );
+ }
+
+ //4--guessed language
+ uno::Reference< linguistic2::XLanguageGuessing > xLangGuesser( rLangGuessHelper.GetGuesser() );
+ if ( xLangGuesser.is() && rGuessedTextLang.getLength() > 0)
+ {
+ ::com::sun::star::lang::Locale aLocale(xLangGuesser->guessPrimaryLanguage( rGuessedTextLang, 0, rGuessedTextLang.getLength()) );
+ LanguageType nLang = MsLangId::convertLocaleToLanguageWithFallback( aLocale );
+ if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_NONE && nLang != LANGUAGE_SYSTEM
+ && IsScriptTypeMatchingToLanguage( nScriptType, nLang ))
+ rLangItems.insert( rLanguageTable.GetString( nLang ));
+ }
+
+ //5--keyboard language
+ if( rKeyboardLang != OUString())
+ {
+ if ( IsScriptTypeMatchingToLanguage( nScriptType, rLanguageTable.GetType( rKeyboardLang )))
+ rLangItems.insert( rKeyboardLang );
+ }
+
+ //6--all languages used in current document
+ Reference< com::sun::star::frame::XModel > xModel;
+ if ( rxFrame.is() )
+ {
+ Reference< com::sun::star::frame::XController > xController( rxFrame->getController(), UNO_QUERY );
+ if ( xController.is() )
+ xModel = xController->getModel();
+ }
+ Reference< document::XDocumentLanguages > xDocumentLanguages( xModel, UNO_QUERY );
+ /*the description of nScriptType
+ LATIN : 0x001
+ ASIAN : 0x002
+ COMPLEX: 0x004
+ */
+ const sal_Int16 nMaxCount = 7;
+ if ( xDocumentLanguages.is() )
+ {
+ Sequence< Locale > rLocales( xDocumentLanguages->getDocumentLanguages( nScriptType, nMaxCount ));
+ if ( rLocales.getLength() > 0 )
+ {
+ for ( sal_uInt16 i = 0; i < rLocales.getLength(); ++i )
+ {
+ if ( rLangItems.size() == static_cast< size_t >(nMaxCount) )
+ break;
+ const Locale& rLocale=rLocales[i];
+ if( IsScriptTypeMatchingToLanguage( nScriptType, rLanguageTable.GetType( rLocale.Language )))
+ rLangItems.insert( OUString( rLocale.Language ) );
+ }
+ }
+ }
+}
+
+} // namespace framework
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/helper/networkdomain.cxx b/framework/source/fwi/helper/networkdomain.cxx
new file mode 100644
index 000000000000..fb4bc20f5077
--- /dev/null
+++ b/framework/source/fwi/helper/networkdomain.cxx
@@ -0,0 +1,298 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <helper/networkdomain.hxx>
+
+namespace framework
+{
+
+#ifdef WNT
+//_________________________________________________________________________________________________________________
+// Windows
+//_________________________________________________________________________________________________________________
+
+#define UNICODE
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+
+//_________________________________________________________________________________________________________________
+// Win NT, Win 2000, Win XP
+//_________________________________________________________________________________________________________________
+
+static DWORD WINAPI GetUserDomainW_NT( LPWSTR lpBuffer, DWORD nSize )
+{
+ return GetEnvironmentVariable( TEXT("USERDOMAIN"), lpBuffer, nSize );
+}
+
+//_________________________________________________________________________________________________________________
+// Win 9x,Win ME
+//_________________________________________________________________________________________________________________
+
+static DWORD WINAPI GetUserDomainW_WINDOWS( LPWSTR lpBuffer, DWORD nSize )
+{
+ HKEY hkeyLogon;
+ HKEY hkeyWorkgroup;
+ DWORD dwResult = 0;
+
+
+ if ( ERROR_SUCCESS == RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ TEXT("Network\\Logon"),
+ 0, KEY_READ, &hkeyLogon ) )
+ {
+ DWORD dwLogon = 0;
+ DWORD dwLogonSize = sizeof(dwLogon);
+ RegQueryValueEx( hkeyLogon, TEXT("LMLogon"), 0, NULL, (LPBYTE)&dwLogon, &dwLogonSize );
+ RegCloseKey( hkeyLogon );
+
+ if ( dwLogon )
+ {
+ HKEY hkeyNetworkProvider;
+
+ if ( ERROR_SUCCESS == RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Services\\MSNP32\\NetworkProvider"),
+ 0, KEY_READ, &hkeyNetworkProvider ) )
+ {
+ DWORD dwBufferSize = nSize;
+ LONG lResult = RegQueryValueEx( hkeyNetworkProvider, TEXT("AuthenticatingAgent"), 0, NULL, (LPBYTE)lpBuffer, &dwBufferSize );
+
+ if ( ERROR_SUCCESS == lResult || ERROR_MORE_DATA == lResult )
+ dwResult = dwBufferSize / sizeof(TCHAR);
+
+ RegCloseKey( hkeyNetworkProvider );
+ }
+ }
+ }
+ else if ( ERROR_SUCCESS == RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ TEXT("SYSTEM\\CurrentControlSet\\Services\\VxD\\VNETSUP"),
+ 0, KEY_READ, &hkeyWorkgroup ) )
+ {
+ DWORD dwBufferSize = nSize;
+ LONG lResult = RegQueryValueEx( hkeyWorkgroup, TEXT("Workgroup"), 0, NULL, (LPBYTE)lpBuffer, &dwBufferSize );
+
+ if ( ERROR_SUCCESS == lResult || ERROR_MORE_DATA == lResult )
+ dwResult = dwBufferSize / sizeof(TCHAR);
+
+ RegCloseKey( hkeyWorkgroup );
+ }
+
+
+ return dwResult;
+}
+
+static rtl::OUString GetUserDomain()
+{
+ sal_Unicode aBuffer[256];
+
+ long nVersion = GetVersion();
+ DWORD nResult;
+
+ if ( nVersion < 0 )
+ nResult = GetUserDomainW_WINDOWS( reinterpret_cast<LPWSTR>(aBuffer), sizeof( aBuffer ) );
+ else
+ nResult = GetUserDomainW_NT( reinterpret_cast<LPWSTR>(aBuffer), sizeof( aBuffer ) );
+
+ if ( nResult > 0 )
+ return rtl::OUString( aBuffer );
+ else
+ return rtl::OUString();
+}
+
+//_________________________________________________________________________________________________________________
+// Windows
+//_________________________________________________________________________________________________________________
+
+rtl::OUString NetworkDomain::GetYPDomainName()
+{
+ return ::rtl::OUString();
+}
+
+rtl::OUString NetworkDomain::GetNTDomainName()
+{
+ return GetUserDomain();
+}
+
+#elif defined( UNIX )
+
+#include <rtl/ustring.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <osl/thread.h>
+
+//_________________________________________________________________________________________________________________
+// Unix
+//_________________________________________________________________________________________________________________
+
+#if defined( SOLARIS )
+
+//_________________________________________________________________________________________________________________
+// Solaris
+//_________________________________________________________________________________________________________________
+
+#include <sys/systeminfo.h>
+#include <sal/alloca.h>
+
+static rtl_uString *getDomainName()
+{
+ /* Initialize and assume failure */
+ rtl_uString *ustrDomainName = NULL;
+
+ char szBuffer[256];
+
+ long nCopied = sizeof(szBuffer);
+ char *pBuffer = szBuffer;
+ long nBufSize;
+
+ do
+ {
+ nBufSize = nCopied;
+ nCopied = sysinfo( SI_SRPC_DOMAIN, pBuffer, nBufSize );
+
+ /* If nCopied is greater than buffersize we need to allocate
+ a buffer with suitable size */
+
+ if ( nCopied > nBufSize )
+ pBuffer = (char *)alloca( nCopied );
+
+ } while ( nCopied > nBufSize );
+
+ if ( -1 != nCopied )
+ {
+ rtl_string2UString(
+ &ustrDomainName,
+ pBuffer,
+ nCopied - 1,
+ osl_getThreadTextEncoding(),
+ OSTRING_TO_OUSTRING_CVTFLAGS );
+ }
+
+ return ustrDomainName;
+}
+
+#elif defined( LINUX ) /* endif SOLARIS */
+
+//_________________________________________________________________________________________________________________
+// Linux
+//_________________________________________________________________________________________________________________
+
+#include <unistd.h>
+#include <string.h>
+
+static rtl_uString *getDomainName()
+{
+ /* Initialize and assume failure */
+ rtl_uString *ustrDomainName = NULL;
+
+ char *pBuffer;
+ int result;
+ size_t nBufSize = 0;
+
+ do
+ {
+ nBufSize += 256; /* Increase buffer size by steps of 256 bytes */
+ pBuffer = (char *)alloca( nBufSize );
+ result = getdomainname( pBuffer, nBufSize );
+ /* If buffersize in not large enough -1 is returned and errno
+ is set to EINVAL. This only applies to libc. With glibc the name
+ is truncated. */
+ } while ( -1 == result && EINVAL == errno );
+
+ if ( 0 == result )
+ {
+ rtl_string2UString(
+ &ustrDomainName,
+ pBuffer,
+ strlen( pBuffer ),
+ osl_getThreadTextEncoding(),
+ OSTRING_TO_OUSTRING_CVTFLAGS );
+ }
+
+ return ustrDomainName;
+}
+
+#else /* LINUX */
+
+//_________________________________________________________________________________________________________________
+// Other Unix
+//_________________________________________________________________________________________________________________
+
+static rtl_uString *getDomainName()
+{
+ return NULL;
+}
+
+#endif
+
+//_________________________________________________________________________________________________________________
+// Unix
+//_________________________________________________________________________________________________________________
+
+rtl::OUString NetworkDomain::GetYPDomainName()
+{
+ rtl_uString* pResult = getDomainName();
+ if ( pResult )
+ return rtl::OUString( pResult );
+ else
+ return rtl::OUString();
+}
+
+rtl::OUString NetworkDomain::GetNTDomainName()
+{
+ return ::rtl::OUString();
+}
+
+#else /* UNIX */
+
+//_________________________________________________________________________________________________________________
+// Other operating systems (non-Windows and non-Unix)
+//_________________________________________________________________________________________________________________
+
+rtl::OUString NetworkDomain::GetYPDomainName()
+{
+ return rtl::OUString();
+}
+
+rtl::OUString NetworkDomain::GetNTDomainName()
+{
+ return rtl::OUString();
+}
+
+#endif
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/helper/shareablemutex.cxx b/framework/source/fwi/helper/shareablemutex.cxx
new file mode 100644
index 000000000000..1cc9a0acd8b9
--- /dev/null
+++ b/framework/source/fwi/helper/shareablemutex.cxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <helper/shareablemutex.hxx>
+
+namespace framework
+{
+
+ShareableMutex::ShareableMutex()
+{
+ pMutexRef = new MutexRef;
+ pMutexRef->acquire();
+}
+
+ShareableMutex::ShareableMutex( const ShareableMutex& rShareableMutex )
+{
+ pMutexRef = rShareableMutex.pMutexRef;
+ if ( pMutexRef )
+ pMutexRef->acquire();
+}
+
+const ShareableMutex& ShareableMutex::operator=( const ShareableMutex& rShareableMutex )
+{
+ if ( rShareableMutex.pMutexRef )
+ rShareableMutex.pMutexRef->acquire();
+ if ( pMutexRef )
+ pMutexRef->release();
+ pMutexRef = rShareableMutex.pMutexRef;
+ return *this;
+}
+
+ShareableMutex::~ShareableMutex()
+{
+ if ( pMutexRef )
+ pMutexRef->release();
+}
+
+void ShareableMutex::acquire()
+{
+ if ( pMutexRef )
+ pMutexRef->m_oslMutex.acquire();
+}
+
+void ShareableMutex::release()
+{
+ if ( pMutexRef )
+ pMutexRef->m_oslMutex.release();
+}
+
+::osl::Mutex& ShareableMutex::getShareableOslMutex()
+{
+ return pMutexRef->m_oslMutex;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/jobs/configaccess.cxx b/framework/source/fwi/jobs/configaccess.cxx
new file mode 100644
index 000000000000..5a66f81b832e
--- /dev/null
+++ b/framework/source/fwi/jobs/configaccess.cxx
@@ -0,0 +1,245 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//________________________________
+// my own includes
+#include <jobs/configaccess.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <general.h>
+#include <services.h>
+
+//________________________________
+// interface includes
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+//________________________________
+// includes of other projects
+#include <unotools/configpathes.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//________________________________
+// namespace
+
+namespace framework{
+
+//________________________________
+// non exported const
+
+//________________________________
+// non exported definitions
+
+//________________________________
+// declarations
+
+//________________________________
+/**
+ @short open the configuration of this job
+ @descr We open the configuration of this job only. Not the whole package or the whole
+ job set. We are interested on our own properties only.
+ We set the opened configuration access as our member. So any following method,
+ which needs cfg access, can use it. That prevent us against multiple open/close requests.
+ But you can use this method to upgrade an already opened configuration too.
+
+ @param eMode
+ force opening of the configuration access in readonly or in read/write mode
+ */
+ConfigAccess::ConfigAccess( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ /*IN*/ const ::rtl::OUString& sRoot )
+ : ThreadHelpBase( )
+ , m_xSMGR ( xSMGR )
+ , m_sRoot ( sRoot )
+ , m_eMode ( E_CLOSED )
+{
+}
+
+//________________________________
+/**
+ @short last chance to close an open configuration access point
+ @descr In case our user forgot to close this configuration point
+ in the right way, normaly he will run into some trouble -
+ e.g. losing data.
+ */
+ConfigAccess::~ConfigAccess()
+{
+ close();
+}
+
+//________________________________
+/**
+ @short return the internal mode of this instance
+ @descr May be the outside user need any information about successfully opened
+ or closed config access point objects. He can control the internal mode to do so.
+
+ @return The internal open state of this object.
+ */
+ConfigAccess::EOpenMode ConfigAccess::getMode() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_eMode;
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short open the configuration access in the specified mode
+ @descr We set the opened configuration access as our member. So any following method,
+ which needs cfg access, can use it. That prevent us against multiple open/close requests.
+ But you can use this method to upgrade an already opened configuration too.
+ It's possible to open a config access in READONLY mode first and "open" it at a second
+ time within the mode READWRITE. Then we will upgrade it. Dowgrade will be possible too.
+
+ But note: closing will be done explicitly by calling method close() ... not by
+ downgrading with mode CLOSED!
+
+ @param eMode
+ force (re)opening of the configuration access in readonly or in read/write mode
+ */
+void ConfigAccess::open( /*IN*/ EOpenMode eMode )
+{
+ /* SAFE { */
+ // We must lock the whole method to be shure, that nobody
+ // outside uses our internal member m_xAccess!
+ WriteGuard aWriteLock(m_aLock);
+
+ // check if configuration is already open in the right mode.
+ // By the way: Don't allow closing by using this method!
+ if (
+ (eMode !=E_CLOSED) &&
+ (m_eMode!=eMode )
+ )
+ {
+ // We have to close the old access point without any question here.
+ // It will be open again using the new mode.
+ // can be called without checks! It does the checks by itself ...
+ // e.g. for already closed or not opened configuration.
+ // Flushing of all made changes will be done here too.
+ close();
+
+ // create the configuration provider, which provides sub access points
+ css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(m_xSMGR->createInstance(SERVICENAME_CFGPROVIDER), css::uno::UNO_QUERY);
+ if (xConfigProvider.is())
+ {
+ css::beans::PropertyValue aParam;
+ aParam.Name = DECLARE_ASCII("nodepath");
+ aParam.Value <<= m_sRoot;
+
+ css::uno::Sequence< css::uno::Any > lParams(1);
+ lParams[0] <<= aParam;
+
+ // open it
+ try
+ {
+ if (eMode==E_READONLY)
+ m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS , lParams);
+ else
+ if (eMode==E_READWRITE)
+ m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGUPDATEACCESS, lParams);
+ }
+ catch(css::uno::Exception& ex)
+ {
+ (void) ex; // avoid warning
+ LOG_WARNING("open config ...", U2B(ex.Message))
+ }
+
+ m_eMode = E_CLOSED;
+ if (m_xConfig.is())
+ m_eMode = eMode;
+ }
+ }
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short close the internal opened configuration access and flush all changes
+ @descr It checks, if the given access is valid and react in the right way.
+ It flushes all changes ... so nobody else must know this state.
+ */
+void ConfigAccess::close()
+{
+ /* SAFE { */
+ // Lock the whole method, to be shure that nobody else uses our internal members
+ // during this time.
+ WriteGuard aWriteLock(m_aLock);
+
+ // check already closed configuration
+ if (m_xConfig.is())
+ {
+ css::uno::Reference< css::util::XChangesBatch > xFlush(m_xConfig, css::uno::UNO_QUERY);
+ if (xFlush.is())
+ xFlush->commitChanges();
+ m_xConfig = css::uno::Reference< css::uno::XInterface >();
+ m_eMode = E_CLOSED;
+ }
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short provides an access to the internal wrapped configuration access
+ @descr It's not allowed to safe this c++ (!) reference outside. You have
+ to use it directly. Further you must use our public lock member m_aLock
+ to synchronize your code with our internal structures and our interface
+ methods. Acquire it before you call cfg() and release it afterwards immediatly.
+
+ E.g.: ConfigAccess aAccess(...);
+ ReadGuard aReadLock(aAccess.m_aLock);
+ Reference< XPropertySet > xSet(aAccess.cfg(), UNO_QUERY);
+ Any aProp = xSet->getPropertyValue("...");
+ aReadLock.unlock();
+
+ @attention During this time it's not allowed to call the methods open() or close()!
+ Otherwhise you will change your own referenced config access. Anything will
+ be possible then.
+
+ @return A c++(!) reference to the uno instance of the configuration access point.
+ */
+const css::uno::Reference< css::uno::XInterface >& ConfigAccess::cfg()
+{
+ // must be synchronized from outside!
+ // => no lock here ...
+ return m_xConfig;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/jobs/jobconst.cxx b/framework/source/fwi/jobs/jobconst.cxx
new file mode 100644
index 000000000000..9d3403db5cfb
--- /dev/null
+++ b/framework/source/fwi/jobs/jobconst.cxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//________________________________
+// my own includes
+
+#include <jobs/jobconst.hxx>
+
+//________________________________
+// interface includes
+
+//________________________________
+// includes of other projects
+
+//________________________________
+// namespace
+
+namespace framework{
+
+//________________________________
+// non exported const
+
+//________________________________
+// non exported definitions
+
+//________________________________
+// declarations
+
+const ::rtl::OUString JobConst::ANSWER_DEACTIVATE_JOB()
+{
+ static const ::rtl::OUString PROP(RTL_CONSTASCII_USTRINGPARAM("Deactivate"));
+ return PROP;
+}
+
+const ::rtl::OUString JobConst::ANSWER_SAVE_ARGUMENTS()
+{
+ static const ::rtl::OUString PROP(RTL_CONSTASCII_USTRINGPARAM("SaveArguments"));
+ return PROP;
+}
+
+const ::rtl::OUString JobConst::ANSWER_SEND_DISPATCHRESULT()
+{
+ static const ::rtl::OUString PROP(RTL_CONSTASCII_USTRINGPARAM("SendDispatchResult"));
+ return PROP;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/threadhelp/lockhelper.cxx b/framework/source/fwi/threadhelp/lockhelper.cxx
new file mode 100644
index 000000000000..b3956cd5544f
--- /dev/null
+++ b/framework/source/fwi/threadhelp/lockhelper.cxx
@@ -0,0 +1,553 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/lockhelper.hxx>
+#include <general.h>
+#include <macros/debug.hxx>
+
+#include <macros/generic.hxx>
+#include "vcl/solarmutex.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <osl/process.h>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+/*-************************************************************************************************************//**
+ @short use ctor to initialize instance
+ @descr We must initialize our member "m_eLockType". This value specify handling of locking.
+ User use this helper as parameter for a guard creation.
+ These guard use "m_eLockType" to set lock in the right way by using right mutex or rw-lock.
+
+ @seealso enum ELockType
+ @seealso class ReadGuard
+ @seealso class WriteGuard
+
+ @param "rSolarMutex", for some components we must be "vcl-free"! So we can't work with our solar mutex
+ directly. User must set his reference at this instance - so we can work with it!
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+LockHelper::LockHelper( ::osl::SolarMutex* pSolarMutex )
+ : m_pFairRWLock ( NULL )
+ , m_pOwnMutex ( NULL )
+ , m_pSolarMutex ( NULL )
+ , m_pShareableOslMutex( NULL )
+ , m_bDummySolarMutex ( sal_False )
+{
+ m_eLockType = implts_getLockType();
+ switch( m_eLockType )
+ {
+ case E_NOTHING : break; // There is nothing to do ...
+ case E_OWNMUTEX : {
+ m_pOwnMutex = new ::osl::Mutex;
+ }
+ break;
+ case E_SOLARMUTEX : {
+ if( pSolarMutex == NULL )
+ {
+ m_pSolarMutex = new ::vcl::SolarMutexObject;
+ m_bDummySolarMutex = sal_True;
+ }
+ else
+ {
+ m_pSolarMutex = pSolarMutex;
+ }
+ }
+ break;
+ case E_FAIRRWLOCK : {
+ m_pFairRWLock = new FairRWLock;
+ }
+ break;
+ #ifdef ENABLE_ASSERTIONS
+ default : LOG_ASSERT2( m_eLockType!=E_NOTHING, "LockHelper::ctor()", "Invalid lock type found .. so code will not be threadsafe!" )
+ #endif
+ }
+}
+
+/*-************************************************************************************************************//**
+ @short default dtor to release safed pointer
+ @descr We have created dynamical mutex- or lock-member ... or we hold a pointer to external objects.
+ We must release it!
+
+ @seealso ctor()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+LockHelper::~LockHelper()
+{
+ if( m_pShareableOslMutex != NULL )
+ {
+ // Sometimes we hold two pointer to same object!
+ // (e.g. if m_eLockType==E_OWNMUTEX!)
+ // So we should forget it ... but don't delete it twice!
+ if( m_pShareableOslMutex != m_pOwnMutex )
+ {
+ delete m_pShareableOslMutex;
+ }
+ m_pShareableOslMutex = NULL;
+ }
+ if( m_pOwnMutex != NULL )
+ {
+ delete m_pOwnMutex;
+ m_pOwnMutex = NULL;
+ }
+ if( m_pSolarMutex != NULL )
+ {
+ if (m_bDummySolarMutex)
+ {
+ delete static_cast<vcl::SolarMutexObject*>(m_pSolarMutex);
+ m_bDummySolarMutex = sal_False;
+ }
+ m_pSolarMutex = NULL;
+ }
+ if( m_pFairRWLock != NULL )
+ {
+ delete m_pFairRWLock;
+ m_pFairRWLock = NULL;
+ }
+}
+
+/*-************************************************************************************************************//**
+ @interface IMutex
+ @short set an exclusiv lock
+ @descr We must match this lock call with current set lock type and used lock member.
+ If a mutex should be used - it will be easy ... but if a rw-lock should be used
+ we must simulate it as a write access!
+
+ @attention If a shareable osl mutex exist, he must be used as twice!
+ It's neccessary for some cppu-helper classes ...
+
+ @seealso method acquireWriteAccess()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+void LockHelper::acquire()
+{
+ switch( m_eLockType )
+ {
+ case E_NOTHING : break; // There is nothing to do ...
+ case E_OWNMUTEX : {
+ m_pOwnMutex->acquire();
+ }
+ break;
+ case E_SOLARMUTEX : {
+ m_pSolarMutex->acquire();
+ }
+ break;
+ case E_FAIRRWLOCK : {
+ m_pFairRWLock->acquireWriteAccess();
+ }
+ break;
+ }
+}
+
+/*-************************************************************************************************************//**
+ @interface IMutex
+ @short release exclusiv lock
+ @descr We must match this unlock call with current set lock type and used lock member.
+ If a mutex should be used - it will be easy ... but if a rw-lock should be used
+ we must simulate it as a write access!
+
+ @attention If a shareable osl mutex exist, he must be used as twice!
+ It's neccessary for some cppu-helper classes ...
+
+ @seealso method releaseWriteAccess()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+void LockHelper::release()
+{
+ switch( m_eLockType )
+ {
+ case E_NOTHING : break; // There is nothing to do ...
+ case E_OWNMUTEX : {
+ m_pOwnMutex->release();
+ }
+ break;
+ case E_SOLARMUTEX : {
+ m_pSolarMutex->release();
+ }
+ break;
+ case E_FAIRRWLOCK : {
+ m_pFairRWLock->releaseWriteAccess();
+ }
+ break;
+ }
+}
+
+/*-************************************************************************************************************//**
+ @interface IRWLock
+ @short set lock for reading
+ @descr A guard should call this method to acquire read access on your member.
+ Writing isn't allowed then - but nobody could check it for you!
+ We use m_eLockType to differ between all possible "lock-member"!!!
+
+ @attention If a shareable osl mutex exist, he must be used as twice!
+ It's neccessary for some cppu-helper classes ...
+
+ @seealso method releaseReadAccess()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+void LockHelper::acquireReadAccess()
+{
+ switch( m_eLockType )
+ {
+ case E_NOTHING : break; // There is nothing to do ...
+ case E_OWNMUTEX : {
+ m_pOwnMutex->acquire();
+ }
+ break;
+ case E_SOLARMUTEX : {
+ m_pSolarMutex->acquire();
+ }
+ break;
+ case E_FAIRRWLOCK : {
+ m_pFairRWLock->acquireReadAccess();
+ }
+ break;
+ }
+}
+
+/*-************************************************************************************************************//**
+ @interface IRWLock
+ @short reset lock for reading
+ @descr A guard should call this method to release read access on your member.
+ We use m_eLockType to differ between all possible "lock-member"!!!
+
+ @attention If a shareable osl mutex exist, he must be used as twice!
+ It's neccessary for some cppu-helper classes ...
+
+ @seealso method acquireReadAccess()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+void LockHelper::releaseReadAccess()
+{
+ switch( m_eLockType )
+ {
+ case E_NOTHING : break; // There is nothing to do ...
+ case E_OWNMUTEX : {
+ m_pOwnMutex->release();
+ }
+ break;
+ case E_SOLARMUTEX : {
+ m_pSolarMutex->release();
+ }
+ break;
+ case E_FAIRRWLOCK : {
+ m_pFairRWLock->releaseReadAccess();
+ }
+ break;
+ }
+}
+
+/*-************************************************************************************************************//**
+ @interface IRWLock
+ @short set lock for writing
+ @descr A guard should call this method to acquire write access on your member.
+ Reading is allowed too - of course.
+ After successfully calling of this method you are the only writer.
+ We use m_eLockType to differ between all possible "lock-member"!!!
+
+ @attention If a shareable osl mutex exist, he must be used as twice!
+ It's neccessary for some cppu-helper classes ...
+
+ @seealso method releaseWriteAccess()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+void LockHelper::acquireWriteAccess()
+{
+ switch( m_eLockType )
+ {
+ case E_NOTHING : break; // There is nothing to do ...
+ case E_OWNMUTEX : {
+ m_pOwnMutex->acquire();
+ }
+ break;
+ case E_SOLARMUTEX : {
+ m_pSolarMutex->acquire();
+ }
+ break;
+ case E_FAIRRWLOCK : {
+ m_pFairRWLock->acquireWriteAccess();
+ }
+ break;
+ }
+}
+
+/*-************************************************************************************************************//**
+ @interface IRWLock
+ @short reset lock for writing
+ @descr A guard should call this method to release write access on your member.
+ We use m_eLockType to differ between all possible "lock-member"!!!
+
+ @attention If a shareable osl mutex exist, he must be used as twice!
+ It's neccessary for some cppu-helper classes ...
+
+ @seealso method acquireWriteAccess()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+void LockHelper::releaseWriteAccess()
+{
+ switch( m_eLockType )
+ {
+ case E_NOTHING : break; // There is nothing to do ...
+ case E_OWNMUTEX : {
+ m_pOwnMutex->release();
+ }
+ break;
+ case E_SOLARMUTEX : {
+ m_pSolarMutex->release();
+ }
+ break;
+ case E_FAIRRWLOCK : {
+ m_pFairRWLock->releaseWriteAccess();
+ }
+ break;
+ }
+}
+
+/*-************************************************************************************************************//**
+ @interface IRWLock
+ @short downgrade a write access to a read access
+ @descr A guard should call this method to change a write to a read access.
+ New readers can work too - new writer are blocked!
+ We use m_eLockType to differ between all possible "lock-member"!!!
+
+ @attention Ignore shareable mutex(!) - because this call never should release a lock completly!
+ We change a write access to a read access only.
+
+ @attention a) Don't call this method if you are not a writer!
+ Results are not defined then ...
+ An upgrade can't be implemented realy ... because acquiring new access
+ will be the same - there no differences!
+ b) Without function if m_eLockTyp is different from E_FAIRRWLOCK(!) ...
+ because, a mutex don't support it realy.
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+void LockHelper::downgradeWriteAccess()
+{
+ switch( m_eLockType )
+ {
+ case E_NOTHING : break; // There is nothing to do ...
+ case E_OWNMUTEX : break; // Not supported for mutex!
+ case E_SOLARMUTEX : break; // Not supported for mutex!
+ case E_FAIRRWLOCK : m_pFairRWLock->downgradeWriteAccess();
+ break;
+ }
+}
+
+/*-************************************************************************************************************//**
+ @short return a reference to a static lock helper
+ @descr Sometimes we need the global mutex or rw-lock! (e.g. in our own static methods)
+ But it's not a good idea to use these global one very often ...
+ Thats why we use this little helper method.
+ We create our own "class global static" lock.
+ It will be created at first call only!
+ All other requests use these created one then directly.
+
+ @seealso -
+
+ @param -
+ @return A reference to a static mutex/lock member.
+
+ @onerror No error should occure.
+*//*-*************************************************************************************************************/
+LockHelper& LockHelper::getGlobalLock( ::osl::SolarMutex* pSolarMutex )
+{
+ // Initialize static "member" only for one time!
+ // Algorithm:
+ // a) Start with an invalid lock (NULL pointer)
+ // b) If these method first called (lock not already exist!) ...
+ // c) ... we must create a new one. Protect follow code with the global mutex -
+ // (It must be - we create a static variable!)
+ // d) Check pointer again - because ... another instance of our class could be faster then these one!
+ // e) Create the new lock and set it for return on static variable.
+ // f) Return new created or already existing lock object.
+ static LockHelper* pLock = NULL;
+ if( pLock == NULL )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( pLock == NULL )
+ {
+ static LockHelper aLock( pSolarMutex );
+ pLock = &aLock;
+ }
+ }
+ return *pLock;
+}
+
+/*-************************************************************************************************************//**
+ @short return a reference to shared mutex member
+ @descr Sometimes we need a osl-mutex for sharing with our uno helper ...
+ What can we do?
+ a) If we have an initialized "own mutex" ... we can use it!
+ b) Otherwhise we must use a different mutex member :-(
+ I HOPE IT WORKS!
+
+ @seealso -
+
+ @param -
+ @return A reference to a shared mutex.
+
+ @onerror No error should occure.
+*//*-*************************************************************************************************************/
+::osl::Mutex& LockHelper::getShareableOslMutex()
+{
+ if( m_pShareableOslMutex == NULL )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( m_pShareableOslMutex == NULL )
+ {
+ switch( m_eLockType )
+ {
+ case E_OWNMUTEX : {
+ m_pShareableOslMutex = m_pOwnMutex;
+ }
+ break;
+ default : {
+ m_pShareableOslMutex = new ::osl::Mutex;
+ }
+ break;
+ }
+ }
+ }
+ return *m_pShareableOslMutex;
+}
+
+/*-************************************************************************************************************//**
+ @short search for right lock type, which should be used by an instance of this struct
+ @descr We must initialize our member "m_eLockType". This value specify handling of locking.
+ How we can do that? We search for an environment variable. We do it only for one time ....
+ because the environment is fix. So we safe this value and use it for all further requests.
+ If no variable could be found - we use a fallback!
+
+ @attention We have numbered all our enum values for ELockType. So we can use it as value of searched
+ environment variable too!
+
+ @seealso enum ELockType
+ @seealso environment LOCKTYPE
+
+ @param -
+ @return A reference to a created and right initialized lock type!
+
+ @onerror We use a fallback!
+*//*-*************************************************************************************************************/
+ELockType& LockHelper::implts_getLockType()
+{
+ // Initialize static "member" only for one time!
+ // Algorithm:
+ // a) Start with an invalid variable (NULL pointer)
+ // b) If these method first called (value not already exist!) ...
+ // c) ... we must create a new one. Protect follow code with the global mutex -
+ // (It must be - we create a static variable!)
+ // d) Check pointer again - because ... another instance of our class could be faster then these one!
+ // e) Create the new static variable, get value from the environment and set it
+ // f) Return new created or already existing static variable.
+ static ELockType* pType = NULL;
+ if( pType == NULL )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( pType == NULL )
+ {
+ static ELockType eType = FALLBACK_LOCKTYPE;
+
+ ::rtl::OUString aEnvVar( ENVVAR_LOCKTYPE );
+ ::rtl::OUString sValue ;
+ if( osl_getEnvironment( aEnvVar.pData, &sValue.pData ) == osl_Process_E_None )
+ {
+ eType = (ELockType)(sValue.toInt32());
+ }
+
+ LOG_LOCKTYPE( FALLBACK_LOCKTYPE, eType )
+
+ pType = &eType;
+ }
+ }
+ return *pType;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/threadhelp/transactionmanager.cxx b/framework/source/fwi/threadhelp/transactionmanager.cxx
new file mode 100644
index 000000000000..557620d91a32
--- /dev/null
+++ b/framework/source/fwi/threadhelp/transactionmanager.cxx
@@ -0,0 +1,377 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/transactionmanager.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <macros/debug.hxx>
+
+#include <macros/generic.hxx>
+#include <fwidllapi.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/DisposedException.hpp>
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported declarations
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+/*-************************************************************************************************************//**
+ @short standard ctor
+ @descr Initialize instance with right start values for correct working.
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+TransactionManager::TransactionManager()
+ : m_eWorkingMode ( E_INIT )
+ , m_nTransactionCount ( 0 )
+{
+ m_aBarrier.open();
+}
+
+/*-************************************************************************************************************//**
+ @short standard dtor
+ @descr -
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+TransactionManager::~TransactionManager()
+{
+}
+
+/*-****************************************************************************************************//**
+ @interface ITransactionManager
+ @short set new working mode
+ @descr These implementation knows for states of working: E_INIT, E_WORK, E_CLOSING, E_CLOSE
+ You can step during this ones only from the left to the right side and start at left side again!
+ (This is neccessary e.g. for refcounted objects!)
+ This call will block till all current existing transactions was finished.
+ Follow results occure:
+ E_INIT : All requests on this implementation are refused.
+ It's your decision to react in a right way.
+
+ E_WORK : The object can work now. The full functionality is available.
+
+ E_BEFORECLOSE : The object start the closing mechanism ... but sometimes
+ e.g. the dispose() method need to call some private methods.
+ These some special methods should use E_SOFTEXCEPTIONS or ignore
+ E_INCLOSE as returned reason for E_NOEXCEPTIONS to detect this special case!
+
+ E_CLOSE : Object is already dead! All further requests will be refused.
+ It's your decision to react in a right way.
+
+ @seealso -
+
+ @param "eMode", is the new mode - but we don't accept setting mode in wrong order!
+ @return -
+
+ @onerror We do nothing.
+*//*-*****************************************************************************************************/
+void TransactionManager::setWorkingMode( EWorkingMode eMode )
+{
+ // Safe member access.
+ ::osl::ClearableMutexGuard aAccessGuard( m_aAccessLock );
+ sal_Bool bWaitFor = sal_False ;
+ // Change working mode first!
+ if (
+ ( m_eWorkingMode == E_INIT && eMode == E_WORK ) ||
+ ( m_eWorkingMode == E_WORK && eMode == E_BEFORECLOSE ) ||
+ ( m_eWorkingMode == E_BEFORECLOSE && eMode == E_CLOSE ) ||
+ ( m_eWorkingMode == E_CLOSE && eMode == E_INIT )
+ )
+ {
+ m_eWorkingMode = eMode;
+ if( m_eWorkingMode == E_BEFORECLOSE || m_eWorkingMode == E_CLOSE )
+ {
+ bWaitFor = sal_True;
+ }
+ }
+
+ // Wait for current existing transactions then!
+ // (Only neccessary for changing to E_BEFORECLOSE or E_CLOSE! ...
+ // otherwise; if you wait at setting E_WORK another thrad could finish a acquire-call during our unlock() and wait() call
+ // ... and we will wait forever here!!!)
+ // Don't forget to release access mutex before.
+ aAccessGuard.clear();
+ if( bWaitFor == sal_True )
+ {
+ m_aBarrier.wait();
+ }
+}
+
+/*-****************************************************************************************************//**
+ @interface ITransactionManager
+ @short get current working mode
+ @descr If you stand in your close() or init() method ... but don't know
+ if you called more then ones(!) ... you can use this function to get
+ right information.
+ e.g: You have a method init() which is used to change working mode from
+ E_INIT to E_WORK and should be used to initialize some member too ...
+ What should you do:
+
+ void init( sal_Int32 nValue )
+ {
+ // Reject this call if our transaction manager say: "Object already initialized!"
+ // Otherwise initialize your member.
+ if( m_aTransactionManager.getWorkingMode() == E_INIT )
+ {
+ // Object is uninitialized ...
+ // Make member access threadsafe!
+ ResetableGuard aGuard( m_aMutex );
+
+ // Check working mode again .. because anozï¿œther instance could be faster.
+ // (It's possible to set this guard at first of this method too!)
+ if( m_aTransactionManager.getWorkingMode() == E_INIT )
+ {
+ m_aMember = nValue;
+
+ // Object is initialized now ... set working mode to E_WORK!
+ m_aTransactionManager.setWorkingMode( E_WORK );
+ }
+ }
+ }
+
+ @seealso method setWorkingMode()
+
+ @param -
+ @return Current set mode.
+
+ @onerror No error should occure.
+*//*-*****************************************************************************************************/
+EWorkingMode TransactionManager::getWorkingMode() const
+{
+ // Synchronize access to internal member!
+ ::osl::MutexGuard aAccessLock( m_aAccessLock );
+ return m_eWorkingMode;
+}
+
+/*-****************************************************************************************************//**
+ @interface ITransactionManager
+ @short start new transaction
+ @descr A guard should use this method to start a new transaction. He should looks for rejected
+ calls to by using parameter eMode and eReason.
+ If call was not rejected your transaction will be non breakable during releasing your transaction
+ guard! BUT ... your code isn't threadsafe then! It's a transaction manager only ....
+
+ @seealso method unregisterTransaction()
+
+ @param "eMode" ,used to enable/disable throwing exceptions automaticly for rejected calls
+ @param "eReason" ,reason for rejected calls if eMode=E_NOEXCEPTIONS
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void TransactionManager::registerTransaction( EExceptionMode eMode, ERejectReason& eReason ) throw( css::uno::RuntimeException, css::lang::DisposedException )
+{
+ // Look for rejected calls first.
+ // If call was refused we throw some exceptions or do nothing!
+ // It depends from given parameter eMode.
+ if( isCallRejected( eReason ) == sal_True )
+ {
+ impl_throwExceptions( eMode, eReason );
+ }
+
+ // BUT if no exception was thrown ... (may be eMode = E_SOFTEXCEPTIONS!)
+ // we must register this transaction too!
+ // Don't use "else" or a new scope here!!!
+
+ // Safe access to internal member.
+ ::osl::MutexGuard aAccessGuard( m_aAccessLock );
+
+ #ifdef ENABLE_MUTEXDEBUG
+ LOG_ASSERT2( m_nTransactionCount<0, "TransactionManager::acquire()", "Wrong ref count detected!" )
+ #endif
+
+ // Register this new transaction.
+ // If it is the first one .. close gate to disable changing of working mode.
+ ++m_nTransactionCount;
+ if( m_nTransactionCount == 1 )
+ {
+ m_aBarrier.close();
+ }
+}
+
+/*-****************************************************************************************************//**
+ @interface ITransactionManager
+ @short finish transaction
+ @descr A guard should call this method to release current transaction.
+
+ @seealso method registerTransaction()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void TransactionManager::unregisterTransaction() throw( css::uno::RuntimeException, css::lang::DisposedException )
+{
+ // This call could not rejected!
+ // Safe access to internal member.
+ ::osl::MutexGuard aAccessGuard( m_aAccessLock );
+
+ #ifdef ENABLE_MUTEXDEBUG
+ LOG_ASSERT2( m_nTransactionCount<=0, "TransactionManager::release()", "Wrong ref count detected!" )
+ #endif
+
+ // Deregister this transaction.
+ // If it was the last one ... open gate to enable changing of working mode!
+ // (see setWorkingMode())
+
+ --m_nTransactionCount;
+ if( m_nTransactionCount == 0 )
+ {
+ m_aBarrier.open();
+ }
+}
+
+/*-****************************************************************************************************//**
+ @interface ITransactionManager
+ @short look for rejected calls
+ @descr Sometimes user need a possibility to get information about rejected calls
+ without starting a transaction!
+
+ @seealso -
+
+ @param "eReason" returns reason of a rejected call
+ @return true if call was rejected, false otherwise
+
+ @onerror We return false.
+*//*-*****************************************************************************************************/
+sal_Bool TransactionManager::isCallRejected( ERejectReason& eReason ) const
+{
+ // This call must safe access to internal member only.
+ // Set "possible reason" for return and check reject-state then!
+ // User should look for return value first - reason then ...
+ ::osl::MutexGuard aAccessGuard( m_aAccessLock );
+ switch( m_eWorkingMode )
+ {
+ case E_INIT : eReason = E_UNINITIALIZED ;
+ break;
+ case E_WORK : eReason = E_NOREASON ;
+ break;
+ case E_BEFORECLOSE : eReason = E_INCLOSE ;
+ break;
+ case E_CLOSE : eReason = E_CLOSED ;
+ break;
+ }
+ return( eReason!=E_NOREASON );
+}
+
+/*-****************************************************************************************************//**
+ @short throw any exceptions for rejected calls
+ @descr If user whish to use our automaticly exception mode we use this impl-method.
+ We check all combinations of eReason and eExceptionMode and throw right exception with some
+ descriptions for recipient of it.
+
+ @seealso method registerTransaction()
+ @seealso enum ERejectReason
+ @seealso enum EExceptionMode
+
+ @param "eReason" , reason for rejected call
+ @param "eMode" , exception mode - set by user
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void TransactionManager::impl_throwExceptions( EExceptionMode eMode, ERejectReason eReason ) const throw( css::uno::RuntimeException, css::lang::DisposedException )
+{
+ if( eMode != E_NOEXCEPTIONS )
+ {
+ switch( eReason )
+ {
+ case E_UNINITIALIZED : if( eMode == E_HARDEXCEPTIONS )
+ {
+ // Help programmer to find out, why this exception is thrown!
+ LOG_ERROR( "TransactionManager...", "Owner instance not right initialized yet. Call was rejected! Normaly it's an algorithm error ... wrong usin of class!" )
+ //ATTENTION: temp. disabled - till all bad code positions are detected and changed! */
+ // throw css::uno::RuntimeException( DECLARE_ASCII("TransactionManager...\nOwner instance not right initialized yet. Call was rejected! Normaly it's an algorithm error ... wrong usin of class!\n" ), css::uno::Reference< css::uno::XInterface >() );
+ }
+ break;
+ case E_INCLOSE : if( eMode == E_HARDEXCEPTIONS )
+ {
+ // Help programmer to find out, why this exception is thrown!
+ LOG_ERROR( "TransactionManager...", "Owner instance stand in close method. Call was rejected!" )
+ throw css::lang::DisposedException( DECLARE_ASCII("TransactionManager...\nOwner instance stand in close method. Call was rejected!\n" ), css::uno::Reference< css::uno::XInterface >() );
+ }
+ break;
+ case E_CLOSED : {
+ // Help programmer to find out, why this exception is thrown!
+ LOG_ERROR( "TransactionManager...", "Owner instance already closed. Call was rejected!" )
+ throw css::lang::DisposedException( DECLARE_ASCII("TransactionManager...\nOwner instance already closed. Call was rejected!\n" ), css::uno::Reference< css::uno::XInterface >() );
+ }
+ case E_NOREASON : {
+ // Help programmer to find out
+ LOG_ERROR( "TransactionManager...", "Impossible case E_NOREASON!" )
+ }
+ break;
+ default: break; // nothing to do
+ }
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/uielement/constitemcontainer.cxx b/framework/source/fwi/uielement/constitemcontainer.cxx
new file mode 100644
index 000000000000..c90d0580ea1b
--- /dev/null
+++ b/framework/source/fwi/uielement/constitemcontainer.cxx
@@ -0,0 +1,481 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uielement/constitemcontainer.hxx>
+#include <uielement/rootitemcontainer.hxx>
+#include <uielement/itemcontainer.hxx>
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <cppuhelper/implbase1.hxx>
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+
+const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >";
+
+const int PROPHANDLE_UINAME = 1;
+const int PROPCOUNT = 1;
+const rtl::OUString PROPNAME_UINAME( RTL_CONSTASCII_USTRINGPARAM( "UIName" ));
+
+namespace framework
+{
+
+/**
+ * The class which implements the PropertySetInfo interface.
+ */
+extern "C"
+{
+static int SAL_CALL compare_OUString_Property_Impl( const void *arg1, const void *arg2 ) SAL_THROW( () )
+{
+ return ((::rtl::OUString *)arg1)->compareTo( ((Property *)arg2)->Name );
+}
+}
+
+class OPropertySetHelperInfo_Impl
+ : public WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo >
+{
+ Sequence < Property > aInfos;
+
+public:
+ OPropertySetHelperInfo_Impl( IPropertyArrayHelper & rHelper_ ) SAL_THROW( () );
+
+ // XPropertySetInfo-Methoden
+ virtual Sequence< Property > SAL_CALL getProperties(void) throw(::com::sun::star::uno::RuntimeException);
+ virtual Property SAL_CALL getPropertyByName(const ::rtl::OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& PropertyName) throw(::com::sun::star::uno::RuntimeException);
+};
+
+
+/**
+ * Create an object that implements XPropertySetInfo IPropertyArrayHelper.
+ */
+OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl(
+ IPropertyArrayHelper & rHelper_ )
+ SAL_THROW( () )
+ :aInfos( rHelper_.getProperties() )
+{
+}
+
+/**
+ * Return the sequence of properties, which are provided throug the constructor.
+ */
+Sequence< Property > OPropertySetHelperInfo_Impl::getProperties(void) throw(::com::sun::star::uno::RuntimeException)
+{
+ return aInfos;
+}
+
+/**
+ * Return the sequence of properties, which are provided throug the constructor.
+ */
+Property OPropertySetHelperInfo_Impl::getPropertyByName( const ::rtl::OUString & PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
+{
+ Property * pR;
+ pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(),
+ sizeof( Property ),
+ compare_OUString_Property_Impl );
+ if( !pR ) {
+ throw UnknownPropertyException();
+ }
+
+ return *pR;
+}
+
+/**
+ * Return the sequence of properties, which are provided throug the constructor.
+ */
+sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName( const ::rtl::OUString & PropertyName ) throw(::com::sun::star::uno::RuntimeException)
+{
+ Property * pR;
+ pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(),
+ sizeof( Property ),
+ compare_OUString_Property_Impl );
+ return pR != NULL;
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_6 ( ConstItemContainer ,
+ OWeakObject ,
+ DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ),
+ DIRECT_INTERFACE( ::com::sun::star::container::XElementAccess ),
+ DIRECT_INTERFACE( ::com::sun::star::container::XIndexAccess ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::lang::XUnoTunnel )
+ )
+
+DEFINE_XTYPEPROVIDER_6 ( ConstItemContainer ,
+ ::com::sun::star::lang::XTypeProvider ,
+ ::com::sun::star::container::XIndexAccess ,
+ ::com::sun::star::container::XElementAccess ,
+ ::com::sun::star::beans::XFastPropertySet ,
+ ::com::sun::star::beans::XPropertySet ,
+ ::com::sun::star::lang::XUnoTunnel
+ )
+
+ConstItemContainer::ConstItemContainer() : ::cppu::OWeakObject()
+{
+}
+
+ConstItemContainer::ConstItemContainer( const RootItemContainer& rRootItemContainer, sal_Bool bFastCopy )
+{
+ ShareGuard( rRootItemContainer.m_aShareMutex );
+
+ // If bFastCopy is set the onwer of the root item container will transfer ownership to us. So
+ // it is possible to copy only the root part.
+ m_aUIName = rRootItemContainer.m_aUIName;
+ if ( bFastCopy )
+ m_aItemVector = rRootItemContainer.m_aItemVector;
+ else
+ copyItemContainer( rRootItemContainer.m_aItemVector );
+}
+
+ConstItemContainer::ConstItemContainer( const ItemContainer& rItemContainer )
+{
+ ShareGuard( rItemContainer.m_aShareMutex );
+ copyItemContainer( rItemContainer.m_aItemVector );
+}
+
+ConstItemContainer::ConstItemContainer( const Reference< XIndexAccess >& rSourceContainer, sal_Bool bFastCopy )
+{
+ // We also have to copy the UIName property
+ try
+ {
+ Reference< XPropertySet > xPropSet( rSourceContainer, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ rtl::OUString aUIName;
+ xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= m_aUIName;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ if ( rSourceContainer.is() )
+ {
+ try
+ {
+ sal_Int32 nCount = rSourceContainer->getCount();
+ m_aItemVector.reserve(nCount);
+ if ( bFastCopy )
+ {
+ for ( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ Sequence< PropertyValue > aPropSeq;
+ if ( rSourceContainer->getByIndex( i ) >>= aPropSeq )
+ m_aItemVector.push_back( aPropSeq );
+ }
+ }
+ else
+ {
+ for ( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ Sequence< PropertyValue > aPropSeq;
+ if ( rSourceContainer->getByIndex( i ) >>= aPropSeq )
+ {
+ sal_Int32 nContainerIndex = -1;
+ Reference< XIndexAccess > xIndexAccess;
+ for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
+ {
+ if ( aPropSeq[j].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ItemDescriptorContainer" ) ))
+ {
+ aPropSeq[j].Value >>= xIndexAccess;
+ nContainerIndex = j;
+ break;
+ }
+ }
+
+ if ( xIndexAccess.is() && nContainerIndex >= 0 )
+ aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess );
+
+ m_aItemVector.push_back( aPropSeq );
+ }
+ }
+ }
+ }
+ catch ( IndexOutOfBoundsException& )
+ {
+ }
+ }
+}
+
+ConstItemContainer::~ConstItemContainer()
+{
+}
+
+// private
+void ConstItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector )
+{
+ const sal_uInt32 nCount = rSourceVector.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ sal_Int32 nContainerIndex = -1;
+ Sequence< PropertyValue > aPropSeq( rSourceVector[i] );
+ Reference< XIndexAccess > xIndexAccess;
+ for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
+ {
+ if ( aPropSeq[j].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ItemDescriptorContainer" ) ))
+ {
+ aPropSeq[j].Value >>= xIndexAccess;
+ nContainerIndex = j;
+ break;
+ }
+ }
+
+ if ( xIndexAccess.is() && nContainerIndex >= 0 )
+ aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess );
+
+ m_aItemVector.push_back( aPropSeq );
+ }
+}
+
+Reference< XIndexAccess > ConstItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer )
+{
+ Reference< XIndexAccess > xReturn;
+ if ( rSubContainer.is() )
+ {
+ ItemContainer* pSource = ItemContainer::GetImplementation( rSubContainer );
+ ConstItemContainer* pSubContainer( 0 );
+ if ( pSource )
+ pSubContainer = new ConstItemContainer( *pSource );
+ else
+ pSubContainer = new ConstItemContainer( rSubContainer );
+ xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY );
+ }
+
+ return xReturn;
+}
+
+// XUnoTunnel
+sal_Int64 ConstItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier ) throw(::com::sun::star::uno::RuntimeException)
+{
+ if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( ConstItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
+ {
+ return reinterpret_cast< sal_Int64 >( this );
+ }
+ return 0;
+}
+
+const Sequence< sal_Int8 >& ConstItemContainer::GetUnoTunnelId() throw()
+{
+ static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL;
+ if( !pSeq )
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+ConstItemContainer* ConstItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw()
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY );
+ return xUT.is() ? reinterpret_cast< ConstItemContainer* >(sal::static_int_cast< sal_IntPtr >(
+ xUT->getSomething( ConstItemContainer::GetUnoTunnelId() ))) : NULL;
+}
+
+// XElementAccess
+sal_Bool SAL_CALL ConstItemContainer::hasElements()
+throw ( RuntimeException )
+{
+ return ( !m_aItemVector.empty() );
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL ConstItemContainer::getCount()
+throw ( RuntimeException )
+{
+ return m_aItemVector.size();
+}
+
+Any SAL_CALL ConstItemContainer::getByIndex( sal_Int32 Index )
+throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ if ( sal_Int32( m_aItemVector.size()) > Index )
+ return makeAny( m_aItemVector[Index] );
+ else
+ throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
+}
+
+// XPropertySet
+Reference< XPropertySetInfo > SAL_CALL ConstItemContainer::getPropertySetInfo()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
+ static Reference< XPropertySetInfo >* pInfo = NULL;
+
+ if( pInfo == NULL )
+ {
+ // Ready for multithreading
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfo == NULL )
+ {
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+void SAL_CALL ConstItemContainer::setPropertyValue( const ::rtl::OUString&, const Any& )
+throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+Any SAL_CALL ConstItemContainer::getPropertyValue( const ::rtl::OUString& PropertyName )
+throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ if ( PropertyName.equals( PROPNAME_UINAME ))
+ return makeAny( m_aUIName );
+
+ throw UnknownPropertyException();
+}
+
+void SAL_CALL ConstItemContainer::addPropertyChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& )
+throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL ConstItemContainer::removePropertyChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& )
+throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ // Only read-only properties - do nothing
+}
+
+void SAL_CALL ConstItemContainer::addVetoableChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& )
+throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ // Only read-only properties - do nothing
+}
+
+void SAL_CALL ConstItemContainer::removeVetoableChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& )
+throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ // Only read-only properties - do nothing
+}
+
+// XFastPropertySet
+void SAL_CALL ConstItemContainer::setFastPropertyValue( sal_Int32, const ::com::sun::star::uno::Any& )
+throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+Any SAL_CALL ConstItemContainer::getFastPropertyValue( sal_Int32 nHandle )
+throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ if ( nHandle == PROPHANDLE_UINAME )
+ return makeAny( m_aUIName );
+
+ throw UnknownPropertyException();
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL ConstItemContainer::getInfoHelper()
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
+ static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ // Ready for multithreading
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfoHelper == NULL )
+ {
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
+ // "sal_True" say: Table is sorted by name.
+ static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return(*pInfoHelper);
+}
+
+const com::sun::star::uno::Sequence< com::sun::star::beans::Property > ConstItemContainer::impl_getStaticPropertyDescriptor()
+{
+ // Create a new static property array to initialize sequence!
+ // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
+ // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
+ // It's necessary for methods of OPropertySetHelper.
+ // ATTENTION:
+ // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
+
+ static const com::sun::star::beans::Property pProperties[] =
+ {
+ com::sun::star::beans::Property( PROPNAME_UINAME, PROPHANDLE_UINAME ,
+ ::getCppuType((const rtl::OUString*)NULL),
+ com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY )
+ };
+ // Use it to initialize sequence!
+ static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, PROPCOUNT );
+ // Return static "PropertyDescriptor"
+ return lPropertyDescriptor;
+}
+
+Reference < XPropertySetInfo > ConstItemContainer::createPropertySetInfo(
+ IPropertyArrayHelper & rProperties ) SAL_THROW( () )
+{
+ return static_cast< XPropertySetInfo * >( new OPropertySetHelperInfo_Impl( rProperties ) );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/uielement/itemcontainer.cxx b/framework/source/fwi/uielement/itemcontainer.cxx
new file mode 100644
index 000000000000..dca5d23da86d
--- /dev/null
+++ b/framework/source/fwi/uielement/itemcontainer.cxx
@@ -0,0 +1,268 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uielement/itemcontainer.hxx>
+#include <uielement/constitemcontainer.hxx>
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+
+const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >";
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+
+ItemContainer::ItemContainer( const ShareableMutex& rMutex ) :
+ m_aShareMutex( rMutex )
+{
+}
+
+
+ItemContainer::ItemContainer( const ConstItemContainer& rConstItemContainer, const ShareableMutex& rMutex ) : m_aShareMutex( rMutex )
+{
+ copyItemContainer( rConstItemContainer.m_aItemVector, rMutex );
+}
+
+ItemContainer::ItemContainer( const Reference< XIndexAccess >& rSourceContainer, const ShareableMutex& rMutex ) :
+ m_aShareMutex( rMutex )
+{
+ if ( rSourceContainer.is() )
+ {
+ sal_Int32 nCount = rSourceContainer->getCount();
+ try
+ {
+ for ( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ Sequence< PropertyValue > aPropSeq;
+ if ( rSourceContainer->getByIndex( i ) >>= aPropSeq )
+ {
+ sal_Int32 nContainerIndex = -1;
+ Reference< XIndexAccess > xIndexAccess;
+ for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
+ {
+ if ( aPropSeq[j].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ItemDescriptorContainer" ) ))
+ {
+ aPropSeq[j].Value >>= xIndexAccess;
+ nContainerIndex = j;
+ break;
+ }
+ }
+
+ if ( xIndexAccess.is() && nContainerIndex >= 0 )
+ aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess, rMutex );
+
+ m_aItemVector.push_back( aPropSeq );
+ }
+ }
+ }
+ catch ( IndexOutOfBoundsException& )
+ {
+ }
+ }
+}
+
+ItemContainer::~ItemContainer()
+{
+}
+
+// private
+void ItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector, const ShareableMutex& rMutex )
+{
+ const sal_uInt32 nCount = rSourceVector.size();
+ for ( sal_uInt32 i = 0; i < nCount; ++i )
+ {
+ sal_Int32 nContainerIndex = -1;
+ Sequence< PropertyValue > aPropSeq( rSourceVector[i] );
+ Reference< XIndexAccess > xIndexAccess;
+ for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
+ {
+ if ( aPropSeq[j].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ItemDescriptorContainer" ) ))
+ {
+ aPropSeq[j].Value >>= xIndexAccess;
+ nContainerIndex = j;
+ break;
+ }
+ }
+
+ if ( xIndexAccess.is() && nContainerIndex >= 0 )
+ aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess, rMutex );
+
+ m_aItemVector.push_back( aPropSeq );
+ }
+}
+
+Reference< XIndexAccess > ItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer, const ShareableMutex& rMutex )
+{
+ Reference< XIndexAccess > xReturn;
+ if ( rSubContainer.is() )
+ {
+ ConstItemContainer* pSource = ConstItemContainer::GetImplementation( rSubContainer );
+ ItemContainer* pSubContainer( 0 );
+ if ( pSource )
+ pSubContainer = new ItemContainer( *pSource, rMutex );
+ else
+ pSubContainer = new ItemContainer( rSubContainer, rMutex );
+ xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY );
+ }
+
+ return xReturn;
+}
+
+// XUnoTunnel
+sal_Int64 ItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier ) throw(::com::sun::star::uno::RuntimeException)
+{
+ if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( ItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
+
+ return 0;
+}
+
+const Sequence< sal_Int8 >& ItemContainer::GetUnoTunnelId() throw()
+{
+ static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL;
+ if( !pSeq )
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+ItemContainer* ItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw()
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY );
+ return xUT.is() ? reinterpret_cast< ItemContainer* >(sal::static_int_cast< sal_IntPtr >(
+ xUT->getSomething( ItemContainer::GetUnoTunnelId() ))) : NULL;
+}
+
+// XElementAccess
+sal_Bool SAL_CALL ItemContainer::hasElements()
+throw ( RuntimeException )
+{
+ ShareGuard aLock( m_aShareMutex );
+ return ( !m_aItemVector.empty() );
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL ItemContainer::getCount()
+throw ( RuntimeException )
+{
+ ShareGuard aLock( m_aShareMutex );
+ return m_aItemVector.size();
+}
+
+Any SAL_CALL ItemContainer::getByIndex( sal_Int32 Index )
+throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ShareGuard aLock( m_aShareMutex );
+ if ( sal_Int32( m_aItemVector.size()) > Index )
+ return makeAny( m_aItemVector[Index] );
+ else
+ throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
+}
+
+// XIndexContainer
+void SAL_CALL ItemContainer::insertByIndex( sal_Int32 Index, const Any& aItem )
+throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ Sequence< PropertyValue > aSeq;
+ if ( aItem >>= aSeq )
+ {
+ ShareGuard aLock( m_aShareMutex );
+ if ( sal_Int32( m_aItemVector.size()) == Index )
+ m_aItemVector.push_back( aSeq );
+ else if ( sal_Int32( m_aItemVector.size()) >Index )
+ {
+ std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
+ aIter += Index;
+ m_aItemVector.insert( aIter, aSeq );
+ }
+ else
+ throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
+ }
+ else
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
+ (OWeakObject *)this, 2 );
+}
+
+void SAL_CALL ItemContainer::removeByIndex( sal_Int32 Index )
+throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ShareGuard aLock( m_aShareMutex );
+ if ( (sal_Int32)m_aItemVector.size() > Index )
+ {
+ std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
+ aIter += Index;
+ m_aItemVector.erase( aIter );
+ }
+ else
+ throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
+}
+
+void SAL_CALL ItemContainer::replaceByIndex( sal_Int32 Index, const Any& aItem )
+throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ Sequence< PropertyValue > aSeq;
+ if ( aItem >>= aSeq )
+ {
+ ShareGuard aLock( m_aShareMutex );
+ if ( sal_Int32( m_aItemVector.size()) > Index )
+ m_aItemVector[Index] = aSeq;
+ else
+ throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
+ }
+ else
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
+ (OWeakObject *)this, 2 );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/fwi/uielement/rootitemcontainer.cxx b/framework/source/fwi/uielement/rootitemcontainer.cxx
new file mode 100644
index 000000000000..e8759b0c0e7b
--- /dev/null
+++ b/framework/source/fwi/uielement/rootitemcontainer.cxx
@@ -0,0 +1,464 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uielement/rootitemcontainer.hxx>
+
+#include <uielement/itemcontainer.hxx>
+
+#include <uielement/constitemcontainer.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <general.h>
+#include <properties.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+
+const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >";
+
+const int PROPHANDLE_UINAME = 1;
+const int PROPCOUNT = 1;
+const rtl::OUString PROPNAME_UINAME( RTL_CONSTASCII_USTRINGPARAM( "UIName" ));
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_10 ( RootItemContainer ,
+ OWeakObject ,
+ DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ),
+ DIRECT_INTERFACE( ::com::sun::star::container::XIndexContainer ),
+ DIRECT_INTERFACE( ::com::sun::star::lang::XUnoTunnel ),
+ DIRECT_INTERFACE( ::com::sun::star::lang::XSingleComponentFactory ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ),
+ DERIVED_INTERFACE( ::com::sun::star::container::XIndexReplace, com::sun::star::container::XIndexContainer ),
+ DERIVED_INTERFACE( ::com::sun::star::container::XIndexAccess, com::sun::star::container::XIndexReplace ),
+ DERIVED_INTERFACE( ::com::sun::star::container::XElementAccess, ::com::sun::star::container::XIndexAccess )
+ )
+
+DEFINE_XTYPEPROVIDER_10 ( RootItemContainer ,
+ ::com::sun::star::lang::XTypeProvider ,
+ ::com::sun::star::container::XIndexContainer ,
+ ::com::sun::star::container::XIndexReplace ,
+ ::com::sun::star::container::XIndexAccess ,
+ ::com::sun::star::container::XElementAccess ,
+ ::com::sun::star::beans::XMultiPropertySet ,
+ ::com::sun::star::beans::XFastPropertySet ,
+ ::com::sun::star::beans::XPropertySet ,
+ ::com::sun::star::lang::XUnoTunnel ,
+ ::com::sun::star::lang::XSingleComponentFactory
+ )
+
+RootItemContainer::RootItemContainer()
+ : ThreadHelpBase ( )
+ , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
+ , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
+ , ::cppu::OWeakObject()
+{
+}
+
+RootItemContainer::RootItemContainer( const ConstItemContainer& rConstItemContainer )
+ : ThreadHelpBase ( )
+ , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
+ , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
+ , ::cppu::OWeakObject()
+{
+ m_aUIName = rConstItemContainer.m_aUIName;
+ copyItemContainer( rConstItemContainer.m_aItemVector );
+}
+
+RootItemContainer::RootItemContainer( const Reference< XIndexAccess >& rSourceContainer )
+ : ThreadHelpBase ( )
+ , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
+ , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
+ , ::cppu::OWeakObject()
+{
+ // We also have to copy the UIName property
+ try
+ {
+ Reference< XPropertySet > xPropSet( rSourceContainer, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= m_aUIName;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ if ( rSourceContainer.is() )
+ {
+ sal_Int32 nCount = rSourceContainer->getCount();
+ try
+ {
+ for ( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ Sequence< PropertyValue > aPropSeq;
+ if ( rSourceContainer->getByIndex( i ) >>= aPropSeq )
+ {
+ sal_Int32 nContainerIndex = -1;
+ Reference< XIndexAccess > xIndexAccess;
+ for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
+ {
+ if ( aPropSeq[j].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ItemDescriptorContainer" ) ))
+ {
+ aPropSeq[j].Value >>= xIndexAccess;
+ nContainerIndex = j;
+ break;
+ }
+ }
+
+ if ( xIndexAccess.is() && nContainerIndex >= 0 )
+ aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess );
+
+ m_aItemVector.push_back( aPropSeq );
+ }
+ }
+ }
+ catch ( IndexOutOfBoundsException& )
+ {
+ }
+ }
+}
+
+RootItemContainer::~RootItemContainer()
+{
+}
+
+// private
+void RootItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector )
+{
+ const sal_uInt32 nCount = rSourceVector.size();
+ m_aItemVector.reserve(nCount);
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ sal_Int32 nContainerIndex = -1;
+ Sequence< PropertyValue > aPropSeq( rSourceVector[i] );
+ Reference< XIndexAccess > xIndexAccess;
+ for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
+ {
+ if ( aPropSeq[j].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ItemDescriptorContainer" ) ))
+ {
+ aPropSeq[j].Value >>= xIndexAccess;
+ nContainerIndex = j;
+ break;
+ }
+ }
+
+ if ( xIndexAccess.is() && nContainerIndex >= 0 )
+ aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess );
+
+ m_aItemVector.push_back( aPropSeq );
+ }
+}
+
+Reference< XIndexAccess > RootItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer )
+{
+ Reference< XIndexAccess > xReturn;
+ if ( rSubContainer.is() )
+ {
+ ConstItemContainer* pSource = ConstItemContainer::GetImplementation( rSubContainer );
+ ItemContainer* pSubContainer( 0 );
+ if ( pSource )
+ pSubContainer = new ItemContainer( *pSource, m_aShareMutex );
+ else
+ pSubContainer = new ItemContainer( rSubContainer, m_aShareMutex );
+ xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY );
+ }
+
+ return xReturn;
+}
+
+// XUnoTunnel
+sal_Int64 RootItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier ) throw(::com::sun::star::uno::RuntimeException)
+{
+ if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( RootItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
+ return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
+ return 0;
+}
+
+const Sequence< sal_Int8 >& RootItemContainer::GetUnoTunnelId() throw()
+{
+ static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL;
+ if( !pSeq )
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+RootItemContainer* RootItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw()
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY );
+ return xUT.is() ? reinterpret_cast< RootItemContainer* >(sal::static_int_cast< sal_IntPtr >(
+ xUT->getSomething( RootItemContainer::GetUnoTunnelId() ))) : NULL;
+}
+
+// XElementAccess
+sal_Bool SAL_CALL RootItemContainer::hasElements()
+throw ( RuntimeException )
+{
+ ShareGuard aLock( m_aShareMutex );
+ return ( !m_aItemVector.empty() );
+}
+
+// XIndexAccess
+sal_Int32 SAL_CALL RootItemContainer::getCount()
+throw ( RuntimeException )
+{
+ ShareGuard aLock( m_aShareMutex );
+ return m_aItemVector.size();
+}
+
+Any SAL_CALL RootItemContainer::getByIndex( sal_Int32 Index )
+throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ShareGuard aLock( m_aShareMutex );
+ if ( sal_Int32( m_aItemVector.size()) > Index )
+ return makeAny( m_aItemVector[Index] );
+ else
+ throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
+}
+
+// XIndexContainer
+void SAL_CALL RootItemContainer::insertByIndex( sal_Int32 Index, const Any& aItem )
+throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ Sequence< PropertyValue > aSeq;
+ if ( aItem >>= aSeq )
+ {
+ ShareGuard aLock( m_aShareMutex );
+ if ( sal_Int32( m_aItemVector.size()) == Index )
+ m_aItemVector.push_back( aSeq );
+ else if ( sal_Int32( m_aItemVector.size()) >Index )
+ {
+ std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
+ aIter += Index;
+ m_aItemVector.insert( aIter, aSeq );
+ }
+ else
+ throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
+ }
+ else
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
+ (OWeakObject *)this, 2 );
+}
+
+void SAL_CALL RootItemContainer::removeByIndex( sal_Int32 Index )
+throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ShareGuard aLock( m_aShareMutex );
+ if ( (sal_Int32)m_aItemVector.size() > Index )
+ {
+ std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
+ aIter += Index;
+ m_aItemVector.erase( aIter );
+ }
+ else
+ throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
+}
+
+void SAL_CALL RootItemContainer::replaceByIndex( sal_Int32 Index, const Any& aItem )
+throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ Sequence< PropertyValue > aSeq;
+ if ( aItem >>= aSeq )
+ {
+ ShareGuard aLock( m_aShareMutex );
+ if ( sal_Int32( m_aItemVector.size()) > Index )
+ m_aItemVector[Index] = aSeq;
+ else
+ throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
+ }
+ else
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
+ (OWeakObject *)this, 2 );
+}
+
+Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithContext( const Reference< XComponentContext >& )
+throw ( Exception, RuntimeException)
+{
+ return (OWeakObject *)(new ItemContainer( m_aShareMutex ));
+}
+
+Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithArgumentsAndContext( const Sequence< Any >&, const Reference< XComponentContext >& )
+throw (Exception, RuntimeException)
+{
+ return (OWeakObject *)(new ItemContainer( m_aShareMutex ));
+}
+
+// XPropertySet helper
+sal_Bool SAL_CALL RootItemContainer::convertFastPropertyValue( Any& aConvertedValue ,
+ Any& aOldValue ,
+ sal_Int32 nHandle ,
+ const Any& aValue )
+throw( com::sun::star::lang::IllegalArgumentException )
+{
+ // Initialize state with sal_False !!!
+ // (Handle can be invalid)
+ sal_Bool bReturn = sal_False;
+
+ switch( nHandle )
+ {
+ case PROPHANDLE_UINAME:
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny(m_aUIName),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+ }
+
+ // Return state of operation.
+ return bReturn ;
+}
+
+void SAL_CALL RootItemContainer::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle ,
+ const com::sun::star::uno::Any& aValue )
+throw( com::sun::star::uno::Exception )
+{
+ switch( nHandle )
+ {
+ case PROPHANDLE_UINAME:
+ aValue >>= m_aUIName;
+ break;
+ }
+}
+
+void SAL_CALL RootItemContainer::getFastPropertyValue( com::sun::star::uno::Any& aValue ,
+ sal_Int32 nHandle ) const
+{
+ switch( nHandle )
+ {
+ case PROPHANDLE_UINAME:
+ aValue <<= m_aUIName;
+ break;
+ }
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL RootItemContainer::getInfoHelper()
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
+ static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ // Ready for multithreading
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfoHelper == NULL )
+ {
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
+ // "sal_True" say: Table is sorted by name.
+ static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return(*pInfoHelper);
+}
+
+com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL RootItemContainer::getPropertySetInfo()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
+ static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL;
+
+ if( pInfo == NULL )
+ {
+ // Ready for multithreading
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfo == NULL )
+ {
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+const com::sun::star::uno::Sequence< com::sun::star::beans::Property > RootItemContainer::impl_getStaticPropertyDescriptor()
+{
+ // Create a new static property array to initialize sequence!
+ // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
+ // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
+ // It's necessary for methods of OPropertySetHelper.
+ // ATTENTION:
+ // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
+
+ static const com::sun::star::beans::Property pProperties[] =
+ {
+ com::sun::star::beans::Property( PROPNAME_UINAME, PROPHANDLE_UINAME ,
+ ::getCppuType((const rtl::OUString*)NULL),
+ com::sun::star::beans::PropertyAttribute::TRANSIENT )
+ };
+ // Use it to initialize sequence!
+ static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, PROPCOUNT );
+ // Return static "PropertyDescriptor"
+ return lPropertyDescriptor;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/dockingareadefaultacceptor.cxx b/framework/source/helper/dockingareadefaultacceptor.cxx
new file mode 100644
index 000000000000..f10851081624
--- /dev/null
+++ b/framework/source/helper/dockingareadefaultacceptor.cxx
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <helper/dockingareadefaultacceptor.hxx>
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XLayoutConstrains.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+using namespace ::com::sun::star::container ;
+using namespace ::com::sun::star::frame ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::uno ;
+using namespace ::cppu ;
+using namespace ::osl ;
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+DockingAreaDefaultAcceptor::DockingAreaDefaultAcceptor( const css::uno::Reference< XFrame >& xOwner )
+ // Init baseclasses first
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ // Init member
+ , m_xOwner ( xOwner )
+{
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+DockingAreaDefaultAcceptor::~DockingAreaDefaultAcceptor()
+{
+}
+
+//*****************************************************************************************************************
+// XDockingAreaAcceptor
+//*****************************************************************************************************************
+css::uno::Reference< css::awt::XWindow > SAL_CALL DockingAreaDefaultAcceptor::getContainerWindow() throw (css::uno::RuntimeException)
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Try to "lock" the frame for access to taskscontainer.
+ css::uno::Reference< XFrame > xFrame( m_xOwner.get(), UNO_QUERY );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow( xFrame->getContainerWindow() );
+
+ return xContainerWindow;
+}
+
+sal_Bool SAL_CALL DockingAreaDefaultAcceptor::requestDockingAreaSpace( const css::awt::Rectangle& RequestedSpace ) throw (css::uno::RuntimeException)
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Try to "lock" the frame for access to taskscontainer.
+ css::uno::Reference< XFrame > xFrame( m_xOwner.get(), UNO_QUERY );
+ aGuard.unlock();
+
+ if ( xFrame.is() == sal_True )
+ {
+ css::uno::Reference< css::awt::XWindow > xContainerWindow( xFrame->getContainerWindow() );
+ css::uno::Reference< css::awt::XWindow > xComponentWindow( xFrame->getComponentWindow() );
+
+ if (( xContainerWindow.is() == sal_True ) &&
+ ( xComponentWindow.is() == sal_True ) )
+ {
+ css::uno::Reference< css::awt::XDevice > xDevice( xContainerWindow, css::uno::UNO_QUERY );
+ // Convert relativ size to output size.
+ css::awt::Rectangle aRectangle = xContainerWindow->getPosSize();
+ css::awt::DeviceInfo aInfo = xDevice->getInfo();
+ css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
+ aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
+
+ css::awt::Size aMinSize( 0, 0 ); // = xLayoutContrains->getMinimumSize();
+
+ // Check if request border space would decrease component window size below minimum size
+ if ((( aSize.Width - RequestedSpace.X - RequestedSpace.Width ) < aMinSize.Width ) ||
+ (( aSize.Height - RequestedSpace.Y - RequestedSpace.Height ) < aMinSize.Height ) )
+ return sal_False;
+
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+void SAL_CALL DockingAreaDefaultAcceptor::setDockingAreaSpace( const css::awt::Rectangle& BorderSpace ) throw (css::uno::RuntimeException)
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Try to "lock" the frame for access to taskscontainer.
+ css::uno::Reference< XFrame > xFrame( m_xOwner.get(), UNO_QUERY );
+ if ( xFrame.is() == sal_True )
+ {
+ css::uno::Reference< css::awt::XWindow > xContainerWindow( xFrame->getContainerWindow() );
+ css::uno::Reference< css::awt::XWindow > xComponentWindow( xFrame->getComponentWindow() );
+
+ if (( xContainerWindow.is() == sal_True ) &&
+ ( xComponentWindow.is() == sal_True ) )
+ {
+ css::uno::Reference< css::awt::XDevice > xDevice( xContainerWindow, css::uno::UNO_QUERY );
+ // Convert relativ size to output size.
+ css::awt::Rectangle aRectangle = xContainerWindow->getPosSize();
+ css::awt::DeviceInfo aInfo = xDevice->getInfo();
+ css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
+ aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
+ css::awt::Size aMinSize( 0, 0 );// = xLayoutContrains->getMinimumSize();
+
+ // Check if request border space would decrease component window size below minimum size
+ sal_Int32 nWidth = aSize.Width - BorderSpace.X - BorderSpace.Width;
+ sal_Int32 nHeight = aSize.Height - BorderSpace.Y - BorderSpace.Height;
+
+ if (( nWidth > aMinSize.Width ) && ( nHeight > aMinSize.Height ))
+ {
+ // Resize our component window.
+ xComponentWindow->setPosSize( BorderSpace.X, BorderSpace.Y, nWidth, nHeight, css::awt::PosSize::POSSIZE );
+ }
+ }
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/ocomponentaccess.cxx b/framework/source/helper/ocomponentaccess.cxx
new file mode 100644
index 000000000000..f070e85a6c35
--- /dev/null
+++ b/framework/source/helper/ocomponentaccess.cxx
@@ -0,0 +1,263 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <helper/ocomponentaccess.hxx>
+#include <helper/ocomponentenumeration.hxx>
+
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+using namespace ::com::sun::star::container ;
+using namespace ::com::sun::star::frame ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::uno ;
+using namespace ::cppu ;
+using namespace ::osl ;
+using namespace ::rtl ;
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+OComponentAccess::OComponentAccess( const css::uno::Reference< XDesktop >& xOwner )
+ // Init baseclasses first
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ // Init member
+ , m_xOwner ( xOwner )
+{
+ // Safe impossible cases
+ LOG_ASSERT( impldbg_checkParameter_OComponentAccessCtor( xOwner ), "OComponentAccess::OComponentAccess()\nInvalid parameter detected!\n" )
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+OComponentAccess::~OComponentAccess()
+{
+}
+
+//*****************************************************************************************************************
+// XEnumerationAccess
+//*****************************************************************************************************************
+css::uno::Reference< XEnumeration > SAL_CALL OComponentAccess::createEnumeration() throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Set default return value, if method failed.
+ // If no desktop exist and there is no task container - return an empty enumeration!
+ css::uno::Reference< XEnumeration > xReturn = css::uno::Reference< XEnumeration >();
+
+ // Try to "lock" the desktop for access to task container.
+ css::uno::Reference< XInterface > xLock = m_xOwner.get();
+ if ( xLock.is() == sal_True )
+ {
+ // Desktop exist => pointer to task container must be valid.
+ // Initialize a new enumeration ... if some tasks and his components exist!
+ // (OTasksEnumeration will make an assert, if we initialize the new instance without valid values!)
+
+ Sequence< css::uno::Reference< XComponent > > seqComponents;
+ impl_collectAllChildComponents( css::uno::Reference< XFramesSupplier >( xLock, UNO_QUERY ), seqComponents );
+ OComponentEnumeration* pEnumeration = new OComponentEnumeration( seqComponents );
+ xReturn = css::uno::Reference< XEnumeration >( (OWeakObject*)pEnumeration, UNO_QUERY );
+ }
+
+ // Return result of this operation.
+ return xReturn;
+}
+
+//*****************************************************************************************************************
+// XElementAccess
+//*****************************************************************************************************************
+Type SAL_CALL OComponentAccess::getElementType() throw( RuntimeException )
+{
+ // Elements in list an enumeration are components!
+ // Return the uno-type of XComponent.
+ return ::getCppuType((const css::uno::Reference< XComponent >*)NULL);
+}
+
+//*****************************************************************************************************************
+// XElementAccess
+//*****************************************************************************************************************
+sal_Bool SAL_CALL OComponentAccess::hasElements() throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Set default return value, if method failed.
+ sal_Bool bReturn = sal_False;
+
+ // Try to "lock" the desktop for access to task container.
+ css::uno::Reference< XFramesSupplier > xLock( m_xOwner.get(), UNO_QUERY );
+ if ( xLock.is() == sal_True )
+ {
+ // Ask container of owner for existing elements.
+ bReturn = xLock->getFrames()->hasElements();
+ }
+
+ // Return result of this operation.
+ return bReturn;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void OComponentAccess::impl_collectAllChildComponents( const css::uno::Reference< XFramesSupplier >& xNode ,
+ Sequence< css::uno::Reference< XComponent > >& seqComponents )
+{
+ // If valid node was given ...
+ if( xNode.is() == sal_True )
+ {
+ // ... continue collection at these.
+
+ // Get the container of current node, collect the components of existing child frames
+ // and go down to next level in tree (recursive!).
+
+ sal_Int32 nComponentCount = seqComponents.getLength();
+
+ const css::uno::Reference< XFrames > xContainer = xNode->getFrames();
+ const Sequence< css::uno::Reference< XFrame > > seqFrames = xContainer->queryFrames( FrameSearchFlag::CHILDREN );
+
+ const sal_Int32 nFrameCount = seqFrames.getLength();
+ for( sal_Int32 nFrame=0; nFrame<nFrameCount; ++nFrame )
+ {
+ css::uno::Reference< XComponent > xComponent = impl_getFrameComponent( seqFrames[nFrame] );
+ if( xComponent.is() == sal_True )
+ {
+ nComponentCount++;
+ seqComponents.realloc( nComponentCount );
+ seqComponents[nComponentCount-1] = xComponent;
+ }
+ }
+ }
+ // ... otherwise break a recursive path and go back at current stack!
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+css::uno::Reference< XComponent > OComponentAccess::impl_getFrameComponent( const css::uno::Reference< XFrame >& xFrame ) const
+{
+ // Set default return value, if method failed.
+ css::uno::Reference< XComponent > xComponent = css::uno::Reference< XComponent >();
+ // Does no controller exists?
+ css::uno::Reference< XController > xController = xFrame->getController();
+ if ( xController.is() == sal_False )
+ {
+ // Controller not exist - use the VCL-component.
+ xComponent = css::uno::Reference< XComponent >( xFrame->getComponentWindow(), UNO_QUERY );
+ }
+ else
+ {
+ // Does no model exists?
+ css::uno::Reference< XModel > xModel( xController->getModel(), UNO_QUERY );
+ if ( xModel.is() == sal_True )
+ {
+ // Model exist - use the model as component.
+ xComponent = css::uno::Reference< XComponent >( xModel, UNO_QUERY );
+ }
+ else
+ {
+ // Model not exist - use the controller as component.
+ xComponent = css::uno::Reference< XComponent >( xController, UNO_QUERY );
+ }
+ }
+
+ return xComponent;
+}
+
+//_________________________________________________________________________________________________________________
+// debug methods
+//_________________________________________________________________________________________________________________
+
+/*-----------------------------------------------------------------------------------------------------------------
+ The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
+ we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT!
+
+ ATTENTION
+
+ If you miss a test for one of this parameters, contact the autor or add it himself !(?)
+ But ... look for right testing! See using of this methods!
+-----------------------------------------------------------------------------------------------------------------*/
+
+#ifdef ENABLE_ASSERTIONS
+
+//*****************************************************************************************************************
+sal_Bool OComponentAccess::impldbg_checkParameter_OComponentAccessCtor( const css::uno::Reference< XDesktop >& xOwner )
+{
+ // Set default return value.
+ sal_Bool bOK = sal_True;
+ // Check parameter.
+ if (
+ ( &xOwner == NULL ) ||
+ ( xOwner.is() == sal_False )
+ )
+ {
+ bOK = sal_False ;
+ }
+ // Return result of check.
+ return bOK ;
+}
+
+#endif // #ifdef ENABLE_ASSERTIONS
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/ocomponentenumeration.cxx b/framework/source/helper/ocomponentenumeration.cxx
new file mode 100644
index 000000000000..914981fbe980
--- /dev/null
+++ b/framework/source/helper/ocomponentenumeration.cxx
@@ -0,0 +1,238 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <helper/ocomponentenumeration.hxx>
+
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+using namespace ::com::sun::star::container ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::uno ;
+using namespace ::cppu ;
+using namespace ::osl ;
+using namespace ::rtl ;
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+OComponentEnumeration::OComponentEnumeration( const Sequence< css::uno::Reference< XComponent > >& seqComponents )
+ // Init baseclasses first
+ // Attention:
+ // Don't change order of initialization!
+ // ThreadHelpBase is a struct with a mutex as member. We can't use a mutex as member, while
+ // we must garant right initialization and a valid value of this! First initialize
+ // baseclasses and then members. And we need the mutex for other baseclasses !!!
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ // Init member
+ , m_nPosition ( 0 ) // 0 is the first position for a valid list and the right value for an invalid list to!
+ , m_seqComponents ( seqComponents )
+{
+ // Safe impossible states
+ // "Method" not defined for ALL parameters!
+ LOG_ASSERT( impldbg_checkParameter_OComponentEnumerationCtor( seqComponents ), "OComponentEnumeration::OComponentEnumeration()\nInvalid parameter detected!\n" )
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+OComponentEnumeration::~OComponentEnumeration()
+{
+ // Reset instance, free memory ....
+ impl_resetObject();
+}
+
+//*****************************************************************************************************************
+// XEventListener
+//*****************************************************************************************************************
+void SAL_CALL OComponentEnumeration::disposing( const EventObject&
+#if OSL_DEBUG_LEVEL > 0
+aEvent
+#endif
+) throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Safe impossible cases
+ // This method is not specified for all incoming parameters.
+ LOG_ASSERT( impldbg_checkParameter_disposing( aEvent ), "OComponentEnumeration::disposing()\nInvalid parameter detected!\n" )
+
+ // Reset instance to defaults, release references and free memory.
+ impl_resetObject();
+}
+
+//*****************************************************************************************************************
+// XEnumeration
+//*****************************************************************************************************************
+sal_Bool SAL_CALL OComponentEnumeration::hasMoreElements() throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // First position in a valid list is 0.
+ // => The last one is getLength() - 1!
+ // m_nPosition's current value is the position for the next element, which will be return, if user call "nextElement()"
+ // => We have more elements if current position less then the length of the list!
+ return ( m_nPosition < (sal_uInt32)(m_seqComponents.getLength()) );
+}
+
+//*****************************************************************************************************************
+// XEnumeration
+//*****************************************************************************************************************
+Any SAL_CALL OComponentEnumeration::nextElement() throw( NoSuchElementException ,
+ WrappedTargetException ,
+ RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // If we have no elements or end of enumeration is arrived ...
+ if ( hasMoreElements() == sal_False )
+ {
+ // .. throw an exception!
+ throw NoSuchElementException();
+ }
+
+ // Else; Get next element from list ...
+ Any aComponent;
+ aComponent <<= m_seqComponents[m_nPosition];
+ // ... and step to next element!
+ ++m_nPosition;
+
+ // Return listitem.
+ return aComponent;
+}
+
+//*****************************************************************************************************************
+// proteced method
+//*****************************************************************************************************************
+void OComponentEnumeration::impl_resetObject()
+{
+ // Attention:
+ // Write this for multiple calls - NOT AT THE SAME TIME - but for more then one call again)!
+ // It exist two ways to call this method. From destructor and from disposing().
+ // I can't say, which one is the first. Normaly the disposing-call - but other way ....
+
+ // Delete list of components.
+ m_seqComponents.realloc( 0 );
+ // Reset position in list.
+ // The list has no elements anymore. m_nPosition is normaly the current position in list for nextElement!
+ // But a position of 0 in a list of 0 items is an invalid state. This constellation can't work in future.
+ // End of enumeration is arrived!
+ // (see hasMoreElements() for more details...)
+ m_nPosition = 0 ;
+}
+
+//_________________________________________________________________________________________________________________
+// debug methods
+//_________________________________________________________________________________________________________________
+
+/*-----------------------------------------------------------------------------------------------------------------
+ The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
+ we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT!
+
+ ATTENTION
+
+ If you miss a test for one of this parameters, contact the autor or add it himself !(?)
+ But ... look for right testing! See using of this methods!
+-----------------------------------------------------------------------------------------------------------------*/
+
+#ifdef ENABLE_ASSERTIONS
+
+//*****************************************************************************************************************
+// An empty list is allowed ... hasMoreElements() will return false then!
+sal_Bool OComponentEnumeration::impldbg_checkParameter_OComponentEnumerationCtor( const Sequence< css::uno::Reference< XComponent > >& seqComponents )
+{
+ // Set default return value.
+ sal_Bool bOK = sal_True;
+ // Check parameter.
+ if (
+ ( &seqComponents == NULL )
+ )
+ {
+ bOK = sal_False ;
+ }
+ // Return result of check.
+ return bOK ;
+}
+
+//*****************************************************************************************************************
+sal_Bool OComponentEnumeration::impldbg_checkParameter_disposing( const EventObject& aEvent )
+{
+ // Set default return value.
+ sal_Bool bOK = sal_True;
+ // Check parameter.
+ if (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ )
+ {
+ bOK = sal_False ;
+ }
+ // Return result of check.
+ return bOK ;
+}
+
+#endif // #ifdef ENABLE_ASSERTIONS
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/oframes.cxx b/framework/source/helper/oframes.cxx
new file mode 100644
index 000000000000..119e050c409e
--- /dev/null
+++ b/framework/source/helper/oframes.cxx
@@ -0,0 +1,525 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <helper/oframes.hxx>
+
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+using namespace ::com::sun::star::container ;
+using namespace ::com::sun::star::frame ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::uno ;
+using namespace ::cppu ;
+using namespace ::osl ;
+using namespace ::std ;
+
+using rtl::OUString;
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+OFrames::OFrames( const css::uno::Reference< XMultiServiceFactory >& xFactory ,
+ const css::uno::Reference< XFrame >& xOwner ,
+ FrameContainer* pFrameContainer )
+ // Init baseclasses first
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ // Init member
+ , m_xFactory ( xFactory )
+ , m_xOwner ( xOwner )
+ , m_pFrameContainer ( pFrameContainer )
+ , m_bRecursiveSearchProtection( sal_False )
+{
+ // Safe impossible cases
+ // Method is not defined for ALL incoming parameters!
+ LOG_ASSERT( impldbg_checkParameter_OFramesCtor( xFactory, xOwner, pFrameContainer ), "OFrames::OFrames()\nInvalid parameter detected!\n" )
+}
+
+//*****************************************************************************************************************
+// (proteced!) destructor
+//*****************************************************************************************************************
+OFrames::~OFrames()
+{
+ // Reset instance, free memory ....
+ impl_resetObject();
+}
+
+//*****************************************************************************************************************
+// XFrames
+//*****************************************************************************************************************
+void SAL_CALL OFrames::append( const css::uno::Reference< XFrame >& xFrame ) throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Safe impossible cases
+ // Method is not defined for ALL incoming parameters!
+ LOG_ASSERT( impldbg_checkParameter_append( xFrame ), "OFrames::append()\nInvalid parameter detected!\n" )
+
+ // Do the follow only, if owner instance valid!
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFramesSupplier > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() == sal_True )
+ {
+ // Append frame to the end of the container ...
+ m_pFrameContainer->append( xFrame );
+ // Set owner of this instance as parent of the new frame in container!
+ xFrame->setCreator( xOwner );
+ }
+ // Else; Do nothing! Ouer owner is dead.
+ LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::append()\nOuer owner is dead - you can't append any frames ...!\n" )
+}
+
+//*****************************************************************************************************************
+// XFrames
+//*****************************************************************************************************************
+void SAL_CALL OFrames::remove( const css::uno::Reference< XFrame >& xFrame ) throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Safe impossible cases
+ // Method is not defined for ALL incoming parameters!
+ LOG_ASSERT( impldbg_checkParameter_remove( xFrame ), "OFrames::remove()\nInvalid parameter detected!\n" )
+
+ // Do the follow only, if owner instance valid!
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFramesSupplier > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() == sal_True )
+ {
+ // Search frame and remove it from container ...
+ m_pFrameContainer->remove( xFrame );
+ // Don't reset owner-property of removed frame!
+ // This must do the caller of this method himself.
+ // See documentation of interface XFrames for further informations.
+ }
+ // Else; Do nothing! Ouer owner is dead.
+ LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::remove()\nOuer owner is dead - you can't remove any frames ...!\n" )
+}
+
+//*****************************************************************************************************************
+// XFrames
+//*****************************************************************************************************************
+Sequence< css::uno::Reference< XFrame > > SAL_CALL OFrames::queryFrames( sal_Int32 nSearchFlags ) throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Safe impossible cases
+ // Method is not defined for ALL incoming parameters!
+ LOG_ASSERT( impldbg_checkParameter_queryFrames( nSearchFlags ), "OFrames::queryFrames()\nInvalid parameter detected!\n" )
+
+ // Set default return value. (empty sequence)
+ Sequence< css::uno::Reference< XFrame > > seqFrames;
+
+ // Do the follow only, if owner instance valid.
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() == sal_True )
+ {
+ // Work only, if search was not started here ...!
+ if( m_bRecursiveSearchProtection == sal_False )
+ {
+ // This class is a helper for services, which must implement XFrames.
+ // His parent and childs are MY parent and childs to.
+ // All searchflags are supported by this implementation!
+ // If some flags should not be supported - don't call me with this flags!!!
+
+ //_____________________________________________________________________________________________________________
+ // Search with AUTO-flag is not supported yet!
+ // We think about right implementation.
+ LOG_ASSERT( !(nSearchFlags & FrameSearchFlag::AUTO), "OFrames::queryFrames()\nSearch with AUTO-flag is not supported yet!\nWe think about right implementation.\n" )
+ // If searched for tasks ...
+ // Its not supported yet.
+ LOG_ASSERT( !(nSearchFlags & FrameSearchFlag::AUTO), "OFrames::queryFrames()\nSearch for tasks not supported yet!\n" )
+
+ //_____________________________________________________________________________________________________________
+ // Search for ALL and GLOBAL is superflous!
+ // We support all necessary flags, from which these two flags are derived.
+ // ALL = PARENT + SELF + CHILDREN + SIBLINGS
+ // GLOBAL = ALL + TASKS
+
+ //_____________________________________________________________________________________________________________
+ // Add parent to list ... if any exist!
+ if( nSearchFlags & FrameSearchFlag::PARENT )
+ {
+ css::uno::Reference< XFrame > xParent( xOwner->getCreator(), UNO_QUERY );
+ if( xParent.is() == sal_True )
+ {
+ Sequence< css::uno::Reference< XFrame > > seqParent( 1 );
+ seqParent[0] = xParent;
+ impl_appendSequence( seqFrames, seqParent );
+ }
+ }
+
+ //_____________________________________________________________________________________________________________
+ // Add owner to list if SELF is searched.
+ if( nSearchFlags & FrameSearchFlag::SELF )
+ {
+ Sequence< css::uno::Reference< XFrame > > seqSelf( 1 );
+ seqSelf[0] = xOwner;
+ impl_appendSequence( seqFrames, seqSelf );
+ }
+
+ //_____________________________________________________________________________________________________________
+ // Add SIBLINGS to list.
+ if( nSearchFlags & FrameSearchFlag::SIBLINGS )
+ {
+ // Else; start a new search.
+ // Protect this instance against recursive calls from parents.
+ m_bRecursiveSearchProtection = sal_True;
+ // Ask parent of my owner for frames and append results to return list.
+ css::uno::Reference< XFramesSupplier > xParent( xOwner->getCreator(), UNO_QUERY );
+ // If a parent exist ...
+ if ( xParent.is() == sal_True )
+ {
+ // ... ask him for right frames.
+ impl_appendSequence( seqFrames, xParent->getFrames()->queryFrames( nSearchFlags ) );
+ }
+ // We have all searched informations.
+ // Reset protection-mode.
+ m_bRecursiveSearchProtection = sal_False;
+ }
+
+ //_____________________________________________________________________________________________________________
+ // If searched for children, step over all elements in container and collect the informations.
+ if ( nSearchFlags & FrameSearchFlag::CHILDREN )
+ {
+ // Don't search for parents, siblings and self at childrens!
+ // These things are supported by this instance himself.
+ sal_Int32 nChildSearchFlags = FrameSearchFlag::SELF | FrameSearchFlag::CHILDREN;
+ // Step over all items of container and ask childrens for frames.
+ sal_uInt32 nCount = m_pFrameContainer->getCount();
+ for ( sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex )
+ {
+ // We don't must control this conversion.
+ // We have done this at append()!
+ css::uno::Reference< XFramesSupplier > xItem( (*m_pFrameContainer)[nIndex], UNO_QUERY );
+ impl_appendSequence( seqFrames, xItem->getFrames()->queryFrames( nChildSearchFlags ) );
+ }
+ }
+ }
+ }
+ // Else; Do nothing! Ouer owner is dead.
+ LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::queryFrames()\nOuer owner is dead - you can't query for frames ...!\n" )
+
+ // Resturn result of this operation.
+ return seqFrames;
+}
+
+//*****************************************************************************************************************
+// XIndexAccess
+//*****************************************************************************************************************
+sal_Int32 SAL_CALL OFrames::getCount() throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Set default return value.
+ sal_Int32 nCount = 0;
+
+ // Do the follow only, if owner instance valid.
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() == sal_True )
+ {
+ // Set CURRENT size of container for return.
+ nCount = m_pFrameContainer->getCount();
+ }
+
+ // Return result.
+ return nCount;
+}
+
+//*****************************************************************************************************************
+// XIndexAccess
+//*****************************************************************************************************************
+Any SAL_CALL OFrames::getByIndex( sal_Int32 nIndex ) throw( IndexOutOfBoundsException ,
+ WrappedTargetException ,
+ RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ sal_uInt32 nCount = m_pFrameContainer->getCount();
+ if ( nIndex < 0 || ( sal::static_int_cast< sal_uInt32 >( nIndex ) >= nCount ))
+ throw IndexOutOfBoundsException( OUString(RTL_CONSTASCII_USTRINGPARAM("OFrames::getByIndex - Index out of bounds")),
+ (OWeakObject *)this );
+
+ // Set default return value.
+ Any aReturnValue;
+
+ // Do the follow only, if owner instance valid.
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() == sal_True )
+ {
+ // Get element form container.
+ // (If index not valid, FrameContainer return NULL!)
+ aReturnValue <<= (*m_pFrameContainer)[nIndex];
+ }
+
+ // Return result of this operation.
+ return aReturnValue;
+}
+
+//*****************************************************************************************************************
+// XElementAccess
+//*****************************************************************************************************************
+Type SAL_CALL OFrames::getElementType() throw( RuntimeException )
+{
+ // This "container" support XFrame-interfaces only!
+ return ::getCppuType( (const css::uno::Reference< XFrame >*)NULL );
+}
+
+//*****************************************************************************************************************
+// XElementAccess
+//*****************************************************************************************************************
+sal_Bool SAL_CALL OFrames::hasElements() throw( RuntimeException )
+{
+ // Ready for multithreading
+ ResetableGuard aGuard( m_aLock );
+
+ // Set default return value.
+ sal_Bool bHasElements = sal_False;
+ // Do the follow only, if owner instance valid.
+ // Lock owner for follow operations - make a "hard reference"!
+ css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
+ if ( xOwner.is() == sal_True )
+ {
+ // If some elements exist ...
+ if ( m_pFrameContainer->getCount() > 0 )
+ {
+ // ... change this state value!
+ bHasElements = sal_True;
+ }
+ }
+ // Return result of this operation.
+ return bHasElements;
+}
+
+//*****************************************************************************************************************
+// proteced method
+//*****************************************************************************************************************
+void OFrames::impl_resetObject()
+{
+ // Attention:
+ // Write this for multiple calls - NOT AT THE SAME TIME - but for more then one call again)!
+ // It exist two ways to call this method. From destructor and from disposing().
+ // I can't say, which one is the first. Normaly the disposing-call - but other way ....
+
+ // This instance can't work if the weakreference to owner is invalid!
+ // Destroy this to reset this object.
+ m_xOwner = WeakReference< XFrame >();
+ // Reset pointer to shared container to!
+ m_pFrameContainer = NULL;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void OFrames::impl_appendSequence( Sequence< css::uno::Reference< XFrame > >& seqDestination ,
+ const Sequence< css::uno::Reference< XFrame > >& seqSource )
+{
+ // Get some informations about the sequences.
+ sal_Int32 nSourceCount = seqSource.getLength();
+ sal_Int32 nDestinationCount = seqDestination.getLength();
+ const css::uno::Reference< XFrame >* pSourceAccess = seqSource.getConstArray();
+ css::uno::Reference< XFrame >* pDestinationAccess = seqDestination.getArray();
+
+ // Get memory for result list.
+ Sequence< css::uno::Reference< XFrame > > seqResult ( nSourceCount + nDestinationCount );
+ css::uno::Reference< XFrame >* pResultAccess = seqResult.getArray();
+ sal_Int32 nResultPosition = 0;
+
+ // Copy all items from first sequence.
+ for ( sal_Int32 nSourcePosition=0; nSourcePosition<nSourceCount; ++nSourcePosition )
+ {
+ pResultAccess[nResultPosition] = pSourceAccess[nSourcePosition];
+ ++nResultPosition;
+ }
+
+ // Don't manipulate nResultPosition between these two loops!
+ // Its the current position in the result list.
+
+ // Copy all items from second sequence.
+ for ( sal_Int32 nDestinationPosition=0; nDestinationPosition<nDestinationCount; ++nDestinationPosition )
+ {
+ pResultAccess[nResultPosition] = pDestinationAccess[nDestinationPosition];
+ ++nResultPosition;
+ }
+
+ // Return result of this operation.
+ seqDestination.realloc( 0 );
+ seqDestination = seqResult;
+}
+
+//_________________________________________________________________________________________________________________
+// debug methods
+//_________________________________________________________________________________________________________________
+
+/*-----------------------------------------------------------------------------------------------------------------
+ The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
+ we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT!
+
+ ATTENTION
+
+ If you miss a test for one of this parameters, contact the autor or add it himself !(?)
+ But ... look for right testing! See using of this methods!
+-----------------------------------------------------------------------------------------------------------------*/
+
+#ifdef ENABLE_ASSERTIONS
+
+//*****************************************************************************************************************
+// An instance of this class can only work with valid initialization.
+// We share the mutex with ouer owner class, need a valid factory to instanciate new services and
+// use the access to ouer owner for some operations.
+sal_Bool OFrames::impldbg_checkParameter_OFramesCtor( const css::uno::Reference< XMultiServiceFactory >& xFactory ,
+ const css::uno::Reference< XFrame >& xOwner ,
+ FrameContainer* pFrameContainer )
+{
+ // Set default return value.
+ sal_Bool bOK = sal_True;
+ // Check parameter.
+ if (
+ ( &xFactory == NULL ) ||
+ ( &xOwner == NULL ) ||
+ ( xFactory.is() == sal_False ) ||
+ ( xOwner.is() == sal_False ) ||
+ ( pFrameContainer == NULL )
+ )
+ {
+ bOK = sal_False ;
+ }
+ // Return result of check.
+ return bOK ;
+}
+
+//*****************************************************************************************************************
+// Its only allowed to add valid references to container.
+// AND - alle frames must support XFrames-interface!
+sal_Bool OFrames::impldbg_checkParameter_append( const css::uno::Reference< XFrame >& xFrame )
+{
+ // Set default return value.
+ sal_Bool bOK = sal_True;
+ // Check parameter.
+ if (
+ ( &xFrame == NULL ) ||
+ ( xFrame.is() == sal_False )
+ )
+ {
+ bOK = sal_False ;
+ }
+ // Return result of check.
+ return bOK ;
+}
+
+//*****************************************************************************************************************
+// Its only allowed to add valid references to container...
+// ... => You can only delete valid references!
+sal_Bool OFrames::impldbg_checkParameter_remove( const css::uno::Reference< XFrame >& xFrame )
+{
+ // Set default return value.
+ sal_Bool bOK = sal_True;
+ // Check parameter.
+ if (
+ ( &xFrame == NULL ) ||
+ ( xFrame.is() == sal_False )
+ )
+ {
+ bOK = sal_False ;
+ }
+ // Return result of check.
+ return bOK ;
+}
+
+//*****************************************************************************************************************
+// A search for frames must initiate with right flags.
+// Some one are superflous and not supported yet. But here we control only the range of incoming parameter!
+sal_Bool OFrames::impldbg_checkParameter_queryFrames( sal_Int32 nSearchFlags )
+{
+ // Set default return value.
+ sal_Bool bOK = sal_True;
+ // Check parameter.
+ if (
+ ( nSearchFlags != FrameSearchFlag::AUTO ) &&
+ ( !( nSearchFlags & FrameSearchFlag::PARENT ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::SELF ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::CHILDREN ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::CREATE ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::SIBLINGS ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::TASKS ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::ALL ) ) &&
+ ( !( nSearchFlags & FrameSearchFlag::GLOBAL ) )
+ )
+ {
+ bOK = sal_False ;
+ }
+ // Return result of check.
+ return bOK ;
+}
+
+#endif // #ifdef ENABLE_ASSERTIONS
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/persistentwindowstate.cxx b/framework/source/helper/persistentwindowstate.cxx
new file mode 100644
index 000000000000..23765a6dd455
--- /dev/null
+++ b/framework/source/helper/persistentwindowstate.cxx
@@ -0,0 +1,347 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <pattern/window.hxx>
+#include <helper/persistentwindowstate.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <macros/generic.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XWindow.hpp>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <comphelper/configurationhelper.hxx>
+#include <vcl/window.hxx>
+#include <vcl/syswin.hxx>
+
+#include <toolkit/unohlp.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// definitions
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+
+DEFINE_XINTERFACE_4(PersistentWindowState ,
+ OWeakObject ,
+ DIRECT_INTERFACE (css::lang::XTypeProvider ),
+ DIRECT_INTERFACE (css::lang::XInitialization ),
+ DIRECT_INTERFACE (css::frame::XFrameActionListener ),
+ DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener))
+
+DEFINE_XTYPEPROVIDER_4(PersistentWindowState ,
+ css::lang::XTypeProvider ,
+ css::lang::XInitialization ,
+ css::frame::XFrameActionListener,
+ css::lang::XEventListener )
+
+//*****************************************************************************************************************
+PersistentWindowState::PersistentWindowState(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , m_xSMGR (xSMGR )
+ , m_bWindowStateAlreadySet(sal_False )
+{
+}
+
+//*****************************************************************************************************************
+PersistentWindowState::~PersistentWindowState()
+{
+}
+
+//*****************************************************************************************************************
+void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ // check arguments
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ if (lArguments.getLength() < 1)
+ throw css::lang::IllegalArgumentException(
+ DECLARE_ASCII("Empty argument list!"),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ lArguments[0] >>= xFrame;
+ if (!xFrame.is())
+ throw css::lang::IllegalArgumentException(
+ DECLARE_ASCII("No valid frame specified!"),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ // hold the frame as weak reference(!) so it can die everytimes :-)
+ m_xFrame = xFrame;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // start listening
+ xFrame->addFrameActionListener(this);
+}
+
+//*****************************************************************************************************************
+void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ;
+ css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
+ sal_Bool bRestoreWindowState = !m_bWindowStateAlreadySet;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // frame already gone ? We hold it weak only ...
+ if (!xFrame.is())
+ return;
+
+ // no window -> no position and size available
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
+ if (!xWindow.is())
+ return;
+
+ // unknown module -> no configuration available!
+ ::rtl::OUString sModuleName = PersistentWindowState::implst_identifyModule(xSMGR, xFrame);
+ if (!sModuleName.getLength())
+ return;
+
+ switch(aEvent.Action)
+ {
+ case css::frame::FrameAction_COMPONENT_ATTACHED :
+ {
+ if (bRestoreWindowState)
+ {
+ ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xSMGR, sModuleName);
+ PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState);
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_bWindowStateAlreadySet = sal_True;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+ }
+ }
+ break;
+
+ case css::frame::FrameAction_COMPONENT_REATTACHED :
+ {
+ // nothing todo here, because its not allowed to change position and size
+ // of an alredy existing frame!
+ }
+ break;
+
+ case css::frame::FrameAction_COMPONENT_DETACHING :
+ {
+ ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow);
+ PersistentWindowState::implst_setWindowStateOnConfig(xSMGR, sModuleName, sWindowState);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+//*****************************************************************************************************************
+void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject&)
+ throw(css::uno::RuntimeException)
+{
+ // nothing todo here - because we hold the frame as weak reference only
+}
+
+//*****************************************************************************************************************
+::rtl::OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ ::rtl::OUString sModuleName;
+
+ css::uno::Reference< css::frame::XModuleManager > xModuleManager(
+ xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
+ css::uno::UNO_QUERY_THROW);
+
+ try
+ {
+ sModuleName = xModuleManager->identify(xFrame);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { sModuleName = ::rtl::OUString(); }
+
+ return sModuleName;
+}
+
+//*****************************************************************************************************************
+::rtl::OUString PersistentWindowState::implst_getWindowStateFromConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const ::rtl::OUString& sModuleName)
+{
+ ::rtl::OUString sWindowState;
+
+ ::rtl::OUStringBuffer sRelPathBuf(256);
+ sRelPathBuf.appendAscii("Office/Factories/*[\"");
+ sRelPathBuf.append (sModuleName );
+ sRelPathBuf.appendAscii("\"]" );
+
+ ::rtl::OUString sPackage(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup/"));
+ ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
+ ::rtl::OUString sKey(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryWindowAttributes"));
+
+ try
+ {
+ ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
+ sPackage,
+ sRelPath,
+ sKey,
+ ::comphelper::ConfigurationHelper::E_READONLY) >>= sWindowState;
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { sWindowState = ::rtl::OUString(); }
+
+ return sWindowState;
+}
+
+//*****************************************************************************************************************
+void PersistentWindowState::implst_setWindowStateOnConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const ::rtl::OUString& sModuleName ,
+ const ::rtl::OUString& sWindowState)
+{
+ ::rtl::OUStringBuffer sRelPathBuf(256);
+ sRelPathBuf.appendAscii("Office/Factories/*[\"");
+ sRelPathBuf.append (sModuleName );
+ sRelPathBuf.appendAscii("\"]" );
+
+ ::rtl::OUString sPackage(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup/"));
+ ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear();
+ ::rtl::OUString sKey(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryWindowAttributes"));
+
+ try
+ {
+ ::comphelper::ConfigurationHelper::writeDirectKey(xSMGR,
+ sPackage,
+ sRelPath,
+ sKey,
+ css::uno::makeAny(sWindowState),
+ ::comphelper::ConfigurationHelper::E_STANDARD);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+//*****************************************************************************************************************
+::rtl::OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
+{
+ ::rtl::OUString sWindowState;
+
+ if (xWindow.is())
+ {
+ // SOLAR SAFE -> ------------------------
+ SolarMutexGuard aSolarGuard;
+
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ // check for system window is neccessary to guarantee correct pointer cast!
+ if (
+ (pWindow ) &&
+ (pWindow->IsSystemWindow())
+ )
+ {
+ sal_uLong nMask = WINDOWSTATE_MASK_ALL;
+ nMask &= ~(WINDOWSTATE_MASK_MINIMIZED);
+ sWindowState = B2U_ENC(
+ ((SystemWindow*)pWindow)->GetWindowState(nMask),
+ RTL_TEXTENCODING_UTF8);
+ }
+ // <- SOLAR SAFE ------------------------
+ }
+
+ return sWindowState;
+}
+
+
+//*********************************************************************************************************
+void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow ,
+ const ::rtl::OUString& sWindowState)
+{
+ if (
+ (!xWindow.is() ) ||
+ ( sWindowState.getLength() < 1)
+ )
+ return;
+
+ // SOLAR SAFE -> ------------------------
+ SolarMutexGuard aSolarGuard;
+
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ if (!pWindow)
+ return;
+
+ // check for system and work window - its neccessary to guarantee correct pointer cast!
+ sal_Bool bSystemWindow = pWindow->IsSystemWindow();
+ sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW);
+
+ if (!bSystemWindow && !bWorkWindow)
+ return;
+
+ SystemWindow* pSystemWindow = (SystemWindow*)pWindow;
+ WorkWindow* pWorkWindow = (WorkWindow* )pWindow;
+
+ // dont save this special state!
+ if (pWorkWindow->IsMinimized())
+ return;
+
+ pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8));
+ // <- SOLAR SAFE ------------------------
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/statusindicator.cxx b/framework/source/helper/statusindicator.cxx
new file mode 100644
index 000000000000..a73d63fa14e0
--- /dev/null
+++ b/framework/source/helper/statusindicator.cxx
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// include files of own module
+#include <helper/statusindicator.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//_______________________________________________
+// declarations
+
+//***********************************************
+// XInterface
+DEFINE_XINTERFACE_2(StatusIndicator ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::task::XStatusIndicator))
+
+//***********************************************
+// XInterface
+DEFINE_XTYPEPROVIDER_2(StatusIndicator ,
+ css::lang::XTypeProvider ,
+ css::task::XStatusIndicator)
+
+//***********************************************
+StatusIndicator::StatusIndicator(StatusIndicatorFactory* pFactory)
+ : ThreadHelpBase ( )
+ , ::cppu::OWeakObject( )
+ , m_xFactory (pFactory)
+{
+}
+
+//***********************************************
+StatusIndicator::~StatusIndicator()
+{
+}
+
+//***********************************************
+void SAL_CALL StatusIndicator::start(const ::rtl::OUString& sText ,
+ sal_Int32 nRange)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory.get(), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE
+ if (xFactory.is())
+ {
+ StatusIndicatorFactory* pFactory = (StatusIndicatorFactory*)xFactory.get();
+ pFactory->start(this, sText, nRange);
+ }
+}
+
+//***********************************************
+void SAL_CALL StatusIndicator::end()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory.get(), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE
+ if (xFactory.is())
+ {
+ StatusIndicatorFactory* pFactory = (StatusIndicatorFactory*)xFactory.get();
+ pFactory->end(this);
+ }
+}
+
+//***********************************************
+void SAL_CALL StatusIndicator::reset()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory.get(), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE
+ if (xFactory.is())
+ {
+ StatusIndicatorFactory* pFactory = (StatusIndicatorFactory*)xFactory.get();
+ pFactory->reset(this);
+ }
+}
+
+//***********************************************
+void SAL_CALL StatusIndicator::setText(const ::rtl::OUString& sText)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory.get(), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE
+ if (xFactory.is())
+ {
+ StatusIndicatorFactory* pFactory = (StatusIndicatorFactory*)xFactory.get();
+ pFactory->setText(this, sText);
+ }
+}
+
+//***********************************************
+void SAL_CALL StatusIndicator::setValue(sal_Int32 nValue)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory.get(), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE
+ if (xFactory.is())
+ {
+ StatusIndicatorFactory* pFactory = (StatusIndicatorFactory*)xFactory.get();
+ pFactory->setValue(this, nValue);
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/statusindicatorfactory.cxx b/framework/source/helper/statusindicatorfactory.cxx
new file mode 100644
index 000000000000..ccb990e0228f
--- /dev/null
+++ b/framework/source/helper/statusindicatorfactory.cxx
@@ -0,0 +1,647 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//-----------------------------------------------
+// my own includes
+
+#include <algorithm>
+#include <helper/statusindicatorfactory.hxx>
+#include <helper/statusindicator.hxx>
+#include <helper/vclstatusindicator.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <services.h>
+#include <properties.h>
+
+//-----------------------------------------------
+// interface includes
+#include <com/sun/star/awt/Rectangle.hpp>
+
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/XLayoutConstrains.hpp>
+#include <com/sun/star/awt/DeviceInfo.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+
+#include <toolkit/unohlp.hxx>
+
+//-----------------------------------------------
+// includes of other projects
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/configurationhelper.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+
+//-----------------------------------------------
+// namespace
+
+namespace framework{
+
+//-----------------------------------------------
+// definitions
+
+sal_Int32 StatusIndicatorFactory::m_nInReschedule = 0; /// static counter for rescheduling
+static ::rtl::OUString PROGRESS_RESOURCE(RTL_CONSTASCII_USTRINGPARAM("private:resource/progressbar/progressbar"));
+
+//-----------------------------------------------
+DEFINE_XINTERFACE_5(StatusIndicatorFactory ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::lang::XInitialization ),
+ DIRECT_INTERFACE(css::task::XStatusIndicatorFactory),
+ DIRECT_INTERFACE(css::util::XUpdatable ))
+
+DEFINE_XTYPEPROVIDER_5(StatusIndicatorFactory ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::lang::XInitialization ,
+ css::task::XStatusIndicatorFactory,
+ css::util::XUpdatable )
+
+DEFINE_XSERVICEINFO_MULTISERVICE(StatusIndicatorFactory ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_STATUSINDICATORFACTORY ,
+ IMPLEMENTATIONNAME_STATUSINDICATORFACTORY)
+
+DEFINE_INIT_SERVICE(StatusIndicatorFactory,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+ )
+
+//-----------------------------------------------
+StatusIndicatorFactory::StatusIndicatorFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase ( )
+ , ::cppu::OWeakObject ( )
+ , m_xSMGR (xSMGR )
+ , m_pWakeUp (0 )
+ , m_bAllowReschedule (sal_False)
+ , m_bAllowParentShow (sal_False)
+ , m_bDisableReschedule(sal_False)
+{
+}
+
+//-----------------------------------------------
+StatusIndicatorFactory::~StatusIndicatorFactory()
+{
+ impl_stopWakeUpThread();
+}
+
+//-----------------------------------------------
+void SAL_CALL StatusIndicatorFactory::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ ::comphelper::SequenceAsHashMap lArgs(lArguments);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ m_xFrame = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_FRAME , css::uno::Reference< css::frame::XFrame >());
+ m_xPluggWindow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_WINDOW , css::uno::Reference< css::awt::XWindow >() );
+ m_bAllowParentShow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_ALLOWPARENTSHOW , (sal_Bool)sal_False );
+ m_bDisableReschedule = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_DISABLERESCHEDULE, (sal_Bool)sal_False );
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ impl_createProgress();
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::task::XStatusIndicator > SAL_CALL StatusIndicatorFactory::createStatusIndicator()
+ throw(css::uno::RuntimeException)
+{
+ StatusIndicator* pIndicator = new StatusIndicator(this);
+ css::uno::Reference< css::task::XStatusIndicator > xIndicator(static_cast< ::cppu::OWeakObject* >(pIndicator), css::uno::UNO_QUERY_THROW);
+
+ return xIndicator;
+}
+
+//-----------------------------------------------
+void SAL_CALL StatusIndicatorFactory::update()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_bAllowReschedule = sal_True;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::start(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
+ const ::rtl::OUString& sText ,
+ sal_Int32 nRange)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // create new info structure for this child or move it to the front of our stack
+ IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
+ if (pItem != m_aStack.end())
+ m_aStack.erase(pItem);
+ IndicatorInfo aInfo(xChild, sText, nRange);
+ m_aStack.push_back (aInfo );
+
+ m_xActiveChild = xChild;
+ css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ implts_makeParentVisibleIfAllowed();
+
+ if (xProgress.is())
+ xProgress->start(sText, nRange);
+
+ impl_startWakeUpThread();
+ impl_reschedule(sal_True);
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::reset(const css::uno::Reference< css::task::XStatusIndicator >& xChild)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ // reset the internal info structure related to this child
+ IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
+ if (pItem != m_aStack.end())
+ {
+ pItem->m_nValue = 0;
+ pItem->m_sText = ::rtl::OUString();
+ }
+
+ css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
+ css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // not the top most child => dont change UI
+ // But dont forget Reschedule!
+ if (
+ (xChild == xActive) &&
+ (xProgress.is() )
+ )
+ xProgress->reset();
+
+ impl_reschedule(sal_True);
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::end(const css::uno::Reference< css::task::XStatusIndicator >& xChild)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // remove this child from our stack
+ IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
+ if (pItem != m_aStack.end())
+ m_aStack.erase(pItem);
+
+ // activate next child ... or finish the progress if there is no further one.
+ m_xActiveChild.clear();
+ ::rtl::OUString sText;
+ sal_Int32 nValue = 0;
+ IndicatorStack::reverse_iterator pNext = m_aStack.rbegin();
+ if (pNext != m_aStack.rend())
+ {
+ m_xActiveChild = pNext->m_xIndicator;
+ sText = pNext->m_sText;
+ nValue = pNext->m_nValue;
+ }
+
+ css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
+ css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (xActive.is())
+ {
+ // There is at least one further child indicator.
+ // Actualize our progress, so it shows these values from now.
+ if (xProgress.is())
+ {
+ xProgress->setText (sText );
+ xProgress->setValue(nValue);
+ }
+ }
+ else
+ {
+ // Our stack is empty. No further child exists.
+ // Se we must "end" our progress realy
+ if (xProgress.is())
+ xProgress->end();
+ // Now hide the progress bar again.
+ impl_hideProgress();
+
+ impl_stopWakeUpThread();
+ }
+
+ impl_reschedule(sal_True);
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::setText(const css::uno::Reference< css::task::XStatusIndicator >& xChild,
+ const ::rtl::OUString& sText )
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
+ if (pItem != m_aStack.end())
+ pItem->m_sText = sText;
+
+ css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
+ css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
+
+ aWriteLock.unlock();
+ // SAFE -> ----------------------------------
+
+ // paint only the top most indicator
+ // but dont forget to Reschedule!
+ if (
+ (xChild == xActive) &&
+ (xProgress.is() )
+ )
+ {
+ xProgress->setText(sText);
+ }
+
+ impl_reschedule(sal_True);
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::setValue( const css::uno::Reference< css::task::XStatusIndicator >& xChild ,
+ sal_Int32 nValue )
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ sal_Int32 nOldValue = 0;
+ IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild);
+ if (pItem != m_aStack.end())
+ {
+ nOldValue = pItem->m_nValue;
+ pItem->m_nValue = nValue;
+ }
+
+ css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild;
+ css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress;
+
+ aWriteLock.unlock();
+ // SAFE -> ----------------------------------
+
+ if (
+ (xChild == xActive) &&
+ (nOldValue != nValue ) &&
+ (xProgress.is() )
+ )
+ {
+ xProgress->setValue(nValue);
+ }
+
+ impl_reschedule(sal_False);
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::implts_makeParentVisibleIfAllowed()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ if (!m_bAllowParentShow)
+ return;
+
+ css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
+ css::uno::Reference< css::awt::XWindow > xPluggWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY);
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::awt::XWindow > xParentWindow;
+ if (xFrame.is())
+ xParentWindow = xFrame->getContainerWindow();
+ else
+ xParentWindow = xPluggWindow;
+
+ // dont disturb user in case he put the loading document into the background!
+ // Supress any setVisible() or toFront() call in case the initial show was
+ // already made.
+ css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xParentWindow, css::uno::UNO_QUERY);
+ sal_Bool bIsVisible = sal_False;
+ if (xVisibleCheck.is())
+ bIsVisible = xVisibleCheck->isVisible();
+
+ if (bIsVisible)
+ {
+ impl_showProgress();
+ return;
+ }
+
+ // Check if the layout manager has been set to invisible state. It this case we are also
+ // not allowed to set the frame visible!
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ if ( !xLayoutManager->isVisible() )
+ return;
+ }
+ }
+
+ // Ok the window should be made visible ... becuase it isnt currently visible.
+ // BUT ..!
+ // We need a Hack for our applications: They get her progress from the frame directly
+ // on saving documents. Because there is no progress set on the MediaDescriptor.
+ // But that's wrong. In case the document was opened hidden, they shouldnt use any progress .-(
+ // They only possible workaround: dont show the parent window here, if the document was opened hidden.
+ sal_Bool bHiddenDoc = sal_False;
+ if (xFrame.is())
+ {
+ css::uno::Reference< css::frame::XController > xController;
+ css::uno::Reference< css::frame::XModel > xModel ;
+ xController = xFrame->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+ if (xModel.is())
+ {
+ ::comphelper::MediaDescriptor lDocArgs(xModel->getArgs());
+ bHiddenDoc = lDocArgs.getUnpackedValueOrDefault(
+ ::comphelper::MediaDescriptor::PROP_HIDDEN(),
+ (sal_Bool)sal_False);
+ }
+ }
+
+ if (bHiddenDoc)
+ return;
+
+ // OK: The document was not opened in hidden mode ...
+ // and the window isnt already visible.
+ // Show it and bring it to front.
+ // But before we have to be sure, that our internal used helper progress
+ // is visible too.
+ impl_showProgress();
+
+ SolarMutexGuard aSolarGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow(xParentWindow);
+ if ( pWindow )
+ {
+ bool bForceFrontAndFocus(false);
+ ::comphelper::ConfigurationHelper::readDirectKey(
+ xSMGR,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/View")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NewDocumentHandling")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ForceFocusAndToFront")),
+ ::comphelper::ConfigurationHelper::E_READONLY) >>= bForceFrontAndFocus;
+
+ pWindow->Show(sal_True, bForceFrontAndFocus ? SHOW_FOREGROUNDTASK : 0 );
+ }
+
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::impl_createProgress()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
+ css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+
+ aReadLock.lock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+
+ if (xWindow.is())
+ {
+ // use vcl based progress implementation in plugged mode
+ VCLStatusIndicator* pVCLProgress = new VCLStatusIndicator(xSMGR, xWindow);
+ xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pVCLProgress), css::uno::UNO_QUERY);
+ }
+ else
+ if (xFrame.is())
+ {
+ // use frame layouted progress implementation
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ xLayoutManager->lock();
+ xLayoutManager->createElement( PROGRESS_RESOURCE );
+ xLayoutManager->hideElement( PROGRESS_RESOURCE );
+
+ css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESS_RESOURCE);
+ if (xProgressBar.is())
+ xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY);
+ xLayoutManager->unlock();
+ }
+ }
+ }
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xProgress = xProgress;
+ aWriteLock.lock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::impl_showProgress()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
+ css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+
+ aReadLock.lock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+
+ if (xFrame.is())
+ {
+ // use frame layouted progress implementation
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ // Be sure that we have always a progress. It can be that our frame
+ // was recycled and therefore the progress was destroyed!
+ // CreateElement does nothing if there is already a valid progress.
+ xLayoutManager->createElement( PROGRESS_RESOURCE );
+ xLayoutManager->showElement( PROGRESS_RESOURCE );
+
+ css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESS_RESOURCE);
+ if (xProgressBar.is())
+ xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY);
+ }
+ }
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xProgress = xProgress;
+ aWriteLock.lock();
+ // <- SAFE ----------------------------------
+ }
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::impl_hideProgress()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY);
+ css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+
+ aReadLock.lock();
+ // <- SAFE ----------------------------------
+
+ if (xFrame.is())
+ {
+ // use frame layouted progress implementation
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ xLayoutManager->hideElement( PROGRESS_RESOURCE );
+ }
+ }
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::impl_reschedule(sal_Bool bForce)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ if (m_bDisableReschedule)
+ return;
+ aReadLock.unlock();
+ // <- SAFE
+
+ sal_Bool bReschedule = bForce;
+ if (!bReschedule)
+ {
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ bReschedule = m_bAllowReschedule;
+ m_bAllowReschedule = sal_False;
+ aWriteLock.unlock();
+ // <- SAFE
+ }
+
+ if (!bReschedule)
+ return;
+
+ // SAFE ->
+ WriteGuard aGlobalLock(LockHelper::getGlobalLock());
+
+ if (m_nInReschedule == 0)
+ {
+ ++m_nInReschedule;
+ aGlobalLock.unlock();
+ // <- SAFE
+
+ Application::Reschedule(true);
+
+ // SAFE ->
+ aGlobalLock.lock();
+ --m_nInReschedule;
+ }
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::impl_startWakeUpThread()
+{
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_bDisableReschedule)
+ return;
+
+ if (!m_pWakeUp)
+ {
+ m_pWakeUp = new WakeUpThread(this);
+ m_pWakeUp->create();
+ }
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+//-----------------------------------------------
+void StatusIndicatorFactory::impl_stopWakeUpThread()
+{
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ if (m_pWakeUp)
+ {
+ // Thread kill itself after terminate()!
+ m_pWakeUp->terminate();
+ m_pWakeUp = 0;
+ }
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/tagwindowasmodified.cxx b/framework/source/helper/tagwindowasmodified.cxx
new file mode 100644
index 000000000000..a98fb72c2ef6
--- /dev/null
+++ b/framework/source/helper/tagwindowasmodified.cxx
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <helper/tagwindowasmodified.hxx>
+#include <pattern/window.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <macros/generic.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XWindow.hpp>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/frame/FrameAction.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <toolkit/unohlp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/syswin.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <tools/wintypes.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// definitions
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+
+DEFINE_XINTERFACE_4(TagWindowAsModified ,
+ OWeakObject ,
+ DIRECT_INTERFACE (css::lang::XTypeProvider ),
+ DIRECT_INTERFACE (css::lang::XInitialization ),
+ DIRECT_INTERFACE (css::util::XModifyListener ),
+ DERIVED_INTERFACE(css::lang::XEventListener, css::util::XModifyListener))
+
+DEFINE_XTYPEPROVIDER_4(TagWindowAsModified ,
+ css::lang::XTypeProvider ,
+ css::lang::XInitialization ,
+ css::util::XModifyListener ,
+ css::lang::XEventListener )
+
+//*****************************************************************************************************************
+TagWindowAsModified::TagWindowAsModified(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , m_xSMGR (xSMGR )
+{
+}
+
+//*****************************************************************************************************************
+TagWindowAsModified::~TagWindowAsModified()
+{
+}
+
+//*****************************************************************************************************************
+void SAL_CALL TagWindowAsModified::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ css::uno::Reference< css::frame::XFrame > xFrame;
+
+ if (lArguments.getLength() > 0)
+ lArguments[0] >>= xFrame;
+
+ if ( ! xFrame.is ())
+ return;
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xFrame = xFrame ;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ xFrame->addFrameActionListener(this);
+ impl_update (xFrame);
+}
+
+//*****************************************************************************************************************
+void SAL_CALL TagWindowAsModified::modified(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ css::uno::Reference< css::util::XModifiable > xModel (m_xModel.get (), css::uno::UNO_QUERY);
+ css::uno::Reference< css::awt::XWindow > xWindow(m_xWindow.get(), css::uno::UNO_QUERY);
+ if (
+ ( ! xModel.is () ) ||
+ ( ! xWindow.is () ) ||
+ (aEvent.Source != xModel)
+ )
+ return;
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ ::sal_Bool bModified = xModel->isModified ();
+
+ // SYNCHRONIZED ->
+ SolarMutexGuard aSolarGuard;
+
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ if ( ! pWindow)
+ return;
+
+ sal_Bool bSystemWindow = pWindow->IsSystemWindow();
+ sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW);
+ if (!bSystemWindow && !bWorkWindow)
+ return;
+
+ if (bModified)
+ pWindow->SetExtendedStyle(WB_EXT_DOCMODIFIED);
+ else
+ pWindow->SetExtendedStyle( ! WB_EXT_DOCMODIFIED);
+ // <- SYNCHRONIZED
+}
+
+//*****************************************************************************************************************
+void SAL_CALL TagWindowAsModified::frameAction(const css::frame::FrameActionEvent& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ if (
+ (aEvent.Action != css::frame::FrameAction_COMPONENT_REATTACHED) &&
+ (aEvent.Action != css::frame::FrameAction_COMPONENT_ATTACHED )
+ )
+ return;
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
+ if (
+ ( ! xFrame.is () ) ||
+ (aEvent.Source != xFrame)
+ )
+ return;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ impl_update (xFrame);
+}
+
+//*****************************************************************************************************************
+void SAL_CALL TagWindowAsModified::disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
+ if (
+ (xFrame.is () ) &&
+ (aEvent.Source == xFrame)
+ )
+ {
+ m_xFrame = css::uno::Reference< css::frame::XFrame >();
+ return;
+ }
+
+ css::uno::Reference< css::frame::XModel > xModel(m_xModel.get(), css::uno::UNO_QUERY);
+ if (
+ (xModel.is () ) &&
+ (aEvent.Source == xModel)
+ )
+ {
+ m_xModel = css::uno::Reference< css::frame::XModel >();
+ return;
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//*****************************************************************************************************************
+void TagWindowAsModified::impl_update (const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ if ( ! xFrame.is ())
+ return;
+
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow ();
+ css::uno::Reference< css::frame::XController > xController = xFrame->getController ();
+ css::uno::Reference< css::frame::XModel > xModel ;
+ if (xController.is ())
+ xModel = xController->getModel ();
+
+ if (
+ ( ! xWindow.is ()) ||
+ ( ! xModel.is ())
+ )
+ return;
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ // Note: frame was set as member outside ! we have to refresh connections
+ // regarding window and model only here.
+ m_xWindow = xWindow;
+ m_xModel = xModel ;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::util::XModifyBroadcaster > xModifiable(xModel, css::uno::UNO_QUERY);
+ if (xModifiable.is ())
+ xModifiable->addModifyListener (this);
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/titlebarupdate.cxx b/framework/source/helper/titlebarupdate.cxx
new file mode 100644
index 000000000000..832c56b0d1e1
--- /dev/null
+++ b/framework/source/helper/titlebarupdate.cxx
@@ -0,0 +1,423 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <helper/titlebarupdate.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <pattern/window.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <macros/generic.hxx>
+#include <services.h>
+#include <properties.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/frame/XTitleChangeBroadcaster.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <comphelper/sequenceashashmap.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/bootstrap.hxx>
+#include <vcl/window.hxx>
+#include <vcl/syswin.hxx>
+#include <toolkit/unohlp.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// const
+
+static const ::sal_Int32 INVALID_ICON_ID = -1;
+static const ::sal_Int32 DEFAULT_ICON_ID = 0;
+
+//_________________________________________________________________________________________________________________
+// definitions
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+
+DEFINE_XINTERFACE_5(TitleBarUpdate ,
+ OWeakObject ,
+ DIRECT_INTERFACE (css::lang::XTypeProvider ),
+ DIRECT_INTERFACE (css::lang::XInitialization ),
+ DIRECT_INTERFACE (css::frame::XFrameActionListener ),
+ DIRECT_INTERFACE (css::frame::XTitleChangeListener ),
+ DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener))
+
+DEFINE_XTYPEPROVIDER_5(TitleBarUpdate ,
+ css::lang::XTypeProvider ,
+ css::lang::XInitialization ,
+ css::frame::XFrameActionListener,
+ css::frame::XTitleChangeListener,
+ css::lang::XEventListener )
+
+//*****************************************************************************************************************
+TitleBarUpdate::TitleBarUpdate(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , m_xSMGR (xSMGR )
+ , m_xFrame ( )
+{
+}
+
+//*****************************************************************************************************************
+TitleBarUpdate::~TitleBarUpdate()
+{
+}
+
+//*****************************************************************************************************************
+void SAL_CALL TitleBarUpdate::initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ // check arguments
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ if (lArguments.getLength() < 1)
+ throw css::lang::IllegalArgumentException(
+ DECLARE_ASCII("Empty argument list!"),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ lArguments[0] >>= xFrame;
+ if (!xFrame.is())
+ throw css::lang::IllegalArgumentException(
+ DECLARE_ASCII("No valid frame specified!"),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+
+ // SYNCHRONIZED ->
+ WriteGuard aWriteLock(m_aLock);
+ // hold the frame as weak reference(!) so it can die everytimes :-)
+ m_xFrame = xFrame;
+ aWriteLock.unlock();
+ // <- SYNCHRONIZED
+
+ // start listening
+ xFrame->addFrameActionListener(this);
+
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(xFrame, css::uno::UNO_QUERY);
+ if (xBroadcaster.is ())
+ xBroadcaster->addTitleChangeListener (this);
+}
+
+//*****************************************************************************************************************
+void SAL_CALL TitleBarUpdate::frameAction(const css::frame::FrameActionEvent& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // we are interested on events only, which must trigger a title bar update
+ // because component was changed.
+ if (
+ (aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ) ||
+ (aEvent.Action == css::frame::FrameAction_COMPONENT_REATTACHED) ||
+ (aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING )
+ )
+ {
+ impl_forceUpdate ();
+ }
+}
+
+//*****************************************************************************************************************
+void SAL_CALL TitleBarUpdate::titleChanged(const css::frame::TitleChangedEvent& /* aEvent */)
+ throw (css::uno::RuntimeException)
+{
+ impl_forceUpdate ();
+}
+
+//*****************************************************************************************************************
+void SAL_CALL TitleBarUpdate::disposing(const css::lang::EventObject&)
+ throw(css::uno::RuntimeException)
+{
+ // nothing todo here - because we hold the frame as weak reference only
+}
+
+//http://live.gnome.org/GnomeShell/ApplicationBased
+//See http://msdn.microsoft.com/en-us/library/dd378459(v=VS.85).aspx for future
+//Windows 7 equivalent support
+void TitleBarUpdate::impl_updateApplicationID(const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow ();
+ if ( ! xWindow.is() )
+ return;
+
+ ::rtl::OUString sApplicationID;
+ try
+ {
+ ::rtl::OUString aProductName;
+ ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::PRODUCTNAME) >>= aProductName;
+
+ // SYNCHRONIZED ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SYNCHRONIZED
+
+ css::uno::Reference< css::frame::XModuleManager > xModuleManager(
+ xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
+ css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::container::XNameAccess > xConfig(
+ xModuleManager,
+ css::uno::UNO_QUERY_THROW);
+
+ rtl::OUString aModuleId = xModuleManager->identify(xFrame);
+ rtl::OUString sDesktopName;
+
+ if ( aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.text.TextDocument")) ||
+ aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.text.GlobalDocument")) ||
+ aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.text.WebDocument")) ||
+ aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.xforms.XMLFormDocument")) )
+ sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("writer"));
+ else if ( aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.sheet.SpreadsheetDocument")) )
+ sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("calc"));
+ else if ( aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.presentation.PresentationDocument")) )
+ sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("impress"));
+ else if ( aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.DrawingDocument")) )
+ sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("draw"));
+ else if ( aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.formula.FormulaProperties")) )
+ sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("math"));
+ else if ( aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.sdb.DatabaseDocument")) ||
+ aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.sdb.OfficeDatabaseDocument")) ||
+ aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.sdb.RelationDesign")) ||
+ aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.sdb.QueryDesign")) ||
+ aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.sdb.TableDesign")) ||
+ aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.sdb.DataSourceBrowser")) )
+ sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("base"));
+ else if ( aModuleId.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("com.sun.star.frame.StartModule")) )
+ sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("startcenter"));
+ else
+ sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("startcenter"));
+ sApplicationID = aProductName.toAsciiLowerCase();
+ sApplicationID += ::rtl::OUString(sal_Unicode('-'));
+ sApplicationID += sDesktopName;
+ }
+ catch(const css::uno::Exception&)
+ {
+ }
+
+ // VCL SYNCHRONIZED ->
+ SolarMutexGuard aSolarGuard;
+
+ Window* pWindow = (VCLUnoHelper::GetWindow( xWindow ));
+ if (
+ ( pWindow ) &&
+ ( pWindow->GetType() == WINDOW_WORKWINDOW )
+ )
+ {
+ WorkWindow* pWorkWindow = (WorkWindow*)pWindow;
+ pWorkWindow->SetApplicationID( sApplicationID );
+ }
+ // <- VCL SYNCHRONIZED
+}
+
+
+//*****************************************************************************************************************
+::sal_Bool TitleBarUpdate::implst_getModuleInfo(const css::uno::Reference< css::frame::XFrame >& xFrame,
+ TModuleInfo& rInfo )
+{
+ if ( ! xFrame.is ())
+ return sal_False;
+
+ // SYNCHRONIZED ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SYNCHRONIZED
+
+ try
+ {
+ css::uno::Reference< css::frame::XModuleManager > xModuleManager(
+ xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
+ css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::container::XNameAccess > xConfig(
+ xModuleManager,
+ css::uno::UNO_QUERY_THROW);
+
+ rInfo.sID = xModuleManager->identify(xFrame);
+ ::comphelper::SequenceAsHashMap lProps = xConfig->getByName (rInfo.sID);
+
+ rInfo.sUIName = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_UINAME, ::rtl::OUString());
+ rInfo.nIcon = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_ICON , INVALID_ICON_ID );
+
+ // Note: If we could retrieve a module id ... everything is OK.
+ // UIName and Icon ID are optional values !
+ ::sal_Bool bSuccess = (rInfo.sID.getLength () > 0);
+ return bSuccess;
+ }
+ catch(const css::uno::Exception&)
+ {}
+
+ return sal_False;
+}
+
+//*****************************************************************************************************************
+void TitleBarUpdate::impl_forceUpdate()
+{
+ // SYNCHRONIZED ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ;
+ css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SYNCHRONIZED
+
+ // frame already gone ? We hold it weak only ...
+ if ( ! xFrame.is())
+ return;
+
+ // no window -> no chance to set/update title and icon
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow();
+ if ( ! xWindow.is())
+ return;
+
+ impl_updateIcon (xFrame);
+ impl_updateTitle (xFrame);
+#if defined(UNX) && !defined(MACOSX)
+ impl_updateApplicationID (xFrame);
+#endif
+}
+
+//*****************************************************************************************************************
+void TitleBarUpdate::impl_updateIcon(const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ css::uno::Reference< css::frame::XController > xController = xFrame->getController ();
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow ();
+
+ if (
+ ( ! xController.is() ) ||
+ ( ! xWindow.is() )
+ )
+ return;
+
+ // a) set default value to an invalid one. So we can start further searches for right icon id, if
+ // first steps failed!
+ sal_Int32 nIcon = INVALID_ICON_ID;
+
+ // b) try to find information on controller property set directly
+ // Don't forget to catch possible exceptions - because these property is an optional one!
+ css::uno::Reference< css::beans::XPropertySet > xSet( xController, css::uno::UNO_QUERY );
+ if ( xSet.is() )
+ {
+ try
+ {
+ xSet->getPropertyValue( DECLARE_ASCII("IconId") ) >>= nIcon;
+ }
+ catch(const css::uno::Exception&)
+ {}
+ }
+
+ // c) if b) failed ... identify the used module and retrieve set icon from module config.
+ // Tirck :-) Module was already specified outside and aInfo contains all needed informations.
+ if ( nIcon == INVALID_ICON_ID )
+ {
+ TModuleInfo aInfo;
+ if (implst_getModuleInfo(xFrame, aInfo))
+ nIcon = aInfo.nIcon;
+ }
+
+ // d) if all steps failed - use fallback :-)
+ // ... means using the global staroffice icon
+ if( nIcon == INVALID_ICON_ID )
+ nIcon = DEFAULT_ICON_ID;
+
+ // e) set icon on container window now
+ // Don't forget SolarMutex! We use vcl directly :-(
+ // Check window pointer for right WorkWindow class too!!!
+
+ // VCL SYNCHRONIZED ->
+ SolarMutexGuard aSolarGuard;
+
+ Window* pWindow = (VCLUnoHelper::GetWindow( xWindow ));
+ if (
+ ( pWindow ) &&
+ ( pWindow->GetType() == WINDOW_WORKWINDOW )
+ )
+ {
+ WorkWindow* pWorkWindow = (WorkWindow*)pWindow;
+ pWorkWindow->SetIcon( (sal_uInt16)nIcon );
+
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
+ rtl::OUString aURL;
+ if( xModel.is() )
+ aURL = xModel->getURL();
+ pWorkWindow->SetRepresentedURL( aURL );
+ }
+ // <- VCL SYNCHRONIZED
+}
+
+//*****************************************************************************************************************
+void TitleBarUpdate::impl_updateTitle(const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ // no window ... no chance to set any title -> return
+ css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow ();
+ if ( ! xWindow.is() )
+ return;
+
+ css::uno::Reference< css::frame::XTitle > xTitle(xFrame, css::uno::UNO_QUERY);
+ if ( ! xTitle.is() )
+ return;
+
+ const ::rtl::OUString sTitle = xTitle->getTitle ();
+
+ // VCL SYNCHRONIZED ->
+ SolarMutexGuard aSolarGuard;
+
+ Window* pWindow = (VCLUnoHelper::GetWindow( xWindow ));
+ if (
+ ( pWindow ) &&
+ ( pWindow->GetType() == WINDOW_WORKWINDOW )
+ )
+ {
+ WorkWindow* pWorkWindow = (WorkWindow*)pWindow;
+ pWorkWindow->SetText( sTitle );
+ }
+ // <- VCL SYNCHRONIZED
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/uiconfigelementwrapperbase.cxx b/framework/source/helper/uiconfigelementwrapperbase.cxx
new file mode 100644
index 000000000000..4e416511c7a3
--- /dev/null
+++ b/framework/source/helper/uiconfigelementwrapperbase.cxx
@@ -0,0 +1,569 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <helper/uiconfigelementwrapperbase.hxx>
+#include <general.h>
+#include <properties.h>
+#include <threadhelp/resetableguard.hxx>
+#include <uielement/constitemcontainer.hxx>
+#include <uielement/rootitemcontainer.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/ui/XUIConfiguration.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <rtl/logfile.hxx>
+
+const int UIELEMENT_PROPHANDLE_CONFIGSOURCE = 1;
+const int UIELEMENT_PROPHANDLE_FRAME = 2;
+const int UIELEMENT_PROPHANDLE_PERSISTENT = 3;
+const int UIELEMENT_PROPHANDLE_RESOURCEURL = 4;
+const int UIELEMENT_PROPHANDLE_TYPE = 5;
+const int UIELEMENT_PROPHANDLE_XMENUBAR = 6;
+const int UIELEMENT_PROPHANDLE_CONFIGLISTENER = 7;
+const int UIELEMENT_PROPHANDLE_NOCLOSE = 8;
+const int UIELEMENT_PROPCOUNT = 8;
+const rtl::OUString UIELEMENT_PROPNAME_CONFIGLISTENER( RTL_CONSTASCII_USTRINGPARAM( "ConfigListener" ));
+const rtl::OUString UIELEMENT_PROPNAME_CONFIGSOURCE( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
+const rtl::OUString UIELEMENT_PROPNAME_FRAME( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+const rtl::OUString UIELEMENT_PROPNAME_PERSISTENT( RTL_CONSTASCII_USTRINGPARAM( "Persistent" ));
+const rtl::OUString UIELEMENT_PROPNAME_RESOURCEURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ));
+const rtl::OUString UIELEMENT_PROPNAME_TYPE( RTL_CONSTASCII_USTRINGPARAM( "Type" ));
+const rtl::OUString UIELEMENT_PROPNAME_XMENUBAR( RTL_CONSTASCII_USTRINGPARAM( "XMenuBar" ));
+const rtl::OUString UIELEMENT_PROPNAME_NOCLOSE( RTL_CONSTASCII_USTRINGPARAM( "NoClose" ));
+using ::rtl::OUString;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_10 ( UIConfigElementWrapperBase ,
+ OWeakObject ,
+ DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIElement ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIElementSettings ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::lang::XInitialization ),
+ DIRECT_INTERFACE( ::com::sun::star::lang::XComponent ),
+ DIRECT_INTERFACE( ::com::sun::star::util::XUpdatable ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationListener )
+ )
+
+DEFINE_XTYPEPROVIDER_10 ( UIConfigElementWrapperBase ,
+ ::com::sun::star::lang::XTypeProvider ,
+ ::com::sun::star::ui::XUIElement ,
+ ::com::sun::star::ui::XUIElementSettings ,
+ ::com::sun::star::beans::XMultiPropertySet ,
+ ::com::sun::star::beans::XFastPropertySet ,
+ ::com::sun::star::beans::XPropertySet ,
+ ::com::sun::star::lang::XInitialization ,
+ ::com::sun::star::lang::XComponent ,
+ ::com::sun::star::util::XUpdatable ,
+ ::com::sun::star::ui::XUIConfigurationListener
+ )
+
+UIConfigElementWrapperBase::UIConfigElementWrapperBase( sal_Int16 nType,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
+ , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
+ , ::cppu::OWeakObject ( )
+ , m_nType ( nType )
+ , m_bPersistent ( sal_True )
+ , m_bInitialized ( sal_False )
+ , m_bConfigListener ( sal_False )
+ , m_bConfigListening ( sal_False )
+ , m_bDisposed ( sal_False )
+ , m_bNoClose ( sal_False )
+ , m_xServiceFactory ( _xServiceFactory )
+ , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
+{
+}
+
+UIConfigElementWrapperBase::~UIConfigElementWrapperBase()
+{
+}
+
+// XComponent
+void SAL_CALL UIConfigElementWrapperBase::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ // must be implemented by derived class
+ ResetableGuard aLock( m_aLock );
+ m_bDisposed = sal_True;
+}
+
+void SAL_CALL UIConfigElementWrapperBase::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL UIConfigElementWrapperBase::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), aListener );
+}
+
+// XEventListener
+void SAL_CALL UIConfigElementWrapperBase::disposing( const EventObject& )
+throw( RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+ m_xConfigSource.clear();
+}
+
+void SAL_CALL UIConfigElementWrapperBase::initialize( const Sequence< Any >& aArguments )
+throw ( Exception, RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bInitialized )
+ {
+ for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
+ {
+ PropertyValue aPropValue;
+ if ( aArguments[n] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_CONFIGSOURCE ))
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_CONFIGSOURCE, aPropValue.Value );
+ else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_FRAME ))
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_FRAME, aPropValue.Value );
+ else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_PERSISTENT ))
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_PERSISTENT, aPropValue.Value );
+ else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_RESOURCEURL ))
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_RESOURCEURL, aPropValue.Value );
+ else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_TYPE ))
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_TYPE, aPropValue.Value );
+ else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_CONFIGLISTENER ))
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_CONFIGLISTENER, aPropValue.Value );
+ else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_NOCLOSE ))
+ setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_NOCLOSE, aPropValue.Value );
+ }
+ }
+
+ m_bInitialized = sal_True;
+ }
+}
+
+// XUpdatable
+void SAL_CALL UIConfigElementWrapperBase::update() throw (::com::sun::star::uno::RuntimeException)
+{
+ // can be implemented by derived class
+}
+
+void SAL_CALL UIConfigElementWrapperBase::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ // can be implemented by derived class
+}
+
+void SAL_CALL UIConfigElementWrapperBase::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ // can be implemented by derived class
+}
+
+void SAL_CALL UIConfigElementWrapperBase::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ // can be implemented by derived class
+}
+
+// XPropertySet helper
+sal_Bool SAL_CALL UIConfigElementWrapperBase::convertFastPropertyValue( Any& aConvertedValue ,
+ Any& aOldValue ,
+ sal_Int32 nHandle ,
+ const Any& aValue ) throw( com::sun::star::lang::IllegalArgumentException )
+{
+ // Initialize state with sal_False !!!
+ // (Handle can be invalid)
+ sal_Bool bReturn = sal_False;
+
+ switch( nHandle )
+ {
+ case UIELEMENT_PROPHANDLE_CONFIGLISTENER:
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny(m_bConfigListener),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_CONFIGSOURCE:
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny(m_xConfigSource),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_FRAME:
+ {
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny(xFrame),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ }
+ break;
+
+ case UIELEMENT_PROPHANDLE_PERSISTENT:
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny(m_bPersistent),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_RESOURCEURL:
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny(m_aResourceURL),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_TYPE :
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny(m_nType),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_XMENUBAR :
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny(m_xMenuBar),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case UIELEMENT_PROPHANDLE_NOCLOSE:
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny(m_bNoClose),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+ }
+
+ // Return state of operation.
+ return bReturn ;
+}
+
+void SAL_CALL UIConfigElementWrapperBase::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle ,
+ const com::sun::star::uno::Any& aValue ) throw( com::sun::star::uno::Exception )
+{
+ switch( nHandle )
+ {
+ case UIELEMENT_PROPHANDLE_CONFIGLISTENER:
+ {
+ bool bBool( m_bConfigListener );
+ aValue >>= bBool;
+ if ( m_bConfigListener != bBool )
+ {
+ if ( m_bConfigListening )
+ {
+ if ( m_xConfigSource.is() && !bBool )
+ {
+ try
+ {
+ Reference< XUIConfiguration > xUIConfig( m_xConfigSource, UNO_QUERY );
+ if ( xUIConfig.is() )
+ {
+ xUIConfig->removeConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ m_bConfigListening = sal_False;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+ else
+ {
+ if ( m_xConfigSource.is() && bBool )
+ {
+ try
+ {
+ Reference< XUIConfiguration > xUIConfig( m_xConfigSource, UNO_QUERY );
+ if ( xUIConfig.is() )
+ {
+ xUIConfig->addConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ m_bConfigListening = sal_True;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+
+ m_bConfigListener = bBool;
+ }
+ }
+ break;
+ case UIELEMENT_PROPHANDLE_CONFIGSOURCE:
+ aValue >>= m_xConfigSource;
+ break;
+ case UIELEMENT_PROPHANDLE_FRAME:
+ {
+ Reference< XFrame > xFrame;
+
+ aValue >>= xFrame;
+ m_xWeakFrame = xFrame;
+ break;
+ }
+ case UIELEMENT_PROPHANDLE_PERSISTENT:
+ {
+ sal_Bool bBool( m_bPersistent );
+ aValue >>= bBool;
+ m_bPersistent = bBool;
+ break;
+ }
+ case UIELEMENT_PROPHANDLE_RESOURCEURL:
+ aValue >>= m_aResourceURL;
+ break;
+ case UIELEMENT_PROPHANDLE_TYPE:
+ aValue >>= m_nType;
+ break;
+ case UIELEMENT_PROPHANDLE_XMENUBAR:
+ aValue >>= m_xMenuBar;
+ break;
+ case UIELEMENT_PROPHANDLE_NOCLOSE:
+ {
+ sal_Bool bBool( m_bNoClose );
+ aValue >>= bBool;
+ m_bNoClose = bBool;
+ break;
+ }
+ }
+}
+
+void SAL_CALL UIConfigElementWrapperBase::getFastPropertyValue( com::sun::star::uno::Any& aValue ,
+ sal_Int32 nHandle ) const
+{
+ switch( nHandle )
+ {
+ case UIELEMENT_PROPHANDLE_CONFIGLISTENER:
+ aValue <<= m_bConfigListener;
+ break;
+ case UIELEMENT_PROPHANDLE_CONFIGSOURCE:
+ aValue <<= m_xConfigSource;
+ break;
+ case UIELEMENT_PROPHANDLE_FRAME:
+ {
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ aValue <<= xFrame;
+ break;
+ }
+ case UIELEMENT_PROPHANDLE_PERSISTENT:
+ aValue <<= m_bPersistent;
+ break;
+ case UIELEMENT_PROPHANDLE_RESOURCEURL:
+ aValue <<= m_aResourceURL;
+ break;
+ case UIELEMENT_PROPHANDLE_TYPE:
+ aValue <<= m_nType;
+ break;
+ case UIELEMENT_PROPHANDLE_XMENUBAR:
+ aValue <<= m_xMenuBar;
+ break;
+ case UIELEMENT_PROPHANDLE_NOCLOSE:
+ aValue <<= m_bNoClose;
+ break;
+ }
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL UIConfigElementWrapperBase::getInfoHelper()
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
+ static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ // Ready for multithreading
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfoHelper == NULL )
+ {
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
+ // "sal_True" say: Table is sorted by name.
+ static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return(*pInfoHelper);
+}
+
+com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL UIConfigElementWrapperBase::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException)
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
+ static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL;
+
+ if( pInfo == NULL )
+ {
+ // Ready for multithreading
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfo == NULL )
+ {
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+const com::sun::star::uno::Sequence< com::sun::star::beans::Property > UIConfigElementWrapperBase::impl_getStaticPropertyDescriptor()
+{
+ // Create a new static property array to initialize sequence!
+ // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
+ // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
+ // It's necessary for methods of OPropertySetHelper.
+ // ATTENTION:
+ // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
+
+ static const com::sun::star::beans::Property pProperties[] =
+ {
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_CONFIGLISTENER, UIELEMENT_PROPHANDLE_CONFIGLISTENER , ::getCppuType((const sal_Bool*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT ),
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_CONFIGSOURCE , UIELEMENT_PROPHANDLE_CONFIGSOURCE , ::getCppuType((const Reference< ::com::sun::star::ui::XUIConfigurationManager >*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT ),
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_FRAME , UIELEMENT_PROPHANDLE_FRAME , ::getCppuType((const Reference< com::sun::star::frame::XFrame >*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ),
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_NOCLOSE , UIELEMENT_PROPHANDLE_NOCLOSE , ::getCppuType((const sal_Bool*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT ),
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_PERSISTENT , UIELEMENT_PROPHANDLE_PERSISTENT , ::getCppuType((const sal_Bool*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT ),
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_RESOURCEURL , UIELEMENT_PROPHANDLE_RESOURCEURL , ::getCppuType((const ::rtl::OUString*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ),
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_TYPE , UIELEMENT_PROPHANDLE_TYPE , ::getCppuType((const ::rtl::OUString*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ),
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_XMENUBAR , UIELEMENT_PROPHANDLE_XMENUBAR , ::getCppuType((const Reference< com::sun::star::awt::XMenuBar >*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY )
+ };
+ // Use it to initialize sequence!
+ static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, UIELEMENT_PROPCOUNT );
+ // Return static "PropertyDescriptor"
+ return lPropertyDescriptor;
+}
+void SAL_CALL UIConfigElementWrapperBase::setSettings( const Reference< XIndexAccess >& xSettings ) throw ( RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+
+ if ( xSettings.is() )
+ {
+ // Create a copy of the data if the container is not const
+ Reference< XIndexReplace > xReplace( xSettings, UNO_QUERY );
+ if ( xReplace.is() )
+ m_xConfigData = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xSettings ) ), UNO_QUERY );
+ else
+ m_xConfigData = xSettings;
+
+ if ( m_xConfigSource.is() && m_bPersistent )
+ {
+ ::rtl::OUString aResourceURL( m_aResourceURL );
+ Reference< XUIConfigurationManager > xUICfgMgr( m_xConfigSource );
+
+ aLock.unlock();
+
+ try
+ {
+ xUICfgMgr->replaceSettings( aResourceURL, m_xConfigData );
+ }
+ catch( NoSuchElementException& )
+ {
+ }
+ }
+ else if ( !m_bPersistent )
+ {
+ // Transient menubar => Fill menubar with new data
+ impl_fillNewData();
+ }
+ }
+}
+void UIConfigElementWrapperBase::impl_fillNewData()
+{
+}
+Reference< XIndexAccess > SAL_CALL UIConfigElementWrapperBase::getSettings( sal_Bool bWriteable ) throw ( RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+
+ if ( bWriteable )
+ return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( m_xConfigData ) ), UNO_QUERY );
+
+ return m_xConfigData;
+}
+
+Reference< XFrame > SAL_CALL UIConfigElementWrapperBase::getFrame() throw (RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ return xFrame;
+}
+
+::rtl::OUString SAL_CALL UIConfigElementWrapperBase::getResourceURL() throw (RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+ return m_aResourceURL;
+}
+
+::sal_Int16 SAL_CALL UIConfigElementWrapperBase::getType() throw (RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+ return m_nType;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/uielementwrapperbase.cxx b/framework/source/helper/uielementwrapperbase.cxx
new file mode 100644
index 000000000000..bf2c2f7583fa
--- /dev/null
+++ b/framework/source/helper/uielementwrapperbase.cxx
@@ -0,0 +1,285 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <helper/uielementwrapperbase.hxx>
+#include <general.h>
+#include <properties.h>
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <rtl/logfile.hxx>
+
+const int UIELEMENT_PROPHANDLE_RESOURCEURL = 1;
+const int UIELEMENT_PROPHANDLE_TYPE = 2;
+const int UIELEMENT_PROPHANDLE_FRAME = 3;
+const int UIELEMENT_PROPCOUNT = 3;
+const rtl::OUString UIELEMENT_PROPNAME_RESOURCEURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ));
+const rtl::OUString UIELEMENT_PROPNAME_TYPE( RTL_CONSTASCII_USTRINGPARAM( "Type" ));
+const rtl::OUString UIELEMENT_PROPNAME_FRAME( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using ::rtl::OUString;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_8 ( UIElementWrapperBase ,
+ OWeakObject ,
+ DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIElement ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::lang::XInitialization ),
+ DIRECT_INTERFACE( ::com::sun::star::util::XUpdatable ),
+ DIRECT_INTERFACE( ::com::sun::star::lang::XComponent )
+ )
+
+DEFINE_XTYPEPROVIDER_8 ( UIElementWrapperBase ,
+ ::com::sun::star::lang::XTypeProvider ,
+ ::com::sun::star::ui::XUIElement ,
+ ::com::sun::star::beans::XMultiPropertySet ,
+ ::com::sun::star::beans::XFastPropertySet ,
+ ::com::sun::star::beans::XPropertySet ,
+ ::com::sun::star::lang::XInitialization ,
+ ::com::sun::star::util::XUpdatable ,
+ ::com::sun::star::lang::XComponent
+ )
+
+UIElementWrapperBase::UIElementWrapperBase( sal_Int16 nType )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
+ , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
+ , ::cppu::OWeakObject ( )
+ , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
+ , m_nType ( nType )
+ , m_bInitialized ( sal_False )
+ , m_bDisposed ( sal_False )
+{
+}
+
+UIElementWrapperBase::~UIElementWrapperBase()
+{
+}
+
+void SAL_CALL UIElementWrapperBase::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ // must be implemented by derived class
+ ResetableGuard aLock( m_aLock );
+ m_bDisposed = sal_True;
+}
+
+void SAL_CALL UIElementWrapperBase::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL UIElementWrapperBase::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL UIElementWrapperBase::initialize( const Sequence< Any >& aArguments )
+throw ( Exception, RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bInitialized )
+ {
+ for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
+ {
+ PropertyValue aPropValue;
+ if ( aArguments[n] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ResourceURL" ) ))
+ aPropValue.Value >>= m_aResourceURL;
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Frame" ) ))
+ {
+ Reference< XFrame > xFrame;
+ aPropValue.Value >>= xFrame;
+ m_xWeakFrame = xFrame;
+ }
+ }
+ }
+
+ m_bInitialized = sal_True;
+ }
+}
+
+// XUIElement
+::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SAL_CALL UIElementWrapperBase::getFrame() throw (::com::sun::star::uno::RuntimeException)
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame( m_xWeakFrame );
+ return xFrame;
+}
+
+::rtl::OUString SAL_CALL UIElementWrapperBase::getResourceURL() throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_aResourceURL;
+}
+
+::sal_Int16 SAL_CALL UIElementWrapperBase::getType() throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_nType;
+}
+
+// XUpdatable
+void SAL_CALL UIElementWrapperBase::update() throw (::com::sun::star::uno::RuntimeException)
+{
+ // can be implemented by derived class
+}
+
+// XPropertySet helper
+sal_Bool SAL_CALL UIElementWrapperBase::convertFastPropertyValue( Any& /*aConvertedValue*/ ,
+ Any& /*aOldValue*/ ,
+ sal_Int32 /*nHandle*/ ,
+ const Any& /*aValue*/ ) throw( com::sun::star::lang::IllegalArgumentException )
+{
+ // Initialize state with sal_False !!!
+ // (Handle can be invalid)
+ return sal_False ;
+}
+
+void SAL_CALL UIElementWrapperBase::setFastPropertyValue_NoBroadcast( sal_Int32 /*nHandle*/ ,
+ const com::sun::star::uno::Any& /*aValue*/ ) throw( com::sun::star::uno::Exception )
+{
+}
+
+void SAL_CALL UIElementWrapperBase::getFastPropertyValue( com::sun::star::uno::Any& aValue ,
+ sal_Int32 nHandle ) const
+{
+ switch( nHandle )
+ {
+ case UIELEMENT_PROPHANDLE_RESOURCEURL:
+ aValue <<= m_aResourceURL;
+ break;
+ case UIELEMENT_PROPHANDLE_TYPE:
+ aValue <<= m_nType;
+ break;
+ case UIELEMENT_PROPHANDLE_FRAME:
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ aValue <<= xFrame;
+ break;
+ }
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL UIElementWrapperBase::getInfoHelper()
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
+ static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ // Ready for multithreading
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfoHelper == NULL )
+ {
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
+ // "sal_True" say: Table is sorted by name.
+ static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return(*pInfoHelper);
+}
+
+com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL UIElementWrapperBase::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException)
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
+ static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL;
+
+ if( pInfo == NULL )
+ {
+ // Ready for multithreading
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfo == NULL )
+ {
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+const com::sun::star::uno::Sequence< com::sun::star::beans::Property > UIElementWrapperBase::impl_getStaticPropertyDescriptor()
+{
+ // Create a new static property array to initialize sequence!
+ // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
+ // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
+ // It's necessary for methods of OPropertySetHelper.
+ // ATTENTION:
+ // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
+
+ static const com::sun::star::beans::Property pProperties[] =
+ {
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_FRAME , UIELEMENT_PROPHANDLE_FRAME , ::getCppuType((Reference< XFrame >*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ),
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_RESOURCEURL , UIELEMENT_PROPHANDLE_RESOURCEURL , ::getCppuType((sal_Int16*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ),
+ com::sun::star::beans::Property( UIELEMENT_PROPNAME_TYPE , UIELEMENT_PROPHANDLE_TYPE , ::getCppuType((const ::rtl::OUString*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY )
+ };
+ // Use it to initialize sequence!
+ static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, UIELEMENT_PROPCOUNT );
+ // Return static "PropertyDescriptor"
+ return lPropertyDescriptor;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/vclstatusindicator.cxx b/framework/source/helper/vclstatusindicator.cxx
new file mode 100644
index 000000000000..66f61a8a77e8
--- /dev/null
+++ b/framework/source/helper/vclstatusindicator.cxx
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <helper/vclstatusindicator.hxx>
+
+//-----------------------------------------------
+// includes of own modules
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+//-----------------------------------------------
+// includes of interfaces
+
+//-----------------------------------------------
+// includes of external modules
+
+#include <toolkit/unohlp.hxx>
+#include <vcl/svapp.hxx>
+
+//-----------------------------------------------
+// namespace
+
+namespace framework {
+
+//-----------------------------------------------
+// definitions
+
+//-----------------------------------------------
+DEFINE_XINTERFACE_1(VCLStatusIndicator ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::task::XStatusIndicator))
+
+//-----------------------------------------------
+VCLStatusIndicator::VCLStatusIndicator(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::awt::XWindow >& xParentWindow)
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , ::cppu::OWeakObject( )
+ , m_xSMGR (xSMGR )
+ , m_xParentWindow (xParentWindow )
+ , m_pStatusBar (0 )
+ , m_nRange (0 )
+ , m_nValue (0 )
+{
+ if (!m_xParentWindow.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cant work without a parent window!")),
+ static_cast< css::task::XStatusIndicator* >(this));
+}
+
+//-----------------------------------------------
+VCLStatusIndicator::~VCLStatusIndicator()
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL VCLStatusIndicator::start(const ::rtl::OUString& sText ,
+ sal_Int32 nRange)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::awt::XWindow > xParentWindow = m_xParentWindow;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // SOLAR SAFE -> ----------------------------
+ {
+ SolarMutexGuard aSolarGuard;
+
+ Window* pParentWindow = VCLUnoHelper::GetWindow(xParentWindow);
+ if (!m_pStatusBar)
+ m_pStatusBar = new StatusBar(pParentWindow, WB_3DLOOK|WB_BORDER);
+
+ VCLStatusIndicator::impl_recalcLayout(m_pStatusBar, pParentWindow);
+
+ m_pStatusBar->Show();
+ m_pStatusBar->StartProgressMode(sText);
+ m_pStatusBar->SetProgressValue(0);
+
+ // force repaint!
+ pParentWindow->Show();
+ pParentWindow->Invalidate(INVALIDATE_CHILDREN);
+ pParentWindow->Flush();
+ }
+ // <- SOLAR SAFE ----------------------------
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_sText = sText;
+ m_nRange = nRange;
+ m_nValue = 0;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL VCLStatusIndicator::reset()
+ throw(css::uno::RuntimeException)
+{
+ // SOLAR SAFE -> ----------------------------
+ SolarMutexGuard aSolarGuard;
+ if (m_pStatusBar)
+ {
+ m_pStatusBar->SetProgressValue(0);
+ m_pStatusBar->SetText(String());
+ }
+ // <- SOLAR SAFE ----------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL VCLStatusIndicator::end()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_sText = ::rtl::OUString();
+ m_nRange = 0;
+ m_nValue = 0;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // SOLAR SAFE -> ----------------------------
+ {
+ SolarMutexGuard aSolarGuard;
+ if (m_pStatusBar)
+ {
+ m_pStatusBar->EndProgressMode();
+ m_pStatusBar->Show(sal_False);
+
+ delete m_pStatusBar;
+ m_pStatusBar = 0;
+ }
+ }
+ // <- SOLAR SAFE ----------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL VCLStatusIndicator::setText(const ::rtl::OUString& sText)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_sText = sText;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // SOLAR SAFE -> ----------------------------
+ {
+ SolarMutexGuard aSolarGuard;
+ if (m_pStatusBar)
+ m_pStatusBar->SetText(sText);
+ }
+ // <- SOLAR SAFE ----------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL VCLStatusIndicator::setValue(sal_Int32 nValue)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (nValue <= m_nRange)
+ m_nValue = nValue;
+ else
+ m_nValue = m_nRange;
+
+ sal_Int32 nRange = m_nRange;
+ nValue = m_nValue;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // normalize value to fit the range of 0-100 %
+ sal_uInt16 nPercent = sal::static_int_cast< sal_uInt16 >(
+ ::std::min(
+ ((nValue*100) / ::std::max(nRange,(sal_Int32)1)), (sal_Int32)100));
+
+ // SOLAR SAFE -> ----------------------------
+ {
+ SolarMutexGuard aSolarGuard;
+ if (m_pStatusBar)
+ m_pStatusBar->SetProgressValue(nPercent);
+ }
+ // <- SOLAR SAFE ----------------------------
+}
+
+//-----------------------------------------------
+void VCLStatusIndicator::impl_recalcLayout(Window* pStatusBar ,
+ Window* pParentWindow)
+{
+ if (
+ (!pStatusBar ) ||
+ (!pParentWindow)
+ )
+ return;
+
+ Size aParentSize = pParentWindow->GetSizePixel();
+ pStatusBar->SetPosSizePixel(0,
+ 0,
+ aParentSize.Width(),
+ aParentSize.Height());
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/helper/wakeupthread.cxx b/framework/source/helper/wakeupthread.cxx
new file mode 100644
index 000000000000..11828da7aee1
--- /dev/null
+++ b/framework/source/helper/wakeupthread.cxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// include files of own module
+#include <helper/wakeupthread.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//_______________________________________________
+// declarations
+
+//***********************************************
+WakeUpThread::WakeUpThread(const css::uno::Reference< css::util::XUpdatable >& xListener)
+ : ThreadHelpBase( )
+ , m_xListener (xListener)
+{
+}
+
+//***********************************************
+void SAL_CALL WakeUpThread::run()
+{
+ ::osl::Condition aSleeper;
+
+ TimeValue aTime;
+ aTime.Seconds = 0;
+ aTime.Nanosec = 25000000; // 25 msec
+
+ while(schedule())
+ {
+ aSleeper.reset();
+ aSleeper.wait(&aTime);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::util::XUpdatable > xListener(m_xListener.get(), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE
+
+ if (xListener.is())
+ xListener->update();
+ }
+}
+
+//***********************************************
+void SAL_CALL WakeUpThread::onTerminated()
+{
+ delete this;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/acceleratorcache.hxx b/framework/source/inc/accelerators/acceleratorcache.hxx
new file mode 100644
index 000000000000..dc19da763d6c
--- /dev/null
+++ b/framework/source/inc/accelerators/acceleratorcache.hxx
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_ACCELERATORS_ACCELERATORCACHE_HXX_
+#define __FRAMEWORK_ACCELERATORS_ACCELERATORCACHE_HXX_
+
+//__________________________________________
+// own includes
+
+#include <threadhelp/threadhelpbase.hxx>
+#include <general.h>
+#include <stdtypes.h>
+
+//__________________________________________
+// interface includes
+
+#include <com/sun/star/awt/KeyEvent.hpp>
+
+//__________________________________________
+// other includes
+#include <comphelper/sequenceasvector.hxx>
+
+//__________________________________________
+// definition
+
+namespace framework
+{
+
+//__________________________________________
+/**
+ @short implements a cache for any accelerator configuration.
+
+ @descr Its implemented threadsafe, supports copy-on-write pattern
+ and a flush mechansim to support concurrent access to the same
+ configuration.
+
+ copy-on-write ... How? Do the following:
+ */
+class AcceleratorCache : public ThreadHelpBase // attention! Must be the first base class to guarentee right initialize lock ...
+{
+ //______________________________________
+ // const, types
+
+ public:
+
+ //---------------------------------------
+ /** TODO document me
+ commands -> keys
+ */
+ typedef ::comphelper::SequenceAsVector< css::awt::KeyEvent > TKeyList;
+ typedef BaseHash< TKeyList > TCommand2Keys;
+
+ //---------------------------------------
+ /** TODO document me
+ keys -> commands
+ */
+ typedef ::boost::unordered_map< css::awt::KeyEvent ,
+ ::rtl::OUString ,
+ KeyEventHashCode ,
+ KeyEventEqualsFunc > TKey2Commands;
+
+ //______________________________________
+ // member
+
+ private:
+
+ //---------------------------------------
+ /** map commands to keys in relation 1:n.
+ First key is interpreted as preferred one! */
+ TCommand2Keys m_lCommand2Keys;
+
+ //---------------------------------------
+ /** map keys to commands in relation 1:1. */
+ TKey2Commands m_lKey2Commands;
+
+ //______________________________________
+ // interface
+
+ public:
+
+ //---------------------------------------
+ /** @short creates a new - but empty - cache instance. */
+ AcceleratorCache();
+
+ //---------------------------------------
+ /** @short make a copy of this cache.
+ @descr Used for the copy-on-write feature.
+ */
+ AcceleratorCache(const AcceleratorCache& rCopy);
+
+ //---------------------------------------
+ /** @short does nothing real. */
+ virtual ~AcceleratorCache();
+
+ //---------------------------------------
+ /** @short write changes back to the original container.
+
+ @param rCopy
+ the (changed!) copy, which should be written
+ back to this original container.
+ */
+ virtual void takeOver(const AcceleratorCache& rCopy);
+
+ //---------------------------------------
+ /** TODO document me */
+ AcceleratorCache& operator=(const AcceleratorCache& rCopy);
+
+ //---------------------------------------
+ /** @short checks if the specified key exists.
+
+ @param aKey
+ the key, which should be checked.
+
+ @return [bool]
+ sal_True if the speicfied key exists inside this container.
+ */
+ virtual sal_Bool hasKey(const css::awt::KeyEvent& aKey) const;
+ virtual sal_Bool hasCommand(const ::rtl::OUString& sCommand) const;
+
+ //---------------------------------------
+ /** TODO document me */
+ virtual TKeyList getAllKeys() const;
+
+ //---------------------------------------
+ /** @short add a new or change an existing key-command pair
+ of this container.
+
+ @param aKey
+ describe the key.
+
+ @param sCommand
+ describe the command.
+ */
+ virtual void setKeyCommandPair(const css::awt::KeyEvent& aKey ,
+ const ::rtl::OUString& sCommand);
+
+ //---------------------------------------
+ /** @short returns the list of keys, which are registered
+ for this command.
+
+ @param sCommand
+ describe the command.
+
+ @return [TKeyList]
+ the list of registered keys. Can be empty!
+ */
+ virtual TKeyList getKeysByCommand(const ::rtl::OUString& sCommand) const;
+
+ //---------------------------------------
+ /** TODO */
+ virtual ::rtl::OUString getCommandByKey(const css::awt::KeyEvent& aKey) const;
+
+ //---------------------------------------
+ /** TODO */
+ virtual void removeKey(const css::awt::KeyEvent& aKey);
+ virtual void removeCommand(const ::rtl::OUString& sCommand);
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_ACCELERATORS_ACCELERATORCACHE_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/acceleratorconfiguration.hxx b/framework/source/inc/accelerators/acceleratorconfiguration.hxx
new file mode 100644
index 000000000000..1b34cb13c3e1
--- /dev/null
+++ b/framework/source/inc/accelerators/acceleratorconfiguration.hxx
@@ -0,0 +1,479 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_ACCELERATORS_ACCELERATORCONFIGURATION_HXX_
+#define __FRAMEWORK_ACCELERATORS_ACCELERATORCONFIGURATION_HXX_
+
+//__________________________________________
+// own includes
+
+#include <accelerators/istoragelistener.hxx>
+#include <accelerators/presethandler.hxx>
+#include <accelerators/acceleratorcache.hxx>
+#include <accelerators/keymapping.hxx>
+#include <macros/xinterface.hxx>
+#include <macros/xtypeprovider.hxx>
+#include <threadhelp/threadhelpbase.hxx>
+#include <general.h>
+#include <stdtypes.h>
+
+//__________________________________________
+// interface includes
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <com/sun/star/ui/XUIConfiguration.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+
+#include <com/sun/star/ui/XUIConfigurationStorage.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/util/XChangesListener.hpp>
+
+// TODO use XPresetHandler interface instead if available
+#include <com/sun/star/form/XReset.hpp>
+
+//__________________________________________
+// other includes
+#include <cppuhelper/propshlp.hxx>
+#include <cppuhelper/weak.hxx>
+#include <comphelper/locale.hxx>
+#include <salhelper/singletonref.hxx>
+
+//__________________________________________
+// definition
+
+namespace framework
+{
+//-----------------------------------------------
+// Accelerators.xcu
+
+extern const ::rtl::OUString CFG_ENTRY_PRIMARY;
+extern const ::rtl::OUString CFG_ENTRY_SECONDARY;
+
+extern const ::rtl::OUString CFG_ENTRY_GLOBAL;
+extern const ::rtl::OUString CFG_ENTRY_MODULES;
+
+extern const ::rtl::OUString CFG_PROP_COMMAND;
+
+/** "global" type to make accelerator presets unique, so they can be used
+ in combination with the salhelper::SingletonRef mechanism! */
+typedef PresetHandler AcceleratorPresets;
+
+//__________________________________________
+/**
+ implements a read/write access to the accelerator configuration.
+ */
+class XMLBasedAcceleratorConfiguration : protected ThreadHelpBase // attention! Must be the first base class to guarentee right initialize lock ...
+ , public IStorageListener
+ , public ::cppu::OWeakObject
+ , public css::lang::XTypeProvider
+ , public css::form::XReset // TODO use XPresetHandler instead if available
+ , public css::ui::XAcceleratorConfiguration // => css::ui::XUIConfigurationPersistence
+ // css::ui::XUIConfigurationStorage
+ // css::ui::XUIConfiguration
+{
+ //______________________________________
+ // member
+
+ protected:
+
+ //---------------------------------------
+ /** the global uno service manager.
+ Must be used to create own needed services. */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ //---------------------------------------
+ /** used to:
+ i ) copy configuration files from the share to the user layer
+ ii ) provide access to these config files
+ iii) cache all sub storages on the path from the top to the bottom(!)
+ iv ) provide commit for changes. */
+ PresetHandler m_aPresetHandler;
+
+ //---------------------------------------
+ /** contains the cached configuration data */
+ AcceleratorCache m_aReadCache;
+
+ //---------------------------------------
+ /** used to implement the copy on write pattern! */
+ AcceleratorCache* m_pWriteCache;
+
+ //______________________________________
+ // native interface!
+
+ public:
+
+ XMLBasedAcceleratorConfiguration( const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR );
+ virtual ~XMLBasedAcceleratorConfiguration( );
+
+ //______________________________________
+ // uno interface!
+
+ public:
+
+ // XInterface, XTypeProvider
+ FWK_DECLARE_XINTERFACE
+ FWK_DECLARE_XTYPEPROVIDER
+
+ // XAcceleratorConfiguration
+ virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getAllKeyEvents()
+ throw(css::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent)
+ throw(css::container::NoSuchElementException,
+ css::uno::RuntimeException );
+
+ virtual void SAL_CALL setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
+ const ::rtl::OUString& sCommand )
+ throw(css::lang::IllegalArgumentException,
+ css::uno::RuntimeException );
+
+ virtual void SAL_CALL removeKeyEvent(const css::awt::KeyEvent& aKeyEvent)
+ throw(css::container::NoSuchElementException,
+ css::uno::RuntimeException );
+
+ virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getKeyEventsByCommand(const ::rtl::OUString& sCommand)
+ throw(css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::uno::RuntimeException );
+
+ virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList)
+ throw(css::lang::IllegalArgumentException ,
+ css::uno::RuntimeException );
+
+ virtual void SAL_CALL removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand)
+ throw(css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::uno::RuntimeException );
+
+ // XUIConfigurationPersistence
+ virtual void SAL_CALL reload()
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL store()
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL isModified()
+ throw(css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL isReadOnly()
+ throw(css::uno::RuntimeException);
+
+ // XUIConfigurationStorage
+ virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
+ throw(css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL hasStorage()
+ throw(css::uno::RuntimeException);
+
+ // XUIConfiguration
+ virtual void SAL_CALL addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener)
+ throw(css::uno::RuntimeException);
+
+ // XReset
+ // TODO use XPresetHandler instead if available
+ virtual void SAL_CALL reset()
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL addResetListener(const css::uno::Reference< css::form::XResetListener >& xListener)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeResetListener(const css::uno::Reference< css::form::XResetListener >& xListener)
+ throw(css::uno::RuntimeException);
+
+ // IStorageListener
+ virtual void changesOccurred(const ::rtl::OUString& sPath);
+
+ //______________________________________
+ // helper for derived classes
+
+ protected:
+
+ //---------------------------------------
+ /** @short return the current office locale.
+
+ @descr We does not cache this value, because we are not listen
+ for changes on the configuration layer ...
+
+ @return ::comphelper::Locale
+ The current office locale.
+ */
+ ::comphelper::Locale impl_ts_getLocale() const;
+
+ //______________________________________
+ // helper
+
+ private:
+
+ //---------------------------------------
+ /** @short load a configuration set, using the given stream.
+
+ @param xStream
+ provides the XML structure as stream.
+ */
+ void impl_ts_load(const css::uno::Reference< css::io::XInputStream >& xStream);
+
+ //---------------------------------------
+ /** @short save a configuration set, using the given stream.
+
+ @param xStream
+ the XML structure can be written there.
+ */
+ void impl_ts_save(const css::uno::Reference< css::io::XOutputStream >& xStream);
+
+ //---------------------------------------
+ /** @short try to locate and open a sub storage.
+
+ @descr It search at the root storage for the specified
+ sub storage. If it exists - it will be opened.
+ By default this method tries to open the storage
+ for reading. But the calli can request a writeable
+ storage.
+
+ @param xRooStorage
+ used to locate the sub storage.
+
+ @param sSubStorage
+ relativ path of the sub storage.
+
+ @param bOutStream
+ force open of the sub storage in
+ write mode - instead of read mode, which
+ is the default.
+
+ @return [XInterface]
+ will be a css::io::XInpoutStream or a css::io::XOutputStream.
+ Depends from the parameter bWriteable!
+ */
+ css::uno::Reference< css::uno::XInterface > impl_ts_openSubStorage(const css::uno::Reference< css::embed::XStorage >& xRootStorage,
+ const ::rtl::OUString& sSubStorage ,
+ sal_Bool bOutStream );
+
+ //---------------------------------------
+ /** @short returns a reference to one of our internal cache members.
+
+ @descr We implement the copy-on-write pattern. Doing so
+ we know two caches internaly. The second one is used
+ only, if the container was changed.
+
+ This method here returns access to one of these
+ caches - depending on the change state of this
+ configuration service.
+
+ @param bWriteAccessRequested
+ if the outside code whish to change the container
+ it must call this method with "sal_True". So the internal
+ cache can be prepared for that (means copy-on-write ...).
+
+ @return [AcceleratorCache]
+ c++ reference(!) to one of our internal caches.
+ */
+ AcceleratorCache& impl_getCFG(sal_Bool bWriteAccessRequested = sal_False);
+
+};
+
+class XCUBasedAcceleratorConfiguration : protected ThreadHelpBase // attention! Must be the first base class to guarentee right initialize lock ...
+ , public ::cppu::OWeakObject
+ , public css::lang::XTypeProvider
+ , public css::util::XChangesListener
+ , public css::form::XReset // TODO use XPresetHandler instead if available
+ , public css::ui::XAcceleratorConfiguration // => css::ui::XUIConfigurationPersistence
+ // css::ui::XUIConfigurationStorage
+ // css::ui::XUIConfiguration
+{
+ //______________________________________
+ // member
+
+ protected:
+
+ //---------------------------------------
+ /** the global uno service manager.
+ Must be used to create own needed services. */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ css::uno::Reference< css::container::XNameAccess > m_xCfg;
+ AcceleratorCache m_aPrimaryReadCache;
+ AcceleratorCache m_aSecondaryReadCache;
+ AcceleratorCache* m_pPrimaryWriteCache;
+ AcceleratorCache* m_pSecondaryWriteCache;
+
+ ::rtl::OUString m_sGlobalOrModules;
+ ::rtl::OUString m_sModuleCFG;
+
+ ::salhelper::SingletonRef< KeyMapping > m_rKeyMapping;
+
+ //______________________________________
+ // native interface!
+
+ public:
+
+ XCUBasedAcceleratorConfiguration( const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR );
+ virtual ~XCUBasedAcceleratorConfiguration( );
+
+ //______________________________________
+ // uno interface!
+
+ public:
+
+ // XInterface, XTypeProvider
+ FWK_DECLARE_XINTERFACE
+ FWK_DECLARE_XTYPEPROVIDER
+
+ // XAcceleratorConfiguration
+ virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getAllKeyEvents()
+ throw(css::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent)
+ throw(css::container::NoSuchElementException,
+ css::uno::RuntimeException );
+
+ virtual void SAL_CALL setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
+ const ::rtl::OUString& sCommand )
+ throw(css::lang::IllegalArgumentException,
+ css::uno::RuntimeException );
+
+ virtual void SAL_CALL removeKeyEvent(const css::awt::KeyEvent& aKeyEvent)
+ throw(css::container::NoSuchElementException,
+ css::uno::RuntimeException );
+
+ virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getKeyEventsByCommand(const ::rtl::OUString& sCommand)
+ throw(css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::uno::RuntimeException );
+
+ virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPreferredKeyEventsForCommandList(const css::uno::Sequence< ::rtl::OUString >& lCommandList)
+ throw(css::lang::IllegalArgumentException ,
+ css::uno::RuntimeException );
+
+ virtual void SAL_CALL removeCommandFromAllKeyEvents(const ::rtl::OUString& sCommand)
+ throw(css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::uno::RuntimeException );
+
+ // XUIConfigurationPersistence
+ virtual void SAL_CALL reload()
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL store()
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL isModified()
+ throw(css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL isReadOnly()
+ throw(css::uno::RuntimeException);
+
+ // XUIConfigurationStorage
+ virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
+ throw(css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL hasStorage()
+ throw(css::uno::RuntimeException);
+
+ // XUIConfiguration
+ virtual void SAL_CALL addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener)
+ throw(css::uno::RuntimeException);
+
+ // XReset
+ // TODO use XPresetHandler instead if available
+ virtual void SAL_CALL reset()
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL addResetListener(const css::uno::Reference< css::form::XResetListener >& xListener)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeResetListener(const css::uno::Reference< css::form::XResetListener >& xListener)
+ throw(css::uno::RuntimeException);
+
+ // css.util.XChangesListener
+ virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent)
+ throw(css::uno::RuntimeException);
+
+ // css.lang.XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException);
+
+ //______________________________________
+ // helper for derived classes
+
+ protected:
+
+ //---------------------------------------
+ /** @short return the current office locale.
+
+ @descr We does not cache this value, because we are not listen
+ for changes on the configuration layer ...
+
+ @return ::comphelper::Locale
+ The current office locale.
+ */
+ ::comphelper::Locale impl_ts_getLocale() const;
+
+ //______________________________________
+ // helper
+
+ private:
+
+ void impl_ts_load(sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg);
+ void impl_ts_save(sal_Bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg);
+
+ void insertKeyToConfiguration(const css::awt::KeyEvent& aKeyEvent, const ::rtl::OUString& sCommand, const sal_Bool bPreferred);
+ void removeKeyFromConfiguration(const css::awt::KeyEvent& aKeyEvent, const sal_Bool bPreferred);
+
+ void reloadChanged(const ::rtl::OUString& sPrimarySecondary, const ::rtl::OUString& sGlobalModules, const ::rtl::OUString& sModule, const ::rtl::OUString& sKey);
+ AcceleratorCache& impl_getCFG(sal_Bool bPreferred, sal_Bool bWriteAccessRequested = sal_False);
+
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_ACCELERATORS_ACCELERATORCONFIGURATION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/documentacceleratorconfiguration.hxx b/framework/source/inc/accelerators/documentacceleratorconfiguration.hxx
new file mode 100644
index 000000000000..cdd90d21af45
--- /dev/null
+++ b/framework/source/inc/accelerators/documentacceleratorconfiguration.hxx
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_
+#define __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_
+
+//__________________________________________
+// own includes
+
+#include <accelerators/acceleratorconfiguration.hxx>
+#include <accelerators/istoragelistener.hxx>
+#include <accelerators/presethandler.hxx>
+
+#include <macros/xinterface.hxx>
+#include <macros/xtypeprovider.hxx>
+#include <macros/xserviceinfo.hxx>
+
+//__________________________________________
+// interface includes
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/XUIConfigurationStorage.hpp>
+
+//__________________________________________
+// other includes
+
+//__________________________________________
+// definition
+
+namespace framework
+{
+
+//__________________________________________
+/**
+ implements a read/write access to a document
+ based accelerator configuration.
+ */
+class DocumentAcceleratorConfiguration : public XMLBasedAcceleratorConfiguration
+ , public css::lang::XServiceInfo
+ , public css::lang::XInitialization
+// , public css::ui::XUIConfigurationStorage
+{
+ //______________________________________
+ // member
+
+ private:
+
+ //----------------------------------
+ /** points to the root storage of the outside document,
+ where we can read/save our configuration data. */
+ css::uno::Reference< css::embed::XStorage > m_xDocumentRoot;
+
+ //______________________________________
+ // interface
+
+ public:
+
+ //----------------------------------
+ /** initialize this instance and fill the internal cache.
+
+ @param xSMGR
+ reference to an uno service manager, which is used internaly.
+ */
+ DocumentAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR);
+ virtual ~DocumentAcceleratorConfiguration();
+
+ // XInterface, XTypeProvider, XServiceInfo
+ FWK_DECLARE_XINTERFACE
+ FWK_DECLARE_XTYPEPROVIDER
+ DECLARE_XSERVICEINFO
+
+ // XInitialization
+ virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ // XUIConfigurationStorage
+ virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
+ throw(css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasStorage()
+ throw(css::uno::RuntimeException);
+
+ //______________________________________
+ // helper
+
+ private:
+
+ //----------------------------------
+ /** read all data into the cache. */
+ void impl_ts_fillCache();
+
+ //----------------------------------
+ /** forget all currently cached data AND(!)
+ forget all currently used storages. */
+ void impl_ts_clearCache();
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_ACCELERATORS_DOCUMENTACCELERATORCONFIGURATION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/globalacceleratorconfiguration.hxx b/framework/source/inc/accelerators/globalacceleratorconfiguration.hxx
new file mode 100644
index 000000000000..28c7ba4eb12b
--- /dev/null
+++ b/framework/source/inc/accelerators/globalacceleratorconfiguration.hxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_ACCELERATORS_GLOBALACCELERATORCONFIGURATION_HXX_
+#define __FRAMEWORK_ACCELERATORS_GLOBALACCELERATORCONFIGURATION_HXX_
+
+//__________________________________________
+// own includes
+
+#include <accelerators/acceleratorconfiguration.hxx>
+#include <accelerators/presethandler.hxx>
+
+#include <macros/xinterface.hxx>
+#include <macros/xtypeprovider.hxx>
+#include <macros/xserviceinfo.hxx>
+
+//__________________________________________
+// interface includes
+
+#include <com/sun/star/lang/XInitialization.hpp>
+
+//__________________________________________
+// other includes
+
+//__________________________________________
+// definition
+
+namespace framework
+{
+
+//__________________________________________
+/**
+ implements a read/write access to the global
+ accelerator configuration.
+ */
+class GlobalAcceleratorConfiguration : public XCUBasedAcceleratorConfiguration
+ , public css::lang::XServiceInfo
+ , public css::lang::XInitialization
+{
+ //______________________________________
+ // interface
+
+ public:
+
+ //----------------------------------
+ /** initialize this instance and fill the internal cache.
+
+ @param xSMGR
+ reference to an uno service manager, which is used internaly.
+ */
+ GlobalAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR);
+
+ //----------------------------------
+ /** TODO */
+ virtual ~GlobalAcceleratorConfiguration();
+
+ // XInterface, XTypeProvider, XServiceInfo
+ FWK_DECLARE_XINTERFACE
+ FWK_DECLARE_XTYPEPROVIDER
+ DECLARE_XSERVICEINFO
+
+ // XInitialization
+ virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw (css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ //______________________________________
+ // helper
+
+ private:
+
+ ::rtl::OUString m_sLocale;
+
+ /** helper to listen for configuration changes without ownership cycle problems */
+ css::uno::Reference< css::util::XChangesListener > m_xCfgListener;
+
+ //----------------------------------
+ /** read all data into the cache. */
+ void impl_ts_fillCache();
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_ACCELERATORS_GLOBALACCELERATORCONFIGURATION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/istoragelistener.hxx b/framework/source/inc/accelerators/istoragelistener.hxx
new file mode 100644
index 000000000000..555d517d3a54
--- /dev/null
+++ b/framework/source/inc/accelerators/istoragelistener.hxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_ACCELERATORS_ISTORAGELISTENER_HXX_
+#define __FRAMEWORK_ACCELERATORS_ISTORAGELISTENER_HXX_
+
+//__________________________________________
+// own includes
+
+#include <general.h>
+#include <stdtypes.h>
+
+//__________________________________________
+// interface includes
+
+//__________________________________________
+// other includes
+
+//__________________________________________
+// definition
+
+namespace framework
+{
+
+//__________________________________________
+/**
+ TODO document me
+ */
+class IStorageListener
+{
+ public:
+
+ //--------------------------------------
+ /** @short TODO */
+ virtual void changesOccurred(const ::rtl::OUString& sPath) = 0;
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_ACCELERATORS_ISTORAGELISTENER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/keymapping.hxx b/framework/source/inc/accelerators/keymapping.hxx
new file mode 100644
index 000000000000..d64964d5cf4d
--- /dev/null
+++ b/framework/source/inc/accelerators/keymapping.hxx
@@ -0,0 +1,165 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_ACCELERATORS_KEYMAPPING_HXX_
+#define __FRAMEWORK_ACCELERATORS_KEYMAPPING_HXX_
+
+//__________________________________________
+// own includes
+
+#include <general.h>
+#include <stdtypes.h>
+
+//__________________________________________
+// interface includes
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+//__________________________________________
+// other includes
+
+//__________________________________________
+// definition
+
+namespace framework
+{
+
+//__________________________________________
+/**
+ can be used to map key identifier to the
+ corresponding key codes ...
+ */
+class KeyMapping
+{
+ //______________________________________
+ // const, types
+
+ private:
+
+ //---------------------------------------
+ /** @short is used to map a key code
+ to the right key identifier, which is
+ used to make the xml file "human readable"
+ */
+ struct KeyIdentifierInfo
+ {
+ sal_Int16 Code ;
+ const char* Identifier;
+ };
+
+ //---------------------------------------
+ /** @short hash structure to map identifier to key codes. */
+ typedef BaseHash< sal_Int16 > Identifier2CodeHash;
+
+ //---------------------------------------
+ /** @short hash structure to map key codes to identifier. */
+ typedef ::boost::unordered_map< sal_Int16 ,
+ ::rtl::OUString ,
+ ShortHashCode ,
+ ::std::equal_to< sal_Int16 > > Code2IdentifierHash;
+
+ //______________________________________
+ // member
+
+ private:
+
+ static KeyIdentifierInfo KeyIdentifierMap[];
+
+ //---------------------------------------
+ /** @short hash to map identifier to key codes. */
+ Identifier2CodeHash m_lIdentifierHash;
+
+ //---------------------------------------
+ /** @short hash to map key codes to identifier. */
+ Code2IdentifierHash m_lCodeHash;
+
+ //______________________________________
+ // interface
+
+ public:
+
+ KeyMapping();
+ virtual ~KeyMapping();
+
+ //----------------------------------
+ /** @short return a suitable key code
+ for the specified key identifier.
+
+ @param sIdentifier
+ string value, which describe the key.
+
+ @return [css::awt::KeyEvent]
+ the corresponding key code as
+ short value.
+
+ @throw [css::lang::IllegalArgumentException]
+ if the given identifier does not describe
+ a well known key code.
+ */
+ virtual sal_uInt16 mapIdentifierToCode(const ::rtl::OUString& sIdentifier)
+ throw(css::lang::IllegalArgumentException);
+
+ //----------------------------------
+ /** @short return a suitable key identifier
+ for the specified key code.
+
+ @param nCode
+ short value, which describe the key.
+
+ @return The corresponding string identifier.
+ */
+ virtual ::rtl::OUString mapCodeToIdentifier(sal_uInt16 nCode);
+
+ //______________________________________
+ // helper
+
+ private:
+
+ //----------------------------------
+ /** @short check if the given string describe a numeric
+ value ... and convert it.
+
+ @param sIdentifier
+ the string value, which should be converted.
+
+
+ @param rCode
+ contains the converted code, but is defined only
+ if this method returns sal_True!
+
+ @return [boolean]
+ sal_True if convertion was successfully.
+ */
+ sal_Bool impl_st_interpretIdentifierAsPureKeyCode(const ::rtl::OUString& sIdentifier,
+ sal_uInt16& rCode );
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_ACCELERATORS_KEYMAPPING_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/moduleacceleratorconfiguration.hxx b/framework/source/inc/accelerators/moduleacceleratorconfiguration.hxx
new file mode 100644
index 000000000000..05588598ebf8
--- /dev/null
+++ b/framework/source/inc/accelerators/moduleacceleratorconfiguration.hxx
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_ACCELERATORS_MODULEACCELERATORCONFIGURATION_HXX_
+#define __FRAMEWORK_ACCELERATORS_MODULEACCELERATORCONFIGURATION_HXX_
+
+//__________________________________________
+// own includes
+
+#include <accelerators/acceleratorconfiguration.hxx>
+#include <accelerators/presethandler.hxx>
+
+#include <macros/xinterface.hxx>
+#include <macros/xtypeprovider.hxx>
+#include <macros/xserviceinfo.hxx>
+
+//__________________________________________
+// interface includes
+#include <com/sun/star/lang/XInitialization.hpp>
+
+//__________________________________________
+// other includes
+
+//__________________________________________
+// definition
+
+namespace framework
+{
+
+//__________________________________________
+/**
+ implements a read/write access to a module
+ dependend accelerator configuration.
+ */
+class ModuleAcceleratorConfiguration : public XCUBasedAcceleratorConfiguration
+ , public css::lang::XServiceInfo
+ , public css::lang::XInitialization
+{
+ //______________________________________
+ // member
+
+ private:
+
+ //----------------------------------
+ /** identify the application module, where this accelerator
+ configuration cache should work on. */
+ ::rtl::OUString m_sModule;
+ ::rtl::OUString m_sLocale;
+
+ //______________________________________
+ // interface
+
+ public:
+
+ //----------------------------------
+ /** initialize this instance and fill the internal cache.
+
+ @param xSMGR
+ reference to an uno service manager, which is used internaly.
+ */
+ ModuleAcceleratorConfiguration(const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR);
+
+ //----------------------------------
+ /** TODO */
+ virtual ~ModuleAcceleratorConfiguration();
+
+ // XInterface, XTypeProvider, XServiceInfo
+ FWK_DECLARE_XINTERFACE
+ FWK_DECLARE_XTYPEPROVIDER
+ DECLARE_XSERVICEINFO
+
+ // XInitialization
+ virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException);
+
+ //______________________________________
+ // helper
+
+ private:
+ /** helper to listen for configuration changes without ownership cycle problems */
+ css::uno::Reference< css::util::XChangesListener > m_xCfgListener;
+
+ //----------------------------------
+ /** read all data into the cache. */
+ void impl_ts_fillCache();
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_ACCELERATORS_MODULEACCELERATORCONFIGURATION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/presethandler.hxx b/framework/source/inc/accelerators/presethandler.hxx
new file mode 100644
index 000000000000..cb136f122a46
--- /dev/null
+++ b/framework/source/inc/accelerators/presethandler.hxx
@@ -0,0 +1,534 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_ACCELERATORS_PRESETHANDLER_HXX_
+#define __FRAMEWORK_ACCELERATORS_PRESETHANDLER_HXX_
+
+//__________________________________________
+// own includes
+
+#include <accelerators/storageholder.hxx>
+#include <threadhelp/threadhelpbase.hxx>
+#include <general.h>
+#include <stdtypes.h>
+
+//__________________________________________
+// interface includes
+
+#include <com/sun/star/embed/XStorage.hpp>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//__________________________________________
+// other includes
+#include <comphelper/processfactory.hxx>
+#include <salhelper/singletonref.hxx>
+#include <comphelper/locale.hxx>
+
+//__________________________________________
+// definition
+
+namespace framework
+{
+
+//__________________________________________
+/**
+ TODO document me
+
+ <layer>/global/<resourcetype>/<preset>.xml
+ <layer>/modules/<moduleid>/<resourcetype>/<preset>.xml
+
+ RESOURCETYPE PRESET TARGET
+ (share) (user)
+ "accelerator" "default" "current"
+ "word"
+ "excel"
+
+ "menubar" "default" "menubar"
+
+ */
+class PresetHandler : private ThreadHelpBase // attention! Must be the first base class to guarentee right initialize lock ...
+{
+ //-------------------------------------------
+ // const
+
+ public:
+
+ static ::rtl::OUString PRESET_DEFAULT();
+ static ::rtl::OUString TARGET_CURRENT();
+
+ static ::rtl::OUString RESOURCETYPE_MENUBAR();
+ static ::rtl::OUString RESOURCETYPE_TOOLBAR();
+ static ::rtl::OUString RESOURCETYPE_ACCELERATOR();
+ static ::rtl::OUString RESOURCETYPE_STATUSBAR();
+
+ //-------------------------------------------
+ // types
+
+ public:
+
+ //---------------------------------------
+ /** @short this handler can provide different
+ types of configuration.
+
+ @descr Means: a global or a module dependend
+ or ... configuration.
+ */
+ enum EConfigType
+ {
+ E_GLOBAL,
+ E_MODULES,
+ E_DOCUMENT
+ };
+
+ private:
+
+ //---------------------------------------
+ /** @short because a concurrent access to the same storage from different implementations
+ isnt supported, we have to share it with others.
+
+ @descr This struct makes it possible to use any shared storage
+ in combination with a SingletonRef<> template ...
+
+ Attention: Because these struct is shared it must be
+ used within a synchronized section. Thats why this struct
+ uses a base class ThreadHelpBase and can be locked
+ from outside doing so!
+ */
+ struct TSharedStorages : public ThreadHelpBase
+ {
+ public:
+
+ StorageHolder m_lStoragesShare;
+ StorageHolder m_lStoragesUser;
+
+ TSharedStorages()
+ : m_lStoragesShare(::comphelper::getProcessServiceFactory())
+ , m_lStoragesUser (::comphelper::getProcessServiceFactory())
+ {};
+
+ virtual ~TSharedStorages() {};
+ };
+
+ //-------------------------------------------
+ // member
+
+ private:
+
+ //---------------------------------------
+ /** @short can be used to create on needed uno resources. */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ //---------------------------------------
+ /** @short knows the type of provided configuration.
+
+ @descr e.g. global, modules, ...
+ */
+ EConfigType m_eConfigType;
+
+ //---------------------------------------
+ /** @short specify the type of resource, which configuration sets
+ must be provided here.
+
+ @descr e.g. menubars, toolbars, accelerators
+ */
+ ::rtl::OUString m_sResourceType;
+
+ //---------------------------------------
+ /** @short specify the application module for a module
+ dependend configuration.
+
+ @descr Will be used only, if m_sResourceType is set to
+ "module". Further it must be a valid module identifier
+ then ...
+ */
+ ::rtl::OUString m_sModule;
+
+ //---------------------------------------
+ /** @short provides access to the:
+ a) shared root storages
+ b) shared "inbetween" storages
+ of the share and user layer. */
+ ::salhelper::SingletonRef< TSharedStorages > m_aSharedStorages;
+
+ //---------------------------------------
+ /** @short if we run in document mode, we cant use the global root storages!
+ We have to use a special document storage explicitly. */
+ StorageHolder m_lDocumentStorages;
+
+ //---------------------------------------
+ /** @short holds the folder storage of the share layer alive,
+ where the current configuration set exists.
+
+ @descr Note: If this preset handler works in document mode
+ this member is meaned relative to the document root ...
+ not to the share layer root!
+
+ Further is defined, that m_xWorkingStorageUser
+ is equals to m_xWorkingStorageShare then!
+ */
+ css::uno::Reference< css::embed::XStorage > m_xWorkingStorageShare;
+
+ //---------------------------------------
+ /** @short global language-independent storage
+ */
+ css::uno::Reference< css::embed::XStorage > m_xWorkingStorageNoLang;
+
+ //---------------------------------------
+ /** @short holds the folder storage of the user layer alive,
+ where the current configuration set exists.
+
+ @descr Note: If this preset handler works in document mode
+ this member is meaned relative to the document root ...
+ not to the user layer root!
+
+ Further is defined, that m_xWorkingStorageUser
+ is equals to m_xWorkingStorageShare then!
+ */
+ css::uno::Reference< css::embed::XStorage > m_xWorkingStorageUser;
+
+ //---------------------------------------
+ /** @short knows the names of all presets inside the current
+ working storage of the share layer. */
+ OUStringList m_lPresets;
+
+ //---------------------------------------
+ /** @short knows the names of all targets inside the current
+ working storage of the user layer. */
+ OUStringList m_lTargets;
+
+ //---------------------------------------
+ /** @short its the current office locale and will be used
+ to handle localized presets.
+
+ @descr Default is "x-notranslate" which disable any
+ localized handling inside this class! */
+ ::comphelper::Locale m_aLocale;
+
+ //---------------------------------------
+ /** @short knows the relative path from the root. */
+ ::rtl::OUString m_sRelPathShare;
+ ::rtl::OUString m_sRelPathNoLang;
+ ::rtl::OUString m_sRelPathUser;
+
+ //-------------------------------------------
+ // native interface
+
+ public:
+
+ //---------------------------------------
+ /** @short does nothing real.
+
+ @descr Because this class should be useable in combination
+ with ::salhelper::SingletonRef template this ctor
+ cant have any special parameters!
+
+ @param xSMGR
+ points to an uno service manager, which is used internaly
+ to create own needed uno resources.
+ */
+ PresetHandler(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+
+ //---------------------------------------
+ /** @short copy ctor */
+ PresetHandler(const PresetHandler& rCopy);
+
+ //---------------------------------------
+ /** @short closes all open storages ... if user forgot that .-) */
+ virtual ~PresetHandler();
+
+ //---------------------------------------
+ /** @short free all currently cache(!) storages. */
+ void forgetCachedStorages();
+
+ //---------------------------------------
+ /** @short return access to the internaly used and cached root storage.
+
+ @descr These root storages are the base of all further opened
+ presets and targets. They are provided here only, to support
+ older implementations, which base on them ...
+
+ getOrCreate...() - What does it mean?
+ Such root storage will be created one times only and
+ cached then internaly till the last instance of such PresetHandler
+ dies.
+
+ @return com::sun::star::embed::XStorage
+ which represent a root storage.
+ */
+ css::uno::Reference< css::embed::XStorage > getOrCreateRootStorageShare();
+ css::uno::Reference< css::embed::XStorage > getOrCreateRootStorageUser();
+
+ //---------------------------------------
+ /** @short provides access to the current working storages.
+
+ @descr Working storages are the "lowest" storages, where the
+ preset and target files exists.
+
+ @return com::sun::star::embed::XStorage
+ which the current working storage.
+ */
+ css::uno::Reference< css::embed::XStorage > getWorkingStorageShare();
+ css::uno::Reference< css::embed::XStorage > getWorkingStorageUser();
+
+ //---------------------------------------
+ /** @short check if there is a parent storage well known for
+ the specified child storage and return it.
+
+ @param xChild
+ the child storage where a paranet storage should be searched for.
+
+ @return com::sun::star::embed::XStorage
+ A valid storage if a paranet exists. NULL otherwise.
+ */
+ css::uno::Reference< css::embed::XStorage > getParentStorageShare(const css::uno::Reference< css::embed::XStorage >& xChild);
+ css::uno::Reference< css::embed::XStorage > getParentStorageUser (const css::uno::Reference< css::embed::XStorage >& xChild);
+
+ //---------------------------------------
+ /** @short free all internal structures and let this handler
+ work on a new type of configuration sets.
+
+ @param eConfigType
+ differ between global or module dependend configuration.
+
+ @param sResourceType
+ differ between menubar/toolbar/accelerator/... configuration.
+
+ @param sModule
+ if sResourceType is set to a module dependend configuration,
+ it address the current application module.
+
+ @param xDocumentRoot
+ if sResourceType is set to E_DOCUMENT, this value points to the
+ root storage inside the document, where we can save our
+ configuration files. Note: Thats not the real root of the document ...
+ its only a sub storage. But we interpret it as our root storage.
+
+ @param aLocale
+ in case this configuration supports localized entries,
+ the current locale must be set.
+
+ Localzation will be represented as directory structure
+ of provided presets. Means: you call us with a preset name "default";
+ and we use e.g. "/en-US/default.xml" internaly.
+
+ If no localization exists for this preset set, this class
+ will work in default mode - means "no locale" - automaticly.
+ e.g. "/default.xml"
+
+ @throw com::sun::star::uno::RuntimeException(!)
+ if the specified resource couldn't be located.
+ */
+ void connectToResource( EConfigType eConfigType ,
+ const ::rtl::OUString& sResourceType ,
+ const ::rtl::OUString& sModule ,
+ const css::uno::Reference< css::embed::XStorage >& xDocumentRoot ,
+ const ::comphelper::Locale& aLocale = ::comphelper::Locale(::comphelper::Locale::X_NOTRANSLATE()));
+
+ //---------------------------------------
+ /** @short try to copy the specified preset from the share
+ layer to the user layer and establish it as the
+ specified target.
+
+ @descr Means: copy share/.../<preset>.xml user/.../<target>.xml
+ Note: The target will be overwritten completly or
+ created as new by this operation!
+
+ @param sPreset
+ the ALIAS name of an existing preset.
+
+ @param sTarget
+ the ALIAS name of the target.
+
+ @throw com::sun::star::container::NoSuchElementException
+ if the specified preset does not exists.
+
+ @throw com::sun::star::io::IOException
+ if copying failed.
+ */
+ void copyPresetToTarget(const ::rtl::OUString& sPreset,
+ const ::rtl::OUString& sTarget);
+
+ //---------------------------------------
+ /** @short open the specified preset as stream object
+ and return it.
+
+ @descr Note: Because presets resist inside the share
+ layer, they will be opened readonly everytimes.
+
+ @param sPreset
+ the ALIAS name of an existing preset.
+
+ @param bNoLangGlobal
+ access the global language-independent storage instead of the preset storage
+
+ @return The opened preset stream ... or NULL if the preset does not exists.
+ */
+ css::uno::Reference< css::io::XStream > openPreset(const ::rtl::OUString& sPreset,
+ sal_Bool bUseNoLangGlobal = sal_False);
+
+ //---------------------------------------
+ /** @short open the specified target as stream object
+ and return it.
+
+ @descr Note: Targets resist inside the user
+ layer. Normaly they are opened in read/write mode.
+ But it will be opened readonly automaticly if that isnt possible
+ (may be the file is write protected on the system ...).
+
+ @param sTarget
+ the ALIAS name of the target.
+
+ @param bCreateIfMissing
+ create target file, if it does not still exists.
+ Note: That does not means reseting of an existing file!
+
+ @return The opened target stream ... or NULL if the target does not exists
+ or couldnt be created as new one.
+ */
+ css::uno::Reference< css::io::XStream > openTarget(const ::rtl::OUString& sTarget ,
+ sal_Bool bCreateIfMissing);
+
+ //---------------------------------------
+ /** @short do anything which is neccessary to flush all changes
+ back to disk.
+
+ @descr We have to call commit on all cached sub storages on the
+ path from the root storage upside down to the working storage
+ (which are not realy used, but required to be holded alive!).
+ */
+ void commitUserChanges();
+
+ //---------------------------------------
+ /** TODO */
+ void addStorageListener(IStorageListener* pListener);
+ void removeStorageListener(IStorageListener* pListener);
+
+ //-------------------------------------------
+ // helper
+
+ private:
+
+ //---------------------------------------
+ /** @short open a config path ignoring errors (catching exceptions).
+
+ @descr We catch only normal exceptions here - no runtime exceptions.
+
+ @param sPath
+ the configuration path, which should be opened.
+
+ @param eMode
+ the open mode (READ/READWRITE)
+
+ @param bShare
+ force using of the share layer instead of the user layer.
+
+ @return An opened storage in case method was successfully - null otherwise.
+ */
+ css::uno::Reference< css::embed::XStorage > impl_openPathIgnoringErrors(const ::rtl::OUString& sPath ,
+ sal_Int32 eMode ,
+ sal_Bool bShare);
+
+ //---------------------------------------
+ /** @short try to find the specified locale inside list of possible ones.
+
+ @descr The lits of possible locale values was e.g. retrieved from the system
+ (configuration, directory listing etcpp). The locale normaly represent
+ the current office locale. This method search for a suitable item by using
+ different algorithm.
+ a) exact search
+ b) search with using fallbacks
+
+ @param lLocalizedValues
+ list of ISO locale codes
+
+ @param aLocale
+ [IN ] the current office locale, which should be searched inside lLocalizedValues.
+ [OUT] in case fallbacks was allowed, it contains afterwards the fallback locale.
+
+ @param bAllowFallbacks
+ enable/disable using of fallbacks
+
+ @return An iterator, which points directly into lLocalizedValue list.
+ As a negative result the special iterator lLocalizedValues.end() will be returned.
+ */
+ ::std::vector< ::rtl::OUString >::const_iterator impl_findMatchingLocalizedValue(const ::std::vector< ::rtl::OUString >& lLocalizedValues,
+ ::comphelper::Locale& aLocale ,
+ sal_Bool bAllowFallbacks );
+
+ //---------------------------------------
+ /** @short open a config path ignoring errors (catching exceptions).
+
+ @descr We catch only normal exceptions here - no runtime exceptions.
+ Further the path itself is tries in different versions (using locale
+ specific attributes).
+ e.g. "path/e-US" => "path/en" => "path/de"
+
+ @param sPath
+ the configuration path, which should be opened.
+ Its further used as out parameter too, so we can return the localized
+ path to the calli!
+
+ @param eMode
+ the open mode (READ/READWRITE)
+
+ @param bShare
+ force using of the share layer instead of the user layer.
+
+ @param aLocale
+ [IN ] contains the start locale for searching localized sub dirs.
+ [OUT] contains the locale of a found localized sub dir
+
+ @param bAllowFallback
+ enable/disable fallback handling for locales
+
+ @return An opened storage in case method was successfully - null otherwise.
+ */
+ css::uno::Reference< css::embed::XStorage > impl_openLocalizedPathIgnoringErrors(::rtl::OUString& sPath ,
+ sal_Int32 eMode ,
+ sal_Bool bShare ,
+ ::comphelper::Locale& aLocale ,
+ sal_Bool bAllowFallback);
+
+ //---------------------------------------
+ /** @short returns the names of all sub storages of specified storage.
+
+ @param xFolder
+ the base storage for this operation.
+
+ @return [vector< string >]
+ a list of folder names.
+ */
+ ::std::vector< ::rtl::OUString > impl_getSubFolderNames(const css::uno::Reference< css::embed::XStorage >& xFolder);
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_ACCELERATORS_PRESETHANDLER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/storageholder.hxx b/framework/source/inc/accelerators/storageholder.hxx
new file mode 100644
index 000000000000..741e9718e2d6
--- /dev/null
+++ b/framework/source/inc/accelerators/storageholder.hxx
@@ -0,0 +1,260 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_ACCELERATORS_STORAGEHOLDER_HXX_
+#define __FRAMEWORK_ACCELERATORS_STORAGEHOLDER_HXX_
+
+//===============================================
+// own includes
+
+#include <accelerators/istoragelistener.hxx>
+#include <threadhelp/threadhelpbase.hxx>
+#include <general.h>
+#include <stdtypes.h>
+
+//===============================================
+// interface includes
+
+#include <com/sun/star/embed/XStorage.hpp>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//===============================================
+// other includes
+
+
+//===============================================
+// namespace
+
+namespace framework
+{
+
+#ifdef css
+ #error "Who defines css? I will use it as namespace alias inside header."
+#else
+ #define css ::com::sun::star
+#endif
+
+//===============================================
+// definitions
+
+//-----------------------------------------------
+/**
+ TODO document me
+ */
+class StorageHolder : private ThreadHelpBase // attention! Must be the first base class to guarentee right initialize lock ...
+{
+ //-------------------------------------------
+ // types
+ public:
+
+ /** @short TODO */
+ typedef ::std::vector< css::uno::Reference< css::embed::XStorage > > TStorageList;
+
+ typedef ::std::vector< IStorageListener* > TStorageListenerList;
+
+ struct TStorageInfo
+ {
+ public:
+ css::uno::Reference< css::embed::XStorage > Storage;
+ sal_Int32 UseCount;
+ TStorageListenerList Listener;
+
+ TStorageInfo()
+ : UseCount(0)
+ {}
+ };
+
+ /** @short TODO */
+ typedef ::boost::unordered_map< ::rtl::OUString ,
+ TStorageInfo ,
+ ::rtl::OUStringHash ,
+ ::std::equal_to< ::rtl::OUString > > TPath2StorageInfo;
+
+ //-------------------------------------------
+ // member
+ private:
+
+ /** @short TODO */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ /** @short TODO */
+ css::uno::Reference< css::embed::XStorage > m_xRoot;
+
+ /** @short TODO */
+ TPath2StorageInfo m_lStorages;
+
+ //-------------------------------------------
+ // interface
+ public:
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ StorageHolder();
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ StorageHolder(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual ~StorageHolder();
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual void forgetCachedStorages();
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual void setRootStorage(const css::uno::Reference< css::embed::XStorage >& xRoot);
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual css::uno::Reference< css::embed::XStorage > getRootStorage() const;
+
+ //---------------------------------------
+ /** @short TODO
+ open or get!
+ */
+ virtual css::uno::Reference< css::embed::XStorage > openPath(const ::rtl::OUString& sPath ,
+ sal_Int32 nOpenMode);
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual StorageHolder::TStorageList getAllPathStorages(const ::rtl::OUString& sPath);
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual void commitPath(const ::rtl::OUString& sPath);
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual void closePath(const ::rtl::OUString& sPath);
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual void notifyPath(const ::rtl::OUString& sPath);
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual void addStorageListener( IStorageListener* pListener,
+ const ::rtl::OUString& sPath );
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual void removeStorageListener( IStorageListener* pListener,
+ const ::rtl::OUString& sPath );
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual ::rtl::OUString getPathOfStorage(const css::uno::Reference< css::embed::XStorage >& xStorage);
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual css::uno::Reference< css::embed::XStorage > getParentStorage(const css::uno::Reference< css::embed::XStorage >& xChild);
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ virtual css::uno::Reference< css::embed::XStorage > getParentStorage(const ::rtl::OUString& sChildPath);
+
+ //---------------------------------------
+ /** @short TODO
+ */
+ void operator=(const StorageHolder& rCopy);
+
+ //---------------------------------------
+ /** @short opens a sub element of the specified base storage.
+
+ @descr First this method try to open the requested sub element
+ using the given open mode. If it failed there is second step,
+ which tries to do the same again ... but removing a might existing
+ WRITE flag from the open mode. The user can supress this fallback
+ handling by setting the parameter bAllowFallback to sal_False.
+
+ @param xBaseStorage
+ the storage, where the sub element should be searched.
+
+ @param sSubElement
+ the full name of the sub element.
+ e.g. "default.xml"
+
+ @param eOpenMode
+ a flag field, which set the open mode for this operation.
+
+ @param bAllowFallback
+ if eOpenMode contains an ELEMENT_WRITE flag this parameter
+ allow to remove it and try it with the rest of eOpenMode flags
+ again.
+ */
+ static css::uno::Reference< css::embed::XStorage > openSubStorageWithFallback(const css::uno::Reference< css::embed::XStorage >& xBaseStorage ,
+ const ::rtl::OUString& sSubStorage ,
+ sal_Int32 eOpenMode ,
+ sal_Bool bAllowFallback);
+
+ static css::uno::Reference< css::io::XStream > openSubStreamWithFallback(const css::uno::Reference< css::embed::XStorage >& xBaseStorage ,
+ const ::rtl::OUString& sSubStream ,
+ sal_Int32 eOpenMode ,
+ sal_Bool bAllowFallback);
+
+ //---------------------------------------
+ // helper
+ private:
+
+ //-----------------------------------
+ /** @short TODO
+ */
+ static ::rtl::OUString impl_st_normPath(const ::rtl::OUString& sPath);
+
+ //-----------------------------------
+ /** @short TODO
+ */
+ static OUStringList impl_st_parsePath(const ::rtl::OUString& sPath);
+};
+
+#undef css // dont let it out!
+
+} // namespace framework
+
+#endif // __FRAMEWORK_ACCELERATORS_STORAGEHOLDER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/constant/containerquery.hxx b/framework/source/inc/constant/containerquery.hxx
new file mode 100644
index 000000000000..050fde2e128f
--- /dev/null
+++ b/framework/source/inc/constant/containerquery.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_CONSTANT_CONTAINERQUERY_H_
+#define __FRAMEWORK_CONSTANT_CONTAINERQUERY_H_
+
+#include <sal/types.h>
+
+namespace framework{
+ namespace constant{
+
+struct ContainerQuery
+{
+ public:
+
+ static const sal_Unicode SEPERATOR_PARAM;
+ static const sal_Unicode SEPERATOR_VALUE;
+};
+
+ } // namespace constant
+} // namespace framework
+
+#endif // #ifndef __FRAMEWORK_CONSTANT_CONTAINERQUERY_H_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/constant/contenthandler.hxx b/framework/source/inc/constant/contenthandler.hxx
new file mode 100644
index 000000000000..19eabc22719e
--- /dev/null
+++ b/framework/source/inc/constant/contenthandler.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_CONSTANT_CONTENTHANDLER_H_
+#define __FRAMEWORK_CONSTANT_CONTENTHANDLER_H_
+
+#include <rtl/ustring.hxx>
+
+namespace framework{
+ namespace constant{
+
+struct ContentHandler
+{
+ public:
+
+ static const ::rtl::OUString PROP_NAME;
+ static const ::rtl::OUString PROP_TYPES;
+};
+
+ } // namespace constant
+} // namespace framework
+
+#endif // #ifndef __FRAMEWORK_CONSTANT_CONTENTHANDLER_H_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/constant/frameloader.hxx b/framework/source/inc/constant/frameloader.hxx
new file mode 100644
index 000000000000..1db45dddc5ba
--- /dev/null
+++ b/framework/source/inc/constant/frameloader.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_CONSTANT_FRAMELOADER_H_
+#define __FRAMEWORK_CONSTANT_FRAMELOADER_H_
+
+#include <rtl/ustring.hxx>
+
+namespace framework{
+ namespace constant{
+
+class FrameLoader
+{
+ public:
+
+ static const ::rtl::OUString PROP_NAME; // string
+ static const ::rtl::OUString PROP_TYPES; // seq< string >
+};
+
+ } // namespace constant
+} // namespace framework
+
+#endif // #ifndef __FRAMEWORK_CONSTANT_FRAMELOADER_H_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/dispatch/loaddispatcher.hxx b/framework/source/inc/dispatch/loaddispatcher.hxx
new file mode 100644
index 000000000000..bc4b95fcd3d4
--- /dev/null
+++ b/framework/source/inc/dispatch/loaddispatcher.hxx
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_DISPATCH_LOADDISPATCHER_HXX_
+#define __FRAMEWORK_DISPATCH_LOADDISPATCHER_HXX_
+
+//_______________________________________________
+// my own includes
+
+#include <loadenv/loadenv.hxx>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/frame/XNotifyingDispatch.hpp>
+#include <com/sun/star/frame/XSynchronousDispatch.hpp>
+
+//_______________________________________________
+// other includes
+
+#include <cppuhelper/implbase2.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// exported const
+
+//_______________________________________________
+// exported definitions
+
+/** @short implements a dispatch object which can be used to load
+ non-visible components (by using the mechanism of ContentHandler)
+ or visible-components (by using the mechanism of FrameLoader).
+
+ @author as96863
+ */
+class LoadDispatcher : private ThreadHelpBase
+ , public ::cppu::WeakImplHelper2< css::frame::XNotifyingDispatch, // => XDispatch => XInterface
+ css::frame::XSynchronousDispatch >
+{
+ //___________________________________________
+ // member
+
+ private:
+
+ /** @short can be used to create own needed services on demand. */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ /** @short TODO document me */
+ css::uno::WeakReference< css::frame::XFrame > m_xOwnerFrame;
+
+ /** @short TODO document me */
+ ::rtl::OUString m_sTarget;
+
+ /** @short TODO document me */
+ sal_Int32 m_nSearchFlags;
+
+ /** @short TODO document me */
+ LoadEnv m_aLoader;
+
+ //___________________________________________
+ // native interface
+
+ public:
+
+ /** @short creates a new instance and initialize it with all neccessary parameters.
+
+ @descr Every instance of such LoadDispatcher can be used for the specified context only.
+ That means: It can be used to load any further requested content into tzhe here(!)
+ specified target frame.
+
+ @param xSMGR
+ will be used to create own needed services on demand.
+
+ @param xOwnerFrame
+ used as startpoit to locate the right target frame.
+
+ @param sTargetName
+ the name or the target frame for loading or a special qualifier
+ which define such target.
+
+ @param nSearchFlags
+ used in case sTargetFrame isnt a special one.
+ */
+ LoadDispatcher(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xOwnerFrame ,
+ const ::rtl::OUString sTargetName ,
+ sal_Int32 nSearchFlags);
+
+ //_______________________________________
+
+ /** @short used to free internal resources.
+ */
+ virtual ~LoadDispatcher();
+
+ //___________________________________________
+ // uno interface
+
+ public:
+
+ // XNotifyingDispatch
+ virtual void SAL_CALL dispatchWithNotification(const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
+ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
+ throw(css::uno::RuntimeException);
+
+ // XDispatch
+ virtual void SAL_CALL dispatch(const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
+ const css::util::URL& aURL )
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
+ const css::util::URL& aURL )
+ throw(css::uno::RuntimeException);
+
+ // XSynchronousDispatch
+ virtual css::uno::Any SAL_CALL dispatchWithReturnValue( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
+ throw( css::uno::RuntimeException );
+
+ private:
+ css::uno::Any impl_dispatch( const css::util::URL& rURL,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
+ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener );
+}; // class LoadDispatcher
+
+} // namespace framework
+
+#endif // #ifndef __FRAMEWORK_DISPATCH_LOADDISPATCHER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/dispatch/uieventloghelper.hxx b/framework/source/inc/dispatch/uieventloghelper.hxx
new file mode 100644
index 000000000000..90df4943d9f6
--- /dev/null
+++ b/framework/source/inc/dispatch/uieventloghelper.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_DISPATCH_UIEVENTLOGHELPER_HXX_
+#define __FRAMEWORK_DISPATCH_UIEVENTLOGHELPER_HXX_
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <comphelper/uieventslogger.hxx>
+#include <rtl/ustring.hxx>
+#include <services.h>
+
+namespace framework
+{
+ class UiEventLogHelper
+ {
+ public:
+ UiEventLogHelper(const ::rtl::OUString& aWidgetname)
+ : m_aWidgetName(aWidgetname)
+ , m_hasAppName(false)
+ { }
+
+ void log(const ::com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rServiceManager,
+ const ::com::sun::star::uno::Reference< com::sun::star::uno::XInterface >& rModel,
+ const ::com::sun::star::util::URL& rUrl,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& rArgs)
+ {
+
+ if(!m_hasAppName && rServiceManager.is() && rModel.is())
+ {
+ try
+ {
+ static ::rtl::OUString our_aModuleManagerName = SERVICENAME_MODULEMANAGER;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager > xModuleManager(
+ rServiceManager->createInstance(our_aModuleManagerName)
+ , ::com::sun::star::uno::UNO_QUERY_THROW);
+ m_aAppName = xModuleManager->identify(rModel);
+ m_hasAppName = true;
+ } catch(::com::sun::star::uno::Exception&) {}
+ }
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue> aArgsWithOrigin(rArgs);
+ ::comphelper::UiEventsLogger::appendDispatchOrigin(aArgsWithOrigin, m_aAppName, m_aWidgetName);
+ ::comphelper::UiEventsLogger::logDispatch(rUrl, aArgsWithOrigin);
+ }
+
+ private:
+ const ::rtl::OUString m_aWidgetName;
+ bool m_hasAppName;
+ ::rtl::OUString m_aAppName;
+ };
+}
+
+#endif // __FRAMEWORK_DISPATCH_UIEVENTLOGHELPER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/dispatch/windowcommanddispatch.hxx b/framework/source/inc/dispatch/windowcommanddispatch.hxx
new file mode 100644
index 000000000000..549c6d9e69ae
--- /dev/null
+++ b/framework/source/inc/dispatch/windowcommanddispatch.hxx
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_DISPATCH_WINDOWCOMMANDDISPATCH_HXX_
+#define __FRAMEWORK_DISPATCH_WINDOWCOMMANDDISPATCH_HXX_
+
+//_______________________________________________
+// my own includes
+
+#include <threadhelp/threadhelpbase.hxx>
+
+//_______________________________________________
+// interface includes
+
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//_______________________________________________
+// other includes
+
+#include <cppuhelper/implbase1.hxx>
+#include <tools/link.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+namespace css = ::com::sun::star;
+
+//_______________________________________________
+// exported const
+
+//_______________________________________________
+// exported definitions
+
+/** @short internal helper to bind e.g. MAC-Menu events to our internal dispatch API.
+
+ @descr On e.g. MAC platform system menus are merged together with some fix entries as
+ e.g. "Pereferences" or "About". These menu entries trigger hard coded commands.
+ Here we map these commands to the right URLs and dispatch them.
+
+ This helper knows a frame and its container window (where VCL provide the hard coded
+ commands). We hold those objects weak so there is no need to react for complex UNO dispose/ing()
+ scenarios. On the other side VCL does not hold us alive (because it doesn't know our UNO reference).
+ So we register at the VCL level as an event listener and
+ */
+class WindowCommandDispatch : private ThreadHelpBase
+{
+ //___________________________________________
+ // const
+
+ private:
+
+ /// dispatch URL to trigger our "Tools->Options" dialog
+ static const ::rtl::OUString COMMAND_PREFERENCES;
+
+ /// dispatch URL to trigger our About box
+ static const ::rtl::OUString COMMAND_ABOUTBOX;
+
+ //___________________________________________
+ // member
+
+ private:
+
+ /// can be used to create own needed services on demand.
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ /// knows the frame, where we dispatch our commands as weak reference
+ css::uno::WeakReference< css::frame::XFrame > m_xFrame;
+
+ /// knows the VCL window (where the hard coded commands occurred) as weak XWindow reference
+ css::uno::WeakReference< css::awt::XWindow > m_xWindow;
+
+ //___________________________________________
+ // native interface
+
+ public:
+
+ //_______________________________________
+
+ /** @short creates a new instance and initialize it with all necessary parameters.
+
+ @descr Every instance of such MACDispatch can be used for the specified context only.
+ Means: 1 MACDispatch object is bound to 1 Frame/Window pair in which context
+ the detected commands will be executed.
+
+ @param xSMGR
+ will be used to create own needed services on demand.
+
+ @param xFrame
+ used as for new detected commands.
+ */
+ WindowCommandDispatch(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const css::uno::Reference< css::frame::XFrame >& xFrame);
+
+ //_______________________________________
+
+ /** @short used to free internal resources.
+ */
+ virtual ~WindowCommandDispatch();
+
+ //___________________________________________
+ // implementation
+
+ private:
+
+ //_______________________________________
+
+ /** @short establish all listener connections we need.
+
+ @descr Those listener connections will be created one times only (see ctor).
+ Afterwards we listen for incoming events till our referred frame/window pair
+ will be closed.
+ */
+ void impl_startListening();
+
+ /** @short drop all listener connections we need.
+
+ */
+ void impl_stopListening();
+
+ //_______________________________________
+
+ /** @short callback from VCL to notify new commands
+ */
+ DECL_LINK( impl_notifyCommand, void* );
+
+ //_______________________________________
+
+ /** @short dispatch right command URLs into our frame context.
+
+ @param sCommand
+ the command for dispatch
+ */
+ void impl_dispatchCommand(const ::rtl::OUString& sCommand);
+
+}; // class MACDispatch
+
+} // namespace framework
+
+#endif // #ifndef __FRAMEWORK_DISPATCH_MACDISPATCH_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/loadenv/actionlockguard.hxx b/framework/source/inc/loadenv/actionlockguard.hxx
new file mode 100644
index 000000000000..da72daebdaec
--- /dev/null
+++ b/framework/source/inc/loadenv/actionlockguard.hxx
@@ -0,0 +1,212 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_LOADENV_ACTIONLOCKGUARD_HXX_
+#define __FRAMEWORK_LOADENV_ACTIONLOCKGUARD_HXX_
+
+//_______________________________________________
+// includes of own project
+
+#include <threadhelp/threadhelpbase.hxx>
+#include <threadhelp/resetableguard.hxx>
+
+//_______________________________________________
+// includes of uno interface
+#include <com/sun/star/document/XActionLockable.hpp>
+
+//_______________________________________________
+// includes of an other project
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+#ifndef css
+namespace css = ::com::sun::star;
+#endif
+
+//_______________________________________________
+// definitions
+
+/** @short implements a guard, which can use the interface
+ <type scope="com::sun::star::document">XActionLockable</type>.
+
+ @descr This guard should be used to be shure, that any lock will be
+ released. Otherwhise the locaked document can hinder the office on shutdown!
+*/
+class ActionLockGuard : private ThreadHelpBase
+{
+ //-------------------------------------------
+ // member
+
+ private:
+
+ /** @short points to the object, which can be locked from outside. */
+ css::uno::Reference< css::document::XActionLockable > m_xActionLock;
+
+ /** @short knows if a lock exists on the internal lock object
+ forced by this guard instance. */
+ sal_Bool m_bActionLocked;
+
+ //-------------------------------------------
+ // interface
+
+ public:
+
+ //---------------------------------------
+ /** @short default ctor to initialize a "non working guard".
+
+ @descr That can be usefull in cases, where no resource still exists,
+ but will be available next time. Then this guard can be used
+ in a mode "use guard for more then one resources".
+ */
+ ActionLockGuard()
+ : ThreadHelpBase ( )
+ , m_bActionLocked(sal_False)
+ {
+ }
+
+ //---------------------------------------
+ /** @short initialize new guard instance and lock the given resource immediatly.
+
+ @param xLock
+ points to the outside resource, which should be locked.
+ */
+ ActionLockGuard(const css::uno::Reference< css::document::XActionLockable >& xLock)
+ : ThreadHelpBase ( )
+ , m_bActionLocked(sal_False)
+ {
+ setResource(xLock);
+ }
+
+ //---------------------------------------
+ /** @short release this guard instance and make shure, that no lock
+ will exist afterwards on the internal wrapped resource.
+ */
+ virtual ~ActionLockGuard()
+ {
+ unlock();
+ }
+
+ //---------------------------------------
+ /** @short set a new resource for locking at this guard.
+
+ @descr This call will fail, if an internal resource already exists
+ and is currently locked.
+
+ @param xLock
+ points to the outside resource, which should be locked.
+
+ @return sal_True, if new resource could be set and locked.
+ sal_False otherwhise.
+ */
+ virtual sal_Bool setResource(const css::uno::Reference< css::document::XActionLockable >& xLock)
+ {
+ // SAFE -> ..........................
+ ResetableGuard aMutexLock(m_aLock);
+
+ if (m_bActionLocked || !xLock.is())
+ return sal_False;
+
+ m_xActionLock = xLock;
+ m_xActionLock->addActionLock();
+ m_bActionLocked = m_xActionLock->isActionLocked();
+ // <- SAFE ..........................
+
+ return sal_True;
+ }
+
+ //---------------------------------------
+ /** @short set a new resource for locking at this guard.
+
+ @descr This call will fail, if an internal resource already exists
+ and is currently locked.
+
+ @param xLock
+ points to the outside resource, which should be locked.
+
+ @return sal_True, if new resource could be set and locked.
+ sal_False otherwhise.
+ */
+ virtual void freeResource()
+ {
+ // SAFE -> ..........................
+ ResetableGuard aMutexLock(m_aLock);
+
+ css::uno::Reference< css::document::XActionLockable > xLock = m_xActionLock ;
+ sal_Bool bLocked = m_bActionLocked;
+
+ m_xActionLock.clear();
+ m_bActionLocked = sal_False;
+
+ aMutexLock.unlock();
+ // <- SAFE ..........................
+
+ if (bLocked && xLock.is())
+ xLock->removeActionLock();
+ }
+
+ //---------------------------------------
+ /** @short lock the internal wrapped resource, if its not already done. */
+ virtual void lock()
+ {
+ // SAFE -> ..........................
+ ResetableGuard aMutexLock(m_aLock);
+
+ if (!m_bActionLocked && m_xActionLock.is())
+ {
+ m_xActionLock->addActionLock();
+ m_bActionLocked = m_xActionLock->isActionLocked();
+ }
+ // <- SAFE ..........................
+ }
+
+ //---------------------------------------
+ /** @short unlock the internal wrapped resource, if its not already done. */
+ virtual void unlock()
+ {
+ // SAFE -> ..........................
+ ResetableGuard aMutexLock(m_aLock);
+
+ if (m_bActionLocked && m_xActionLock.is())
+ {
+ m_xActionLock->removeActionLock();
+ // dont check for any locks here ...
+ // May another guard use the same lock object :-(
+ m_bActionLocked = sal_False;
+ }
+ // <- SAFE ..........................
+ }
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_LOADENV_ACTIONLOCKGUARD_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/loadenv/loadenv.hxx b/framework/source/inc/loadenv/loadenv.hxx
new file mode 100644
index 000000000000..f2f3b3f08dcc
--- /dev/null
+++ b/framework/source/inc/loadenv/loadenv.hxx
@@ -0,0 +1,703 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef __FRAMEWORK_LOADENV_LOADENV_HXX_
+#define __FRAMEWORK_LOADENV_LOADENV_HXX_
+
+//_______________________________________________
+// includes of own project
+
+#include <loadenv/loadenvexception.hxx>
+#include <loadenv/actionlockguard.hxx>
+#include <threadhelp/threadhelpbase.hxx>
+
+//_______________________________________________
+// includes of uno interface
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/XFrameLoader.hpp>
+#include <com/sun/star/frame/XLoadEventListener.hpp>
+#include <com/sun/star/frame/XDispatchResultListener.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/util/URL.hpp>
+
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include <com/sun/star/io/IOException.hpp>
+
+//_______________________________________________
+// includes of an other project
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+namespace css = ::com::sun::star;
+class QuietInteraction;
+//_______________________________________________
+// definitions
+
+/** @short implements general mechainsm for loading documents.
+
+ @descr An instance of this class can be used inside the API calls
+ XComponentLoader::loadComponentFromURL() and XDispatch::dispatch()
+ (of course in its derived interfaces too :-)).
+
+ @author as96863
+ */
+class LoadEnv : private ThreadHelpBase
+{
+ //___________________________________________
+ // structs, types, etc.
+
+ public:
+
+ /** @short enable/disable special features
+ of a load request.
+
+ @desrc Such features must outcome without
+ any special parameters.
+ To make enableing/disabling of
+ features very easy (e.g. at the ctor of
+ this class) these values must be combinable
+ as flags. That means: its values must be in
+ range of [2^n]!
+ */
+ enum EFeature
+ {
+ /// we should be informed, if no feature is enabled :-)
+ E_NO_FEATURE = 0,
+ /// enable using of UI elements during loading (means progress, interaction handler etcpp.)
+ E_WORK_WITH_UI = 1,
+ /// enable loading of resources, which are not related to a target frame! (see concept of ContentHandler)
+ E_ALLOW_CONTENTHANDLER = 2
+ };
+
+ //_______________________________________
+
+ /** @short classify a content.
+
+ @descr The load environment must know, if a content
+ is related to a target frame or not. Only "visible"
+ components, which full fill the requirements of the
+ model-controller-view paradigm can be loaded into a frame.
+ Such contents are classified as E_CAN_BE_LOADED.
+
+ But e.g. for the dispatch framework exists special ContentHandler
+ objects, which can load a content in "non visible" mode ...
+ and do not need a target frame for its operation. Such
+ ContentHandler e.g. plays sounds.
+ Such contents are classified as E_CAN_BE_HANDLED.
+
+ And last but not least a content can be "not valid" in general.
+ */
+ enum EContentType
+ {
+ /// identifies a content, which seems to be invalid in general
+ E_UNSUPPORTED_CONTENT,
+ /// identifies a content, which can be used with a ContentHandler and is not related to a target frame
+ E_CAN_BE_HANDLED,
+ /// identifies a content, which can be loaded into a target frame
+ E_CAN_BE_LOADED,
+ /// special mode for non real loading, In such case the model is given directly!
+ E_CAN_BE_SET
+ };
+
+ //___________________________________________
+ // member
+
+ private:
+
+ /** @short reference to an uno service manager, which must be used
+ to created on needed services on demand.
+ */
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+
+ /** @short points to the frame, which uses this LoadEnv object
+ and must be used to start target search there.
+ */
+ css::uno::Reference< css::frame::XFrame > m_xBaseFrame;
+
+ /** @short points to the frame, into which the new component was loaded.
+
+ @descr Note: This reference will be empty if loading failed
+ or a non visible content was loaded!
+ It can be the same frame as m_xBaseFrame it describe, in case
+ the target "_self", "" or the search flag "SELF" was used.
+ Otherwhise its the new created or recycled frame, which was
+ used for loading and contains further the new component.
+
+ Please use method getTarget() or getTargetComponent()
+ to return the frame/controller or model to any interested
+ user of the results of this load request.
+ */
+ css::uno::Reference< css::frame::XFrame > m_xTargetFrame;
+
+ /** @short contains the name of the target, in which the specified resource
+ of this instance must be loaded.
+ */
+ ::rtl::OUString m_sTarget;
+
+ /** @short if m_sTarget is not a special one, this flags regulate searching
+ of a suitable one.
+ */
+ sal_Int32 m_nSearchFlags;
+
+ /** @short contains all needed informations about the resource,
+ which should be loaded.
+
+ @descr Inside this struct e.g. the URL, its type and filter name,
+ the stream or a model directly are saved.
+ */
+ ::comphelper::MediaDescriptor m_lMediaDescriptor;
+
+ /** @short because the mediadescriptor contains the complete URL ... but
+ some functionality need the structured version, we hold it twice :-(.
+ */
+ css::util::URL m_aURL;
+
+ /** @short enable/disable special features of a load request. */
+ EFeature m_eFeature;
+
+ /** @short classify the content, which should be loaded by this instance. */
+ EContentType m_eContentType;
+
+ /** @short it indicates, that the member m_xTargetFrame was new created for this
+ load request and must be closed in case loading (not handling!)
+ operation failed. The default value is sal_False!
+ */
+ sal_Bool m_bCloseFrameOnError;
+
+ /** @short it indicates, that the old document (which was located inside m_xBaseFrame
+ in combination with the m_sTarget value "_self") was suspended.
+ Normaly it will be replaced by the new loaded document. But in case
+ loading (not handling!) failed, it must be reactivated.
+ The default value is sal_False!
+ */
+ sal_Bool m_bReactivateControllerOnError;
+
+ /** @short it holds one (!) asynchronous used contenthandler or frameloader
+ alive, till the asynchronous operation will be finished.
+ */
+ css::uno::Reference< css::uno::XInterface > m_xAsynchronousJob;
+
+ /** @short holds the information about the finished load process.
+
+ @descr The content of m_xTargetFrame cant be used as valid indicator,
+ (in case the micht existing old document was reactivated)
+ we must hold the result of the load process explicitly.
+ */
+ sal_Bool m_bLoaded;
+
+ /** @short holds an XActionLock on the internal used task member.
+
+ @seealso m_xTargetFrame
+ */
+ ActionLockGuard m_aTargetLock;
+
+ /** TODO document me ... */
+ void* m_pCheck;
+
+ QuietInteraction* m_pQuietInteraction;
+
+ //___________________________________________
+ // native interface
+
+ public:
+
+ /** @short initialize a new instance of this load environment.
+
+ @param xSMGR
+ reference to an uno service manager, which can be used internaly
+ to create on needed services on demand.
+
+ @throw Currently there is no reason to throw such exception!
+
+ @throw A RuntimeException in case any internal process indicates, that
+ the whole runtime cant be used any longer.
+ */
+ LoadEnv(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+
+ /** @short deinitialize an instance of this class in the right way.
+ */
+ virtual ~LoadEnv();
+
+ //_______________________________________
+
+ /** @short DRAFT TODO
+ */
+ static css::uno::Reference< css::lang::XComponent > loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader,
+ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const ::rtl::OUString& sURL ,
+ const ::rtl::OUString& sTarget,
+ sal_Int32 nFlags ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArgs )
+ throw(css::lang::IllegalArgumentException,
+ css::io::IOException ,
+ css::uno::RuntimeException );
+
+ //_______________________________________
+
+ /** @short set some changeable parameters for a new load request.
+
+ @descr The parameter for targeting, the content description, and
+ some environment specifier (UI, dispatch functionality)
+ can be set here ... BEFORE the real load process is started
+ by calling startLoading(). Of course a still running load request
+ will be detected here and a suitable exception will be thrown.
+ Such constellation can be detected outside by using provided
+ synchronisation methods or callbacks.
+
+ @param sURL
+ points to the resource, which should be loaded.
+
+ @param lMediaDescriptor
+ contains additional informations for the following load request.
+
+ @param xBaseFrame
+ points to the frame which must be used as start point for target search.
+
+ @param sTarget
+ regulate searching/creating of frames, which should contain the
+ new loaded component afterwards.
+
+ @param nSearchFlags
+ regulate searching of targets, if sTarget is not a special one.
+
+ @param eFeature
+ flag field, which enable/disable special features of this
+ new instance for following load call.
+
+ @param eContentType
+ classify the given content.
+ This value is set to a default value "UNKNWON_CONTENT", which force
+ an internal check, if this content is loadable or not.
+ But may this check was already made by the caller of this method and
+ passing this information to this LoadEnv instance can supress this
+ might expensive check.
+ That can be usefull in case this information is needed outside too,
+ to decide if its neccessary to create some resources for this load
+ request ... or to reject the request imidiatly if it seems to be not
+ loadable in general.
+
+ @throw A LoadEnvException e.g. if another load operation is till in progress
+ or initialization of a new one fail by other reasons.
+ The real reason, a suitable message and ID will be given here immidiatly.
+
+ @throw A RuntimeException in case any internal process indicates, that
+ the whole runtime cant be used any longer.
+ */
+ virtual void initializeLoading(const ::rtl::OUString& sURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor,
+ const css::uno::Reference< css::frame::XFrame >& xBaseFrame ,
+ const ::rtl::OUString& sTarget ,
+ sal_Int32 nSearchFlags ,
+ EFeature eFeature = E_NO_FEATURE ,
+ EContentType eContentType = E_UNSUPPORTED_CONTENT)
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+
+ /** @short start loading of the resource represented by this loadenv instance.
+
+ @descr There is no direct return value possible here. Because it depends
+ from the usage of this instance! E.g. for loading a "visible component"
+ a frame with a controller/model inside can be possible. For loading
+ of a "non visible component" only an information about a successfully start
+ can be provided.
+ Further it cant be guranteed, that the internal process runs synchronous.
+ Thats why we preferr using of specialized methods afterwards e.g. to:
+ - wait till the internal job will be finished
+ and get the results
+ - or to let it run without any further control from outside.
+
+ @throw A LoadEnvException if start of the load process failed (because
+ another is still in progress!).
+ The reason, a suitable message and ID will be given here immidiatly.
+
+ @throw A RuntimeException in case any internal process indicates, that
+ the whole runtime cant be used any longer.
+ */
+ virtual void startLoading()
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+
+ /** @short wait for an alreay running load request (started by calling
+ startLoading() before).
+
+ @descr The timeout parameter can be used to wait some times only
+ or forever. The return value indicates if the load request
+ was finished during the specified timeout period.
+ But it indicates not, if the load request was successfully or not!
+
+ @param nTimeout
+ specify a timeout in [ms].
+ A value 0 let it wait forever!
+
+ @return sal_True if the started load process could be finished in time;
+ sal_False if the specified time was over.
+
+ @throw ... currently not used :-)
+
+ @throw A RuntimeException in case any internal process indicates, that
+ the whole runtime cant be used any longer.
+ */
+ virtual sal_Bool waitWhileLoading(sal_uInt32 nTimeout = 0)
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+ /** TODO document me ... */
+ virtual void cancelLoading()
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+ /** TODO document me ... */
+ virtual css::uno::Reference< css::frame::XFrame > getTarget() const;
+
+ //_______________________________________
+ /** TODO document me ... */
+ virtual css::uno::Reference< css::lang::XComponent > getTargetComponent() const;
+/*
+ //___________________________________________
+ // helper uno interface!
+ // You have to use the native interface only!
+
+ public:
+
+ //_______________________________________
+ // frame.XLoadEventListener
+ virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
+ throw(css::uno::RuntimeException);
+
+ //_______________________________________
+ // frame.XDispatchResultListener
+ virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
+ throw(css::uno::RuntimeException);
+
+ //_______________________________________
+ // lang.XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException);
+*/
+
+ //___________________________________________
+ // static interface
+
+ public:
+
+ /** @short checks if the specified content can be handled by a
+ ContentHandler only and is not related to a target frame,
+ or if it can be loaded by a FrameLoader into a target frame
+ as "visible" component.
+
+ @descr using:
+ switch(classifyContent(...))
+ {
+ case E_CAN_BE_HANDLED :
+ handleIt(...);
+ break;
+
+ case E_CAN_BE_LOADED :
+ xFrame = locateTargetFrame();
+ loadIt(xFrame);
+ break;
+
+ case E_NOT_A_CONTENT :
+ default : throw ...;
+ }
+
+ @param sURL
+ describe the content.
+
+ @param lMediaDescriptor
+ describe the content more detailed!
+
+ @return A suitable enum value, which classify the specified content.
+ */
+ static EContentType classifyContent(const ::rtl::OUString& sURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor);
+
+ /** TODO document me ... */
+ static void initializeUIDefaults(
+ const css::uno::Reference< css::lang::XMultiServiceFactory >& i_rSMGR,
+ ::comphelper::MediaDescriptor& io_lMediaDescriptor,
+ const bool _bUIMode,
+ QuietInteraction** o_ppQuiteInteraction
+ );
+
+ /** TODO document me ... */
+ void impl_setResult(sal_Bool bResult);
+
+ /** TODO document me ... */
+ css::uno::Reference< css::uno::XInterface > impl_searchLoader();
+
+ //_______________________________________
+
+ /** @short it means; show the frame, bring it to front,
+ might set the right icon etcpp. in case loading was
+ successfully or reactivate a might existing old document or
+ close the frame if it was created before in case loading failed.
+
+ @throw A LoadEnvException only in cases, where an internal error indicates,
+ that the complete load environment seems to be not useable in general.
+ In such cases a RuntimeException would be to hard for the outside code :-)
+
+ @throw A RuntimeException in case any internal process indicates, that
+ the whole runtime cant be used any longer.
+ */
+ void impl_reactForLoadingState()
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //___________________________________________
+ // private helper
+
+ private:
+
+ /** @short tries to detect the type and the filter of the specified content.
+
+ @descr This method update the available media descriptor of this instance,
+ so it contains the right type, a corresponding filter, may a
+ valid frame loader etc. In case detection failed, this descriptor
+ is corrected first, before a suitable exception will be thrown.
+ (Excepting a RuntimeException occure!)
+
+ @attention Not all types we know, are supported by filters. So it does not
+ indicates an error, if no suitable filter(loader etcpp will be found
+ for a type. But a type must be detected for the specified content.
+ Otherwhise its an error and loading cant be finished successfully.
+
+ @throw A LoadEnvException if detection failed.
+
+ @throw A RuntimeException in case any internal process indicates, that
+ the whole runtime cant be used any longer.
+ */
+ void impl_detectTypeAndFilter()
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+
+ /** @short tries to ask user for it's filter decision in case
+ normal detection failed.
+
+ @descr We use a may existing interaction handler to do so.
+
+ @return [string]
+ the type selected by the user.
+
+ @attention Internaly we update the member m_lMediaDescriptor!
+ */
+ ::rtl::OUString impl_askUserForTypeAndFilterIfAllowed()
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+
+ /** @short tries to use ContentHandler objects for loading.
+
+ @descr It searches for a suitable content handler object, registered
+ for the detected content type (must be done before by calling
+ impl_detectTypeAndFilter()). Because such handler does not depend
+ from a real target frame, location of such frame will be
+ supressed here.
+ In case handle failed all new created resources will be
+ removed before a suitable exception is thrown.
+ (Excepting a RuntimeException occure!)
+
+ @return TODO
+
+ @throw A LoadEnvException if handling failed.
+
+ @throw A RuntimeException in case any internal process indicates, that
+ the whole runtime cant be used any longer.
+ */
+ sal_Bool impl_handleContent()
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+
+ /** @short tries to use FrameLoader objects for loading.
+
+ @descr First the target frame will be located. If it could be found
+ or new created a filter/frame loader will be instanciated and
+ used to load the content into this frame.
+ In case loading failed all new created resources will be
+ removed before a suitable exception is thrown.
+ (Excepting a RuntimeException occure!)
+
+ @return TODO
+
+ @throw A LoadEnvException if loading failed.
+
+ @throw A RuntimeException in case any internal process indicates, that
+ the whole runtime cant be used any longer.
+ */
+ sal_Bool impl_loadContent()
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+
+ /** @short checks if the specified content is already loaded.
+
+ @descr It depends from the set target information, if such
+ search is allowed or not! So this method checks first,
+ if the target is the special one "_default".
+ If not it returns with an empty result immidatly!
+ In case search is allowed, an existing document with the
+ same URL is searched. If it could be found, the corresponding
+ view will get the focus and this method return the corresponding frame.
+ Optional jumpmarks will be accepted here too. So the
+ view of the document will be updated to show the position
+ inside the document, which is related to the jumpmark.
+
+ @return A valid reference to the target frame, which contains the already loaded content
+ and could be activated successfully. An empty reference oterwhise.
+
+ @throw A LoadEnvException only in cases, where an internal error indicates,
+ that the complete load environment seems to be not useable in general.
+ In such cases a RuntimeException would be to hard for the outside code :-)
+
+ @throw A RuntimeException in case any internal process indicates, that
+ the whole runtime cant be used any longer.
+ */
+ css::uno::Reference< css::frame::XFrame > impl_searchAlreadyLoaded()
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+
+ /** @short search for any target frame, which seems to be useable
+ for this load request.
+
+ @descr Because this special feature is bound to the target specifier "_default"
+ its checked inside first. If its not set => this method return an empty
+ reference. Otherwhise any currently existing frame will be analyzed, if
+ it can be used here. The following rules exists:
+
+ <ul>
+ <li>The frame must be empty ...</li>
+ <li>or contains an empty document of the same application module
+ which the new document will have (Note: the filter of the new content
+ must be well known here!)</li>
+ <li>and(!) this target must not be already used by any other load request.</li>
+ </ul>
+
+ If a suitable target is located it will be locked. Thats why the last rule
+ exists! If this method returns a valid frame reference, it was locked to be useable
+ for this load request only. (Dont forget to reset this state later!)
+ Concurrent LoadEnv instances can synchronize her work be using such locks :-) HOPEFULLY
+
+ @throw A LoadEnvException only in cases, where an internal error indicates,
+ that the complete load environment seems to be not useable in general.
+ In such cases a RuntimeException would be to hard for the outside code :-)
+
+ @throw A RuntimeException in case any internal process indicates, that
+ the whole runtime cant be used any longer.
+ */
+ css::uno::Reference< css::frame::XFrame > impl_searchRecycleTarget()
+ throw(LoadEnvException, css::uno::RuntimeException);
+
+ //_______________________________________
+
+ /** @short because showing of a frame is needed more then once ...
+ it's implemented as an seperate method .-)
+
+ @descr Note: Showing of a frame is bound to a special feature ...
+ a) If we recycle any existing frame, we must bring it to front.
+ Showing of such frame isnt needed realy .. because we recycle
+ visible frames only!
+ b) If the document was already shown (e.g. by our progress implementation)
+ we do nothing here. The reason behind: The document was already shown ..
+ and it was already make a top window ...
+ If the user activated another frame inbetween (because loading needed some time)
+ it's not allowed to disturb the user again. Then the frame must resists in the background.
+ c) If the frame was not shown before ... but loading of a visible document into this frame
+ was finished ... we need both actions: setVisible() and toFront().
+
+ @param xWindow
+ points to the container window of a frame.
+
+ @param bForceToFront
+ if it's set to sal_False ... showing of the window is done more intelligent.
+ setVisible() is called only if the window was not shown before.
+ This mode is needed by b) and c)
+ If it's set to sal_True ... both actions has to be done: setVisible(), toFront()!
+ This mode is needed by a)
+ */
+ void impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow ,
+ sal_Bool bForceToFront);
+
+ //_______________________________________
+
+ /** @short checks weather a frame is already used for another load request or not.
+
+ @descr Such frames cant be used for our "recycle feature"!
+
+ @param xFrame
+ the frame, which should be checked.
+
+ @return [sal_Bool]
+ sal_True if this frame is already used for loading,
+ sal_False otherwise.
+ */
+ sal_Bool impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const;
+
+ //_______________________________________
+
+ /** @short try to determine the used application module
+ of this load request and applay right position and size
+ for this document window ... hopefully before we show it .-)
+ */
+ void impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow);
+
+ //_______________________________________
+
+ /** @short determine if it's allowed to open new document frames.
+ */
+ sal_Bool impl_furtherDocsAllowed();
+
+ //_______________________________________
+
+ /** @short jumps to the requested bookmark inside a given document.
+ */
+ void impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame,
+ const css::util::URL& aURL );
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_LOADENV_LOADENV_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/loadenv/loadenvexception.hxx b/framework/source/inc/loadenv/loadenvexception.hxx
new file mode 100644
index 000000000000..e06eef42b9db
--- /dev/null
+++ b/framework/source/inc/loadenv/loadenvexception.hxx
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_LOADENV_LOADENVEXCEPTION_HXX_
+#define __FRAMEWORK_LOADENV_LOADENVEXCEPTION_HXX_
+
+//_______________________________________________
+// includes of own project
+
+//_______________________________________________
+// includes of uno interface
+
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/uno/Exception.hpp>
+
+//_______________________________________________
+// includes of an other project
+#include <rtl/string.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+#ifndef css // conflict with define :-(
+namespace css = ::com::sun::star;
+#endif
+
+//_______________________________________________
+// definitions
+
+/** @short specify an exception, which can be used inside the
+ load environment only.
+
+ @descr Of course outside code must wrapp it, to transport
+ the occurred information to its caller.
+
+ @author as96863
+ */
+class LoadEnvException
+{
+ //___________________________________________
+ // const
+
+ public:
+
+ /** @short Can be used as an ID for an instance of a LoadEnvException.
+ @descr To prevent errors on adding/removing/changing such IDs here,
+ an enum field is used. Its int values are self organized ...
+ */
+ enum EIDs
+ {
+ /** @short The specified URL/Stream/etcpp. can not be handled by a LoadEnv instance. */
+ ID_UNSUPPORTED_CONTENT,
+
+ /** @short It was not possible to get access to global filter configuration.
+ @descr Might som neccsessary services could not be created. */
+ ID_NO_CONFIG_ACCESS,
+
+ /** @short Some data obtained from the filter configuration seems to incorrect.
+ @descr Might a filter-type relation ship seem to be damaged. */
+ ID_INVALID_FILTER_CONFIG,
+
+ /** @short indicates a corrupted media descriptor.
+ @descr Some parts are required - some other ones are optional. Such exception
+ should be thrown, if a required item does not exists. */
+ ID_INVALID_MEDIADESCRIPTOR,
+
+ /** @short Its similar to an uno::RuntimeException ....
+ @descr But such runtime exception can break the whole office code.
+ So its capsulated to this specialized load environment only.
+ Mostly it indicates a missing but needed resource ... e.g the
+ global desktop reference! */
+ ID_INVALID_ENVIRONMENT,
+
+ /** @short indicates a failed search for the right target frame. */
+ ID_NO_TARGET_FOUND,
+
+ /** @short An already existing document was found inside a target frame.
+ But its controller could not be suspended successfully. Thats
+ why the new load request was cancelled. The document could not
+ be replaced. */
+ ID_COULD_NOT_SUSPEND_CONTROLLER,
+
+ /** @short TODO */
+ ID_COULD_NOT_REACTIVATE_CONTROLLER,
+
+ /** @short inidcates an already running load operation. Of yourse the same
+ instance cant be used for multiple load requests at the same time.
+ */
+ ID_STILL_RUNNING,
+
+ /** @short sometiems we cant specify the reason for an error, because we
+ was interrupted by an called code in an unexpected way ...
+ */
+ ID_GENERAL_ERROR
+ };
+
+ //___________________________________________
+ // member
+
+ public:
+
+ /** @short contains a suitable message, which describes the reason for this
+ exception. */
+ ::rtl::OString m_sMessage;
+
+ /** @short An ID, which make this exception unique among others. */
+ sal_Int32 m_nID;
+
+ /** @short Contains the original exception, if any occurred. */
+ css::uno::Any m_exOriginal;
+
+ /** TODO
+ Experimental use! May it can be usefully to know, if an exception was already
+ catched and handled by an interaction and was might be rethrowed! */
+ sal_Bool m_bHandled;
+
+ //___________________________________________
+ // interface
+
+ public:
+
+ /** @short initialize a new instance with an ID.
+ @descr Some other items of this exception
+ (e.g. a suitable message) will be generated
+ automaticly.
+
+ @param nID
+ One of the defined const IDs of this class.
+ */
+ LoadEnvException(sal_Int32 nID)
+ {
+ m_nID = nID;
+ }
+
+ //_______________________________________
+
+ /** @short initialize a new instance with an ID
+ an wrap a detected exception into this one.
+ @descr Some other items of this exception
+ (e.g. a suitable message) will be generated
+ automaticly.
+
+ @param nID
+ One of the defined const IDs of this class.
+
+ @param exUno
+ the original catched uno exception.
+ */
+ LoadEnvException( sal_Int32 nID ,
+ const css::uno::Any& exUno)
+ {
+ m_nID = nID ;
+ m_exOriginal = exUno;
+ }
+
+ //_______________________________________
+
+ /** @short destruct an instance of this exception.
+ */
+ ~LoadEnvException()
+ {
+ m_sMessage = ::rtl::OString();
+ m_nID = 0;
+ m_bHandled = false;
+ m_exOriginal.clear();
+ }
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_LOADENV_LOADENVEXCEPTION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/loadenv/targethelper.hxx b/framework/source/inc/loadenv/targethelper.hxx
new file mode 100644
index 000000000000..17096f8087e9
--- /dev/null
+++ b/framework/source/inc/loadenv/targethelper.hxx
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_TARGETHELPER_HXX_
+#define __FRAMEWORK_TARGETHELPER_HXX_
+
+//_______________________________________________
+// own includes
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <targets.h>
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//_______________________________________________
+// definitions
+
+/** @short can be used to detect, if a target name (used e.g. for XFrame.findFrame())
+ has a special meaning or can be used as normal frame name (e.g. for XFrame.setName()).
+
+ @author as96863
+ */
+class TargetHelper
+{
+ //___________________________________________
+ // const
+
+ public:
+
+ /** @short its used at the following interfaces to classify
+ target names.
+ */
+ enum ESpecialTarget
+ {
+ E_NOT_SPECIAL ,
+ E_SELF ,
+ E_PARENT ,
+ E_TOP ,
+ E_BLANK ,
+ E_DEFAULT ,
+ E_BEAMER ,
+ E_MENUBAR ,
+ E_HELPAGENT ,
+ E_HELPTASK
+ };
+
+ //___________________________________________
+ // interface
+
+ public:
+
+ //___________________________________________
+
+ /** @short it checks the given unknown target name,
+ if it's the expected special one.
+
+ @note An empty target is similar to "_self"!
+
+ @param sCheckTarget
+ must be the unknwon target name, which should be checked.
+
+ @param eSpecialTarget
+ represent the expected target.
+
+ @return It returns <TRUE/> if <var>sCheckTarget</var> represent
+ the expected <var>eSpecialTarget</var> value; <FALSE/> otherwhise.
+ */
+ static sal_Bool matchSpecialTarget(const ::rtl::OUString& sCheckTarget ,
+ ESpecialTarget eSpecialTarget);
+
+ //___________________________________________
+
+ /** @short it checks, if the given name can be used
+ to set it at a frame using XFrame.setName() method.
+
+ @descr Because we handle special targets in a hard coded way
+ (means we do not check the real name of a frame then)
+ such named frames will never be found!
+
+ And in case such special names can exists one times only
+ by definition inside the same frame tree (e.g. _beamer and
+ OFFICE_HELP_TASK) its not a good idea to allow anything here :-)
+
+ Of course we can't check unknwon names, which are not special ones.
+ But we decide, that it's not allowed to use "_" as first sign
+ (because we reserve this letter for our own purposes!)
+ and the value must not a well known special target.
+
+ @param sName
+ the new frame name, which sould be checked.
+ */
+ static sal_Bool isValidNameForFrame(const ::rtl::OUString& sName);
+};
+
+} // namespace framework
+
+#endif // #ifndef __FRAMEWORK_TARGETHELPER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/pattern/configuration.hxx b/framework/source/inc/pattern/configuration.hxx
new file mode 100644
index 000000000000..5c46c1cbc0fc
--- /dev/null
+++ b/framework/source/inc/pattern/configuration.hxx
@@ -0,0 +1,175 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_PATTERN_CONFIGURATION_HXX_
+#define __FRAMEWORK_PATTERN_CONFIGURATION_HXX_
+
+//_______________________________________________
+// own includes
+
+#include <services.h>
+#include <general.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Any.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//_______________________________________________
+// other includes
+#include <rtl/ustrbuf.hxx>
+
+//_______________________________________________
+// namespaces
+
+#ifndef css
+namespace css = ::com::sun::star;
+#endif
+
+namespace framework{
+ namespace pattern{
+ namespace configuration{
+
+//_______________________________________________
+// definitions
+
+//-----------------------------------------------
+class ConfigurationHelper
+{
+ //-------------------------------------------
+ // const
+ public:
+
+ //---------------------------------------
+ /** @short allow opening of a configuration access
+ in different working modes.
+
+ @descr All enum values must be useable as flags
+ mapped into a int32 value!
+ */
+ enum EOpenMode
+ {
+ /// open it readonly (default=readwrite!)
+ E_READONLY = 1,
+ /// disable fallback handling for localized cfg nodes
+ E_ALL_LOCALES = 2
+ };
+
+ //-------------------------------------------
+ // interface
+ public:
+
+ //---------------------------------------
+ /**
+ @short opens a configuration access.
+
+ @descr TODO
+
+ @param xSMGR
+ this method need an uno service manager for internal work.
+
+ @param sPackage
+ name the configuration file.
+ e.g. "/.org.openoffice.Setup"
+ Note: It must start with "/" but end without(!) "/"!
+
+ @param sRelPath
+ describe the relativ path of the requested key inside
+ the specified package.
+ e.g. "Office/Factories"
+ Note: Its not allowed to start or end with a "/"!
+ Further you must use encoded path elements if
+ e.g. set nodes are involved.
+
+ @param nOpenFlags
+ force opening of the configuration access in special mode.
+ see enum EOpenMode for further informations.
+ */
+ static css::uno::Reference< css::uno::XInterface > openConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const ::rtl::OUString& sPackage ,
+ const ::rtl::OUString& sRelPath ,
+ sal_Int32 nOpenFlags)
+ {
+ css::uno::Reference< css::uno::XInterface > xCFG;
+
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
+ xSMGR->createInstance(SERVICENAME_CFGPROVIDER), css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUStringBuffer sPath(1024);
+ sPath.append(sPackage );
+ sPath.append(static_cast<sal_Unicode>('/'));
+ sPath.append(sRelPath );
+
+ sal_Bool bReadOnly = ((nOpenFlags & ConfigurationHelper::E_READONLY ) == ConfigurationHelper::E_READONLY );
+ sal_Bool bAllLocales = ((nOpenFlags & ConfigurationHelper::E_ALL_LOCALES) == ConfigurationHelper::E_ALL_LOCALES);
+
+ sal_Int32 c = 1;
+ if (bAllLocales)
+ c = 2;
+
+ css::uno::Sequence< css::uno::Any > lParams(c);
+ css::beans::PropertyValue aParam;
+
+ aParam.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath"));
+ aParam.Value <<= sPath.makeStringAndClear();
+ lParams[0] <<= aParam;
+
+ if (bAllLocales)
+ {
+ aParam.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*"));
+ aParam.Value <<= sal_True;
+ lParams[1] <<= aParam;
+ }
+
+ if (bReadOnly)
+ xCFG = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS, lParams);
+ else
+ xCFG = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGUPDATEACCESS, lParams);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { xCFG.clear(); }
+
+ return xCFG;
+ }
+};
+
+ } // namespace configuration
+ } // namespace pattern
+} // namespace framework
+
+#endif // __FRAMEWORK_PATTERN_CONFIGURATION_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/pattern/frame.hxx b/framework/source/inc/pattern/frame.hxx
new file mode 100644
index 000000000000..d112d8a2f1c4
--- /dev/null
+++ b/framework/source/inc/pattern/frame.hxx
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_PATTERN_FRAME_HXX_
+#define __FRAMEWORK_PATTERN_FRAME_HXX_
+
+//_______________________________________________
+// own includes
+
+#include <general.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+
+//_______________________________________________
+// other includes
+
+//_______________________________________________
+// namespaces
+
+#ifndef css
+namespace css = ::com::sun::star;
+#endif
+
+namespace framework{
+ namespace pattern{
+ namespace frame{
+
+//_______________________________________________
+// definitions
+
+//-----------------------------------------------
+inline css::uno::Reference< css::frame::XModel > extractFrameModel(const css::uno::Reference< css::frame::XFrame >& xFrame)
+{
+ css::uno::Reference< css::frame::XModel > xModel;
+ css::uno::Reference< css::frame::XController > xController;
+ if (xFrame.is())
+ xController = xFrame->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+ return xModel;
+}
+
+//-----------------------------------------------
+/** @short close (or dispose) the given resource.
+
+ @descr It try to close the given resource first.
+ Delegating of the ownership can be influenced from
+ outside. If closing isnt possible (because the
+ needed interface isnt available) dispose() is tried instead.
+ Al possible exception are handled inside.
+ So the user of this method has to look for the return value only.
+
+ @attention The given resource will not be cleared.
+ But later using of it can produce an exception!
+
+ @param xResource
+ the object, which should be closed here.
+
+ @param bDelegateOwnerShip
+ used at the XCloseable->close() method to define
+ the right owner in case closing failed.
+
+ @return [bool]
+ sal_True if closing failed.
+ */
+inline sal_Bool closeIt(const css::uno::Reference< css::uno::XInterface >& xResource ,
+ sal_Bool bDelegateOwnerShip)
+{
+ css::uno::Reference< css::util::XCloseable > xClose (xResource, css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XComponent > xDispose(xResource, css::uno::UNO_QUERY);
+
+ try
+ {
+ if (xClose.is())
+ xClose->close(bDelegateOwnerShip);
+ else
+ if (xDispose.is())
+ xDispose->dispose();
+ else
+ return sal_False;
+ }
+ catch(const css::util::CloseVetoException&)
+ { return sal_False; }
+ catch(const css::lang::DisposedException&)
+ {} // disposed is closed is ...
+ catch(const css::uno::RuntimeException&)
+ { throw; } // shouldnt be suppressed!
+ catch(const css::uno::Exception&)
+ { return sal_False; } // ??? We defined to return a boolen value instead of throwing exceptions ...
+ // (OK: RuntimeExceptions shouldnt be catched inside the core ..)
+
+ return sal_True;
+}
+
+ } // namespace frame
+ } // namespace pattern
+} // namespace framework
+
+#endif // __FRAMEWORK_PATTERN_FRAME_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/pattern/storages.hxx b/framework/source/inc/pattern/storages.hxx
new file mode 100644
index 000000000000..78e5bb463415
--- /dev/null
+++ b/framework/source/inc/pattern/storages.hxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_PATTERN_STORAGES_HXX_
+#define __FRAMEWORK_PATTERN_STORAGES_HXX_
+
+//_______________________________________________
+// own includes
+
+#include <services.h>
+#include <general.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XPackageStructureCreator.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//_______________________________________________
+// other includes
+
+//_______________________________________________
+// namespaces
+
+#ifndef css
+namespace css = ::com::sun::star;
+#endif
+
+namespace framework{
+ namespace pattern{
+ namespace storages{
+
+//_______________________________________________
+// definitions
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > createTempStorageBasedOnFolder(const ::rtl::OUString& sFolder ,
+ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ sal_Bool bReadOnly)
+{
+ // error during opening the temp file isnt realy a runtime error -> handle it gracefully
+ css::uno::Reference< css::io::XOutputStream > xTempFile(xSMGR->createInstance(SERVICENAME_TEMPFILE), css::uno::UNO_QUERY);
+ if (!xTempFile.is())
+ return css::uno::Reference< css::embed::XStorage >();
+
+ // creation of needed resources is mandatory -> error = runtime error
+ css::uno::Reference< css::embed::XPackageStructureCreator > xPackageCreator(xSMGR->createInstance(SERVICENAME_PACKAGESTRUCTURECREATOR), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::lang::XSingleServiceFactory > xStorageFactory(xSMGR->createInstance(SERVICENAME_STORAGEFACTORY) , css::uno::UNO_QUERY_THROW);
+
+ // create zip package
+ xPackageCreator->convertToPackage(sFolder, xTempFile);
+
+ // seek it back - so it can be used in a defined way.
+ css::uno::Reference< css::io::XSeekable > xSeekable(xTempFile, css::uno::UNO_QUERY_THROW);
+ xSeekable->seek(0);
+
+ // open the temp. zip package - using the right open mode
+ sal_Int32 nOpenMode = css::embed::ElementModes::ELEMENT_READWRITE;
+ if (bReadOnly)
+ nOpenMode = css::embed::ElementModes::ELEMENT_READ;
+
+ css::uno::Sequence< css::uno::Any > lArgs(2);
+ lArgs[0] <<= xTempFile;
+ lArgs[1] <<= nOpenMode;
+
+ css::uno::Reference< css::embed::XStorage > xStorage(xStorageFactory->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
+ return xStorage;
+}
+
+ } // namespace storages
+ } // namespace pattern
+} // namespace framework
+
+#endif // __FRAMEWORK_PATTERN_STORAGES_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/pattern/window.hxx b/framework/source/inc/pattern/window.hxx
new file mode 100644
index 000000000000..faecdaea9105
--- /dev/null
+++ b/framework/source/inc/pattern/window.hxx
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_PATTERN_WINDOW_HXX_
+#define __FRAMEWORK_PATTERN_WINDOW_HXX_
+
+//_______________________________________________
+// own includes
+
+#include <general.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+
+//_______________________________________________
+// other includes
+
+#include <toolkit/unohlp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/syswin.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/ustring.hxx>
+
+//_______________________________________________
+// namespaces
+
+#ifndef css
+namespace css = ::com::sun::star;
+#endif
+
+namespace framework{
+
+//_______________________________________________
+// definitions
+
+class WindowHelper
+{
+ public:
+
+//-----------------------------------------------
+static ::rtl::OUString getWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow)
+{
+ if (!xWindow.is())
+ return ::rtl::OUString();
+
+ ByteString sWindowState;
+ // SOLAR SAFE -> ----------------------------
+ {
+ SolarMutexGuard aSolarGuard;
+
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ // check for system window is neccessary to guarantee correct pointer cast!
+ if (pWindow!=NULL && pWindow->IsSystemWindow())
+ {
+ sal_uLong nMask = WINDOWSTATE_MASK_ALL;
+ nMask &= ~(WINDOWSTATE_MASK_MINIMIZED);
+ sWindowState = ((SystemWindow*)pWindow)->GetWindowState(nMask);
+ }
+ }
+ // <- SOLAR SAFE ----------------------------
+
+ return B2U_ENC(sWindowState,RTL_TEXTENCODING_UTF8);
+}
+
+//-----------------------------------------------
+static void setWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow ,
+ const ::rtl::OUString& sWindowState)
+{
+ if (
+ (!xWindow.is() ) ||
+ (!sWindowState.getLength())
+ )
+ return;
+
+ // SOLAR SAFE -> ----------------------------
+ SolarMutexGuard aSolarGuard;
+
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ // check for system window is neccessary to guarantee correct pointer cast!
+ if (
+ (pWindow ) &&
+ (pWindow->IsSystemWindow()) &&
+ (
+ // dont overwrite a might existing minimized mode!
+ (pWindow->GetType() != WINDOW_WORKWINDOW) ||
+ (!((WorkWindow*)pWindow)->IsMinimized() )
+ )
+ )
+ {
+ ((SystemWindow*)pWindow)->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8));
+ }
+
+ // <- SOLAR SAFE ----------------------------
+}
+
+//-----------------------------------------------
+static ::sal_Bool isTopWindow(const css::uno::Reference< css::awt::XWindow >& xWindow)
+{
+ // even child frame containing top level windows (e.g. query designer of database) will be closed
+ css::uno::Reference< css::awt::XTopWindow > xTopWindowCheck(xWindow, css::uno::UNO_QUERY);
+ if (xTopWindowCheck.is())
+ {
+ // Note: Toolkit interface XTopWindow sometimes is used by real VCL-child-windows also .-)
+ // Be sure that these window is realy a "top system window".
+ // Attention ! Checking Window->GetParent() isnt the right approach here.
+ // Because sometimes VCL create "implicit border windows" as parents even we created
+ // a simple XWindow using the toolkit only .-(
+ SolarMutexGuard aSolarGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if (
+ (pWindow ) &&
+ (pWindow->IsSystemWindow())
+ )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_PATTERN_WINDOW_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/interaction/quietinteraction.cxx b/framework/source/interaction/quietinteraction.cxx
new file mode 100644
index 000000000000..305ec97fb272
--- /dev/null
+++ b/framework/source/interaction/quietinteraction.cxx
@@ -0,0 +1,207 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "interaction/quietinteraction.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <macros/generic.hxx>
+#include <macros/debug.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/document/XInteractionFilterSelect.hpp>
+#include <com/sun/star/document/XInteractionFilterOptions.hpp>
+#include <com/sun/star/document/AmbigousFilterRequest.hpp>
+#include <com/sun/star/document/FilterOptionsRequest.hpp>
+#include <com/sun/star/task/ErrorCodeRequest.hpp>
+
+#include <com/sun/star/document/LockedDocumentRequest.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+
+#ifndef __RSC
+#include <tools/errinf.hxx>
+#endif
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// exported definitions
+//_________________________________________________________________________________________________________________
+
+DEFINE_XINTERFACE_2( QuietInteraction ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ) ,
+ DIRECT_INTERFACE(css::task::XInteractionHandler) )
+
+DEFINE_XTYPEPROVIDER_2( QuietInteraction ,
+ css::lang::XTypeProvider ,
+ css::task::XInteractionHandler )
+
+//_________________________________________________________________________________________________________________
+
+QuietInteraction::QuietInteraction()
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , ::cppu::OWeakObject( )
+ , m_aRequest ( )
+{
+}
+
+//_________________________________________________________________________________________________________________
+
+void SAL_CALL QuietInteraction::handle( const css::uno::Reference< css::task::XInteractionRequest >& xRequest ) throw( css::uno::RuntimeException )
+{
+ // safe the request for outside analyzing everytime!
+ css::uno::Any aRequest = xRequest->getRequest();
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ m_aRequest = aRequest;
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ // analyze the request
+ // We need XAbort as possible continuation as minimum!
+ // An optional filter selection we can handle too.
+ css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations = xRequest->getContinuations();
+ css::uno::Reference< css::task::XInteractionAbort > xAbort ;
+ css::uno::Reference< css::task::XInteractionApprove > xApprove ;
+ css::uno::Reference< css::document::XInteractionFilterSelect > xFilter ;
+ css::uno::Reference< css::document::XInteractionFilterOptions > xFOptions ;
+
+ sal_Int32 nCount=lContinuations.getLength();
+ for (sal_Int32 i=0; i<nCount; ++i)
+ {
+ if ( ! xAbort.is() )
+ xAbort = css::uno::Reference< css::task::XInteractionAbort >( lContinuations[i], css::uno::UNO_QUERY );
+
+ if( ! xApprove.is() )
+ xApprove = css::uno::Reference< css::task::XInteractionApprove >( lContinuations[i], css::uno::UNO_QUERY );
+
+ if ( ! xFilter.is() )
+ xFilter = css::uno::Reference< css::document::XInteractionFilterSelect >( lContinuations[i], css::uno::UNO_QUERY );
+
+ if ( ! xFOptions.is() )
+ xFOptions = css::uno::Reference< css::document::XInteractionFilterOptions >( lContinuations[i], css::uno::UNO_QUERY );
+ }
+
+ // differ between abortable interactions (error, unknown filter ...)
+ // and other ones (ambigous but not unknown filter ...)
+ css::task::ErrorCodeRequest aErrorCodeRequest ;
+ css::document::AmbigousFilterRequest aAmbigousFilterRequest;
+ css::document::LockedDocumentRequest aLockedDocumentRequest;
+ css::document::FilterOptionsRequest aFilterOptionsRequest;
+
+ if (aRequest>>=aAmbigousFilterRequest)
+ {
+ if (xFilter.is())
+ {
+ // user selected filter wins everytime!
+ xFilter->setFilter( aAmbigousFilterRequest.SelectedFilter );
+ xFilter->select();
+ }
+ }
+ else
+ if( aRequest >>= aErrorCodeRequest )
+ {
+ // warnings can be ignored => approve
+ // errors must break loading => abort
+ sal_Bool bWarning = (aErrorCodeRequest.ErrCode & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK;
+ if (xApprove.is() && bWarning)
+ xApprove->select();
+ else
+ if (xAbort.is())
+ xAbort->select();
+ }
+ else
+ if( aRequest >>= aLockedDocumentRequest )
+ {
+ // the locked document should be opened readonly by default
+ if (xApprove.is())
+ xApprove->select();
+ else
+ if (xAbort.is())
+ xAbort->select();
+ }
+ else
+ if (aRequest>>=aFilterOptionsRequest)
+ {
+ if (xFOptions.is())
+ {
+ // let the default filter options be used
+ xFOptions->select();
+ }
+ }
+ else
+ if (xAbort.is())
+ xAbort->select();
+}
+
+//_________________________________________________________________________________________________________________
+
+css::uno::Any QuietInteraction::getRequest() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_aRequest;
+ /* } SAFE */
+}
+
+//_________________________________________________________________________________________________________________
+
+sal_Bool QuietInteraction::wasUsed() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_aRequest.hasValue();
+ /* } SAFE */
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/jobs/helponstartup.cxx b/framework/source/jobs/helponstartup.cxx
new file mode 100644
index 000000000000..ec84096eda94
--- /dev/null
+++ b/framework/source/jobs/helponstartup.cxx
@@ -0,0 +1,426 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// include own header
+#include <jobs/helponstartup.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <loadenv/targethelper.hxx>
+#include <services.h>
+
+//_______________________________________________
+// include others
+#include <comphelper/configurationhelper.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <unotools/configmgr.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/help.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//_______________________________________________
+// include interfaces
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//_______________________________________________
+// definitions
+
+// path to module config
+static ::rtl::OUString CFG_PACKAGE_MODULES (RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Setup/Office/Factories"));
+static ::rtl::OUString CFG_PACKAGE_SETUP (RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Setup"));
+static ::rtl::OUString CFG_PACKAGE_COMMON (RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Common"));
+static ::rtl::OUString CFG_PATH_L10N (RTL_CONSTASCII_USTRINGPARAM("L10N"));
+static ::rtl::OUString CFG_PATH_HELP (RTL_CONSTASCII_USTRINGPARAM("Help"));
+static ::rtl::OUString CFG_KEY_LOCALE (RTL_CONSTASCII_USTRINGPARAM("ooLocale"));
+static ::rtl::OUString CFG_KEY_HELPSYSTEM (RTL_CONSTASCII_USTRINGPARAM("System"));
+
+// props of job environment
+static ::rtl::OUString PROP_ENVIRONMENT (RTL_CONSTASCII_USTRINGPARAM("Environment"));
+static ::rtl::OUString PROP_JOBCONFIG (RTL_CONSTASCII_USTRINGPARAM("JobConfig"));
+static ::rtl::OUString PROP_ENVTYPE (RTL_CONSTASCII_USTRINGPARAM("EnvType"));
+static ::rtl::OUString PROP_MODEL (RTL_CONSTASCII_USTRINGPARAM("Model"));
+
+// props of module config
+static ::rtl::OUString PROP_HELP_BASEURL (RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryHelpBaseURL"));
+static ::rtl::OUString PROP_AUTOMATIC_HELP (RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryHelpOnOpen"));
+
+// special value of job environment
+static ::rtl::OUString ENVTYPE_DOCUMENTEVENT (RTL_CONSTASCII_USTRINGPARAM("DOCUMENTEVENT"));
+
+//-----------------------------------------------
+
+DEFINE_XSERVICEINFO_MULTISERVICE(HelpOnStartup ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_JOB ,
+ IMPLEMENTATIONNAME_HELPONSTARTUP)
+
+DEFINE_INIT_SERVICE(HelpOnStartup,
+ {
+ /* Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ // create some needed uno services and cache it
+ m_xModuleManager = css::uno::Reference< css::frame::XModuleManager >(
+ m_xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
+ css::uno::UNO_QUERY_THROW);
+
+ m_xDesktop = css::uno::Reference< css::frame::XFrame >(
+ m_xSMGR->createInstance(SERVICENAME_DESKTOP),
+ css::uno::UNO_QUERY_THROW);
+
+ m_xConfig = css::uno::Reference< css::container::XNameAccess >(
+ ::comphelper::ConfigurationHelper::openConfig(
+ m_xSMGR,
+ CFG_PACKAGE_MODULES,
+ ::comphelper::ConfigurationHelper::E_READONLY),
+ css::uno::UNO_QUERY_THROW);
+
+ // ask for office locale
+ ::comphelper::ConfigurationHelper::readDirectKey(
+ m_xSMGR,
+ CFG_PACKAGE_SETUP,
+ CFG_PATH_L10N,
+ CFG_KEY_LOCALE,
+ ::comphelper::ConfigurationHelper::E_READONLY) >>= m_sLocale;
+
+ // detect system
+ ::comphelper::ConfigurationHelper::readDirectKey(
+ m_xSMGR,
+ CFG_PACKAGE_COMMON,
+ CFG_PATH_HELP,
+ CFG_KEY_HELPSYSTEM,
+ ::comphelper::ConfigurationHelper::E_READONLY) >>= m_sSystem;
+
+ // Start listening for disposing events of these services,
+ // so we can react e.g. for an office shutdown
+ css::uno::Reference< css::lang::XComponent > xComponent;
+ xComponent = css::uno::Reference< css::lang::XComponent >(m_xModuleManager, css::uno::UNO_QUERY);
+ if (xComponent.is())
+ xComponent->addEventListener(static_cast< css::lang::XEventListener* >(this));
+ xComponent = css::uno::Reference< css::lang::XComponent >(m_xDesktop, css::uno::UNO_QUERY);
+ if (xComponent.is())
+ xComponent->addEventListener(static_cast< css::lang::XEventListener* >(this));
+ xComponent = css::uno::Reference< css::lang::XComponent >(m_xConfig, css::uno::UNO_QUERY);
+ if (xComponent.is())
+ xComponent->addEventListener(static_cast< css::lang::XEventListener* >(this));
+ }
+ )
+
+//-----------------------------------------------
+HelpOnStartup::HelpOnStartup(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase( )
+ , m_xSMGR (xSMGR)
+{
+}
+
+//-----------------------------------------------
+HelpOnStartup::~HelpOnStartup()
+{
+}
+
+//-----------------------------------------------
+// css.task.XJob
+css::uno::Any SAL_CALL HelpOnStartup::execute(const css::uno::Sequence< css::beans::NamedValue >& lArguments)
+ throw(css::lang::IllegalArgumentException,
+ css::uno::Exception ,
+ css::uno::RuntimeException )
+{
+ // Analyze the given arguments; try to locate a model there and
+ // classify it's used application module.
+ ::rtl::OUString sModule = its_getModuleIdFromEnv(lArguments);
+
+ // Attention: We are bound to events for openeing any document inside the office.
+ // That includes e.g. the help module itself. But we have to do nothing then!
+ if (!sModule.getLength())
+ return css::uno::Any();
+
+ // check current state of the help module
+ // a) help isnt open => show default page for the detected module
+ // b) help shows any other default page(!) => show default page for the detected module
+ // c) help shows any other content => do nothing (user travelled to any other content and leaved the set of default pages)
+ ::rtl::OUString sCurrentHelpURL = its_getCurrentHelpURL();
+ sal_Bool bCurrentHelpURLIsAnyDefaultURL = its_isHelpUrlADefaultOne(sCurrentHelpURL);
+ sal_Bool bShowIt = sal_False;
+
+ // a)
+ if (!sCurrentHelpURL.getLength())
+ bShowIt = sal_True;
+ else
+ // b)
+ if (bCurrentHelpURLIsAnyDefaultURL)
+ bShowIt = sal_True;
+
+ if (bShowIt)
+ {
+ // retrieve the help URL for the detected application module
+ ::rtl::OUString sModuleDependendHelpURL = its_checkIfHelpEnabledAndGetURL(sModule);
+ if (sModuleDependendHelpURL.getLength())
+ {
+ // Show this help page.
+ // Note: The help window brings itself to front ...
+ Help* pHelp = Application::GetHelp();
+ if (pHelp)
+ pHelp->Start(sModuleDependendHelpURL, 0);
+ }
+ }
+
+ return css::uno::Any();
+}
+
+//-----------------------------------------------
+void SAL_CALL HelpOnStartup::disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ResetableGuard aLock(m_aLock);
+
+ if (aEvent.Source == m_xModuleManager)
+ m_xModuleManager.clear();
+ else
+ if (aEvent.Source == m_xDesktop)
+ m_xDesktop.clear();
+ else
+ if (aEvent.Source == m_xConfig)
+ m_xConfig.clear();
+
+ aLock.unlock();
+ // <- SAFE
+}
+
+//-----------------------------------------------
+::rtl::OUString HelpOnStartup::its_getModuleIdFromEnv(const css::uno::Sequence< css::beans::NamedValue >& lArguments)
+{
+ ::comphelper::SequenceAsHashMap lArgs (lArguments);
+ ::comphelper::SequenceAsHashMap lEnvironment = lArgs.getUnpackedValueOrDefault(PROP_ENVIRONMENT, css::uno::Sequence< css::beans::NamedValue >());
+ ::comphelper::SequenceAsHashMap lJobConfig = lArgs.getUnpackedValueOrDefault(PROP_JOBCONFIG , css::uno::Sequence< css::beans::NamedValue >());
+
+ // check for right environment.
+ // If its not a DocumentEvent, which triggered this job,
+ // we cant work correctly! => return immediatly and do nothing
+ ::rtl::OUString sEnvType = lEnvironment.getUnpackedValueOrDefault(PROP_ENVTYPE, ::rtl::OUString());
+ if (!sEnvType.equals(ENVTYPE_DOCUMENTEVENT))
+ return ::rtl::OUString();
+
+ css::uno::Reference< css::frame::XModel > xDoc = lEnvironment.getUnpackedValueOrDefault(PROP_MODEL, css::uno::Reference< css::frame::XModel >());
+ if (!xDoc.is())
+ return ::rtl::OUString();
+
+ // be sure that we work on top level documents only, which are registered
+ // on the desktop instance. Ignore e.g. life previews, which are top frames too ...
+ // but not registered at this global desktop instance.
+ css::uno::Reference< css::frame::XDesktop > xDesktopCheck;
+ css::uno::Reference< css::frame::XFrame > xFrame ;
+ css::uno::Reference< css::frame::XController > xController = xDoc->getCurrentController();
+ if (xController.is())
+ xFrame = xController->getFrame();
+ if (xFrame.is() && xFrame->isTop())
+ xDesktopCheck = css::uno::Reference< css::frame::XDesktop >(xFrame->getCreator(), css::uno::UNO_QUERY);
+ if (!xDesktopCheck.is())
+ return ::rtl::OUString();
+
+ // OK - now we are sure this document is a top level document.
+ // Classify it.
+ // SAFE ->
+ ResetableGuard aLock(m_aLock);
+ css::uno::Reference< css::frame::XModuleManager > xModuleManager = m_xModuleManager;
+ aLock.unlock();
+ // <- SAFE
+
+ if (!xModuleManager.is())
+ return ::rtl::OUString();
+
+ ::rtl::OUString sModuleId;
+ try
+ {
+ sModuleId = xModuleManager->identify(xDoc);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { sModuleId = ::rtl::OUString(); }
+
+ return sModuleId;
+}
+
+//-----------------------------------------------
+::rtl::OUString HelpOnStartup::its_getCurrentHelpURL()
+{
+ // SAFE ->
+ ResetableGuard aLock(m_aLock);
+ css::uno::Reference< css::frame::XFrame > xDesktop = m_xDesktop;
+ aLock.unlock();
+ // <- SAFE
+
+ if (!xDesktop.is())
+ return ::rtl::OUString();
+
+ css::uno::Reference< css::frame::XFrame > xHelp = xDesktop->findFrame(SPECIALTARGET_HELPTASK, css::frame::FrameSearchFlag::CHILDREN);
+ if (!xHelp.is())
+ return ::rtl::OUString();
+
+ ::rtl::OUString sCurrentHelpURL;
+ try
+ {
+ css::uno::Reference< css::frame::XFramesSupplier > xHelpRoot (xHelp , css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::container::XIndexAccess > xHelpChilds(xHelpRoot->getFrames(), css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::frame::XFrame > xHelpChild ;
+ css::uno::Reference< css::frame::XController > xHelpView ;
+ css::uno::Reference< css::frame::XModel > xHelpContent;
+
+ xHelpChilds->getByIndex(0) >>= xHelpChild;
+ if (xHelpChild.is())
+ xHelpView = xHelpChild->getController();
+ if (xHelpView.is())
+ xHelpContent = xHelpView->getModel();
+ if (xHelpContent.is())
+ sCurrentHelpURL = xHelpContent->getURL();
+ }
+ catch(css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(css::uno::Exception&)
+ { sCurrentHelpURL = ::rtl::OUString(); }
+
+ return sCurrentHelpURL;
+}
+
+//-----------------------------------------------
+::sal_Bool HelpOnStartup::its_isHelpUrlADefaultOne(const ::rtl::OUString& sHelpURL)
+{
+ if (!sHelpURL.getLength())
+ return sal_False;
+
+ // SAFE ->
+ ResetableGuard aLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR (m_xSMGR, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::container::XNameAccess > xConfig = m_xConfig;
+ ::rtl::OUString sLocale = m_sLocale;
+ ::rtl::OUString sSystem = m_sSystem;
+ aLock.unlock();
+ // <- SAFE
+
+ if (!xConfig.is())
+ return sal_False;
+
+ // check given help url against all default ones
+ const css::uno::Sequence< ::rtl::OUString > lModules = xConfig->getElementNames();
+ const ::rtl::OUString* pModules = lModules.getConstArray();
+ ::sal_Int32 c = lModules.getLength();
+ ::sal_Int32 i = 0;
+
+ for (i=0; i<c; ++i)
+ {
+ try
+ {
+ css::uno::Reference< css::container::XNameAccess > xModuleConfig;
+ xConfig->getByName(pModules[i]) >>= xModuleConfig;
+ if (!xModuleConfig.is())
+ continue;
+
+ ::rtl::OUString sHelpBaseURL;
+ xModuleConfig->getByName(PROP_HELP_BASEURL) >>= sHelpBaseURL;
+ ::rtl::OUString sHelpURLForModule = HelpOnStartup::ist_createHelpURL(sHelpBaseURL, sLocale, sSystem);
+ if (sHelpURL.equals(sHelpURLForModule))
+ return sal_True;
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+ }
+
+ return sal_False;
+}
+
+//-----------------------------------------------
+::rtl::OUString HelpOnStartup::its_checkIfHelpEnabledAndGetURL(const ::rtl::OUString& sModule)
+{
+ // SAFE ->
+ ResetableGuard aLock(m_aLock);
+ css::uno::Reference< css::container::XNameAccess > xConfig = m_xConfig;
+ ::rtl::OUString sLocale = m_sLocale;
+ ::rtl::OUString sSystem = m_sSystem;
+ aLock.unlock();
+ // <- SAFE
+
+ ::rtl::OUString sHelpURL;
+
+ try
+ {
+ css::uno::Reference< css::container::XNameAccess > xModuleConfig;
+ if (xConfig.is())
+ xConfig->getByName(sModule) >>= xModuleConfig;
+
+ sal_Bool bHelpEnabled = sal_False;
+ if (xModuleConfig.is())
+ xModuleConfig->getByName(PROP_AUTOMATIC_HELP) >>= bHelpEnabled;
+
+ if (bHelpEnabled)
+ {
+ ::rtl::OUString sHelpBaseURL;
+ xModuleConfig->getByName(PROP_HELP_BASEURL) >>= sHelpBaseURL;
+ sHelpURL = HelpOnStartup::ist_createHelpURL(sHelpBaseURL, sLocale, sSystem);
+ }
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { sHelpURL = ::rtl::OUString(); }
+
+ return sHelpURL;
+}
+
+//-----------------------------------------------
+::rtl::OUString HelpOnStartup::ist_createHelpURL(const ::rtl::OUString& sBaseURL,
+ const ::rtl::OUString& sLocale ,
+ const ::rtl::OUString& sSystem )
+{
+ ::rtl::OUStringBuffer sHelpURL(256);
+ sHelpURL.append (sBaseURL );
+ sHelpURL.appendAscii("?Language=");
+ sHelpURL.append (sLocale );
+ sHelpURL.appendAscii("&System=" );
+ sHelpURL.append (sSystem );
+
+ return sHelpURL.makeStringAndClear();
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/jobs/job.cxx b/framework/source/jobs/job.cxx
new file mode 100644
index 000000000000..635fb4b6aa46
--- /dev/null
+++ b/framework/source/jobs/job.cxx
@@ -0,0 +1,944 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//________________________________
+// my own includes
+#include <jobs/job.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <general.h>
+#include <services.h>
+
+//________________________________
+// interface includes
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/task/XAsyncJob.hpp>
+#include <com/sun/star/util/XCloseBroadcaster.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+//________________________________
+// includes of other projects
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+
+//________________________________
+// namespace
+
+namespace framework{
+
+//________________________________
+// non exported const
+
+//________________________________
+// non exported definitions
+
+//________________________________
+// declarations
+
+DEFINE_XINTERFACE_4( Job ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::task::XJobListener ),
+ DIRECT_INTERFACE(css::frame::XTerminateListener),
+ DIRECT_INTERFACE(css::util::XCloseListener )
+ )
+
+DEFINE_XTYPEPROVIDER_4( Job ,
+ css::lang::XTypeProvider ,
+ css::task::XJobListener ,
+ css::frame::XTerminateListener,
+ css::util::XCloseListener
+ )
+
+//________________________________
+/**
+ @short standard ctor
+ @descr It initialize this new instance. But it set some generic parameters here only.
+ Specialized informations (e.g. the alias or service name ofthis job) will be set
+ later using the method setJobData().
+
+ @param xSMGR
+ reference to the uno service manager
+
+ @param xFrame
+ reference to the frame, in which environment we run
+ (May be null!)
+*/
+Job::Job( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame )
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , ::cppu::OWeakObject ( )
+ , m_aJobCfg (xSMGR )
+ , m_xSMGR (xSMGR )
+ , m_xFrame (xFrame )
+ , m_bListenOnDesktop (sal_False )
+ , m_bListenOnFrame (sal_False )
+ , m_bListenOnModel (sal_False )
+ , m_bPendingCloseFrame (sal_False )
+ , m_bPendingCloseModel (sal_False )
+ , m_eRunState (E_NEW )
+{
+}
+
+//________________________________
+/**
+ @short standard ctor
+ @descr It initialize this new instance. But it set some generic parameters here only.
+ Specialized informations (e.g. the alias or service name ofthis job) will be set
+ later using the method setJobData().
+
+ @param xSMGR
+ reference to the uno service manager
+
+ @param xModel
+ reference to the model, in which environment we run
+ (May be null!)
+*/
+Job::Job( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ /*IN*/ const css::uno::Reference< css::frame::XModel >& xModel )
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , ::cppu::OWeakObject ( )
+ , m_aJobCfg (xSMGR )
+ , m_xSMGR (xSMGR )
+ , m_xModel (xModel )
+ , m_bListenOnDesktop (sal_False )
+ , m_bListenOnFrame (sal_False )
+ , m_bListenOnModel (sal_False )
+ , m_bPendingCloseFrame (sal_False )
+ , m_bPendingCloseModel (sal_False )
+ , m_eRunState (E_NEW )
+{
+}
+
+//________________________________
+/**
+ @short superflous!
+ @descr Releasing of memory and reference must be done inside die() call.
+ Otherwhise it's a bug.
+*/
+Job::~Job()
+{
+}
+
+//________________________________
+/**
+ @short set (or delete) a listener for sending dispatch result events
+ @descr Because this object is used in a wrapped mode ... the original listener
+ for such events can't be registered here directly. Because the
+ listener expect to get the original object given as source of the event.
+ That's why we get this source here too, to fake(!) it at sending time!
+
+ @param xListener
+ the original listener for dispatch result events
+
+ @param xSourceFake
+ our user, which got the registration request for this listener
+*/
+void Job::setDispatchResultFake( /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ,
+ /*IN*/ const css::uno::Reference< css::uno::XInterface >& xSourceFake )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // reject dangerous calls
+ if (m_eRunState != E_NEW)
+ {
+ LOG_WARNING("Job::setJobData()", "job may still running or already finished")
+ return;
+ }
+
+ m_xResultListener = xListener ;
+ m_xResultSourceFake = xSourceFake;
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+void Job::setJobData( const JobData& aData )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // reject dangerous calls
+ if (m_eRunState != E_NEW)
+ {
+ LOG_WARNING("Job::setJobData()", "job may still running or already finished")
+ return;
+ }
+
+ m_aJobCfg = aData;
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short runs the job
+ @descr It doesn't matter, if the job is an asynchronous or
+ synchronous one. This method returns only if it was finished
+ or cancelled.
+
+ @param lDynamicArgs
+ optional arguments for job execution
+ In case the represented job is a configured one (which uses static
+ arguments too) all informations will be merged!
+*/
+void Job::execute( /*IN*/ const css::uno::Sequence< css::beans::NamedValue >& lDynamicArgs )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // reject dangerous calls
+ if (m_eRunState != E_NEW)
+ {
+ LOG_WARNING("Job::execute()", "job may still running or already finished")
+ return;
+ }
+
+ // create the environment and mark this job as running ...
+ m_eRunState = E_RUNNING;
+ impl_startListening();
+
+ css::uno::Reference< css::task::XAsyncJob > xAJob;
+ css::uno::Reference< css::task::XJob > xSJob;
+ css::uno::Sequence< css::beans::NamedValue > lJobArgs = impl_generateJobArgs(lDynamicArgs);
+
+ // It's neccessary to hold us self alive!
+ // Otherwhise we might die by ref count ...
+ css::uno::Reference< css::task::XJobListener > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+
+ try
+ {
+ // create the job
+ // We must check for the supported interface on demand!
+ // But we preferr the synchronous one ...
+ m_xJob = m_xSMGR->createInstance(m_aJobCfg.getService());
+ xSJob = css::uno::Reference< css::task::XJob >(m_xJob, css::uno::UNO_QUERY);
+ if (!xSJob.is())
+ xAJob = css::uno::Reference< css::task::XAsyncJob >(m_xJob, css::uno::UNO_QUERY);
+
+ // execute it asynchron
+ if (xAJob.is())
+ {
+ m_aAsyncWait.reset();
+ aWriteLock.unlock();
+ /* } SAFE */
+ xAJob->executeAsync(lJobArgs, xThis);
+ // wait for finishing this job - so this method
+ // does the same for synchronous and asynchronous jobs!
+ m_aAsyncWait.wait();
+ aWriteLock.lock();
+ /* SAFE { */
+ // Note: Result handling was already done inside the callback!
+ }
+ // execute it synchron
+ else if (xSJob.is())
+ {
+ aWriteLock.unlock();
+ /* } SAFE */
+ css::uno::Any aResult = xSJob->execute(lJobArgs);
+ aWriteLock.lock();
+ /* SAFE { */
+ impl_reactForJobResult(aResult);
+ }
+ }
+ #if OSL_DEBUG_LEVEL > 0
+ catch(const css::uno::Exception& ex)
+ {
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("Got exception during job execution. Original Message was:\n\"");
+ sMsg.append (ex.Message);
+ sMsg.appendAscii("\"");
+ LOG_WARNING("Job::execute()", U2B(sMsg.makeStringAndClear()).getStr())
+ }
+ #else
+ catch(const css::uno::Exception&)
+ {}
+ #endif
+
+ // deinitialize the environment and mark this job as finished ...
+ // but don't overwrite any informations about STOPPED or might DISPOSED jobs!
+ impl_stopListening();
+ if (m_eRunState == E_RUNNING)
+ m_eRunState = E_STOPPED_OR_FINISHED;
+
+ // If we got a close request from our frame or model ...
+ // but we disagreed wit that by throwing a veto exception...
+ // and got the ownership ...
+ // we have to close the resource frame or model now -
+ // and to disable ourself!
+ if (m_bPendingCloseFrame)
+ {
+ m_bPendingCloseFrame = sal_False;
+ css::uno::Reference< css::util::XCloseable > xClose(m_xFrame, css::uno::UNO_QUERY);
+ if (xClose.is())
+ {
+ try
+ {
+ xClose->close(sal_True);
+ }
+ catch(const css::util::CloseVetoException&) {}
+ }
+ }
+
+ if (m_bPendingCloseModel)
+ {
+ m_bPendingCloseModel = sal_False;
+ css::uno::Reference< css::util::XCloseable > xClose(m_xModel, css::uno::UNO_QUERY);
+ if (xClose.is())
+ {
+ try
+ {
+ xClose->close(sal_True);
+ }
+ catch(const css::util::CloseVetoException&) {}
+ }
+ }
+
+ aWriteLock.unlock();
+ /* SAFE { */
+
+ // release this instance ...
+ die();
+}
+
+//________________________________
+/**
+ @short kill this job
+ @descr It doesn't matter if this request is called from inside or
+ from outside. We release our internal structures and stop
+ avary activity. After doing so - this instance will not be
+ useable any longer! Of course we try to handle further requests
+ carefully. May somehwere else hold a reference to us ...
+*/
+void Job::die()
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ impl_stopListening();
+
+ if (m_eRunState != E_DISPOSED)
+ {
+ try
+ {
+ css::uno::Reference< css::lang::XComponent > xDispose(m_xJob, css::uno::UNO_QUERY);
+ if (xDispose.is())
+ {
+ xDispose->dispose();
+ m_eRunState = E_DISPOSED;
+ }
+ }
+ catch(const css::lang::DisposedException&)
+ {
+ m_eRunState = E_DISPOSED;
+ }
+ }
+
+ m_xJob = css::uno::Reference< css::uno::XInterface >();
+ m_xFrame = css::uno::Reference< css::frame::XFrame >();
+ m_xModel = css::uno::Reference< css::frame::XModel >();
+ m_xDesktop = css::uno::Reference< css::frame::XDesktop >();
+ m_xResultListener = css::uno::Reference< css::frame::XDispatchResultListener >();
+ m_xResultSourceFake = css::uno::Reference< css::uno::XInterface >();
+ m_bPendingCloseFrame = sal_False;
+ m_bPendingCloseModel = sal_False;
+
+ aWriteLock.unlock();
+ /* SAFE { */
+}
+
+//________________________________
+/**
+ @short generates list of arguments for job execute
+ @descr There exist a set of informations, which can be needed by a job.
+ a) it's static configuration data (Equals for all jobs. )
+ b) it's specific configuration data (Different for every job.)
+ c) some environment values (e.g. the frame, for which this job was started)
+ d) any other dynamic data (e.g. parameters of a dispatch() request)
+ We collect all these informations and generate one list which include all others.
+
+ @param lDynamicArgs
+ list of dynamic arguments (given by a corresponding dispatch() call)
+ Can be empty too.
+
+ @return A list which includes all mentioned sub lists.
+*/
+css::uno::Sequence< css::beans::NamedValue > Job::impl_generateJobArgs( /*IN*/ const css::uno::Sequence< css::beans::NamedValue >& lDynamicArgs )
+{
+ css::uno::Sequence< css::beans::NamedValue > lAllArgs;
+
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ // the real structure of the returned list depends from the environment of this job!
+ JobData::EMode eMode = m_aJobCfg.getMode();
+
+ // Create list of environment variables. This list must be part of the
+ // returned structure everytimes ... but some of its members are opetional!
+ css::uno::Sequence< css::beans::NamedValue > lEnvArgs(1);
+ lEnvArgs[0].Name = ::rtl::OUString::createFromAscii(JobData::PROP_ENVTYPE);
+ lEnvArgs[0].Value <<= m_aJobCfg.getEnvironmentDescriptor();
+
+ if (m_xFrame.is())
+ {
+ sal_Int32 c = lEnvArgs.getLength();
+ lEnvArgs.realloc(c+1);
+ lEnvArgs[c].Name = ::rtl::OUString::createFromAscii(JobData::PROP_FRAME);
+ lEnvArgs[c].Value <<= m_xFrame;
+ }
+ if (m_xModel.is())
+ {
+ sal_Int32 c = lEnvArgs.getLength();
+ lEnvArgs.realloc(c+1);
+ lEnvArgs[c].Name = ::rtl::OUString::createFromAscii(JobData::PROP_MODEL);
+ lEnvArgs[c].Value <<= m_xModel;
+ }
+ if (eMode==JobData::E_EVENT)
+ {
+ sal_Int32 c = lEnvArgs.getLength();
+ lEnvArgs.realloc(c+1);
+ lEnvArgs[c].Name = ::rtl::OUString::createFromAscii(JobData::PROP_EVENTNAME);
+ lEnvArgs[c].Value <<= m_aJobCfg.getEvent();
+ }
+
+ // get the configuration data from the job data container ... if possible
+ // Means: if this job has any configuration data. Note: only realy
+ // filled lists will be set to the return structure at the end of this method.
+ css::uno::Sequence< css::beans::NamedValue > lConfigArgs ;
+ css::uno::Sequence< css::beans::NamedValue > lJobConfigArgs;
+ if (eMode==JobData::E_ALIAS || eMode==JobData::E_EVENT)
+ {
+ lConfigArgs = m_aJobCfg.getConfig();
+ lJobConfigArgs = m_aJobCfg.getJobConfig();
+ }
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ // Add all valid (not empty) lists to the return list
+ if (lConfigArgs.getLength()>0)
+ {
+ sal_Int32 nLength = lAllArgs.getLength();
+ lAllArgs.realloc(nLength+1);
+ lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_CONFIG);
+ lAllArgs[nLength].Value <<= lConfigArgs;
+ }
+ if (lJobConfigArgs.getLength()>0)
+ {
+ sal_Int32 nLength = lAllArgs.getLength();
+ lAllArgs.realloc(nLength+1);
+ lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_OWNCONFIG);
+ lAllArgs[nLength].Value <<= lJobConfigArgs;
+ }
+ if (lEnvArgs.getLength()>0)
+ {
+ sal_Int32 nLength = lAllArgs.getLength();
+ lAllArgs.realloc(nLength+1);
+ lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_ENVIRONMENT);
+ lAllArgs[nLength].Value <<= lEnvArgs;
+ }
+ if (lDynamicArgs.getLength()>0)
+ {
+ sal_Int32 nLength = lAllArgs.getLength();
+ lAllArgs.realloc(nLength+1);
+ lAllArgs[nLength].Name = ::rtl::OUString::createFromAscii(JobData::PROPSET_DYNAMICDATA);
+ lAllArgs[nLength].Value <<= lDynamicArgs;
+ }
+
+ return lAllArgs;
+}
+
+//________________________________
+/**
+ @short analyze the given job result and change the job configuration
+ @descr Note: Some results can be handled only, if this job has a valid configuration!
+ For "not configured jobs" (means pure services) they can be ignored.
+ But these cases are handled by our JobData member. We can call it everytime.
+ It does the right things automaticly. E.g. if the job has no configuration ...
+ it does nothing during setJobConfig()!
+
+ @param aResult
+ the job result for analyzing
+*/
+void Job::impl_reactForJobResult( /*IN*/ const css::uno::Any& aResult )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // analyze the result set ...
+ JobResult aAnalyzedResult(aResult);
+
+ // some of the following operations will be supported for different environments
+ // or different type of jobs only.
+ JobData::EEnvironment eEnvironment = m_aJobCfg.getEnvironment();
+
+ // write back the job specific configuration data ...
+ // If the environment allow it and if this job has a configuration!
+ if (
+ (m_aJobCfg.hasConfig() ) &&
+ (aAnalyzedResult.existPart(JobResult::E_ARGUMENTS))
+ )
+ {
+ m_aJobCfg.setJobConfig(aAnalyzedResult.getArguments());
+ }
+
+ // disable a job for further executions.
+ // Note: this option is available inside the environment EXECUTOR only
+ if (
+// (eEnvironment == JobData::E_EXECUTION ) &&
+ (m_aJobCfg.hasConfig() ) &&
+ (aAnalyzedResult.existPart(JobResult::E_DEACTIVATE))
+ )
+ {
+ m_aJobCfg.disableJob();
+ }
+
+ // notify any interested listener with the may given result state.
+ // Note: this option is available inside the environment DISPATCH only
+ if (
+ (eEnvironment == JobData::E_DISPATCH ) &&
+ (m_xResultListener.is() ) &&
+ (aAnalyzedResult.existPart(JobResult::E_DISPATCHRESULT))
+ )
+ {
+ m_aJobCfg.setResult(aAnalyzedResult);
+ // Attention: Because the listener expect that the original object send this event ...
+ // and we nor the job are the right ones ...
+ // our user has set itself before. So we can fake this source address!
+ css::frame::DispatchResultEvent aEvent = aAnalyzedResult.getDispatchResult();
+ aEvent.Source = m_xResultSourceFake;
+ m_xResultListener->dispatchFinished(aEvent);
+ }
+
+ aWriteLock.unlock();
+ /* SAFE { */
+}
+
+//________________________________
+/**
+ @short starts listening for office shutdown and closing of our
+ given target frame (if its a valid reference)
+ @descr We will reghister ourself as terminate listener
+ at the global desktop instance. That will hold us
+ alive and additional we get the information, if the
+ office whish to shutdown. If then an internal job
+ is running we will have the chance to supress that
+ by throwing a veto exception. If our internal wrapped
+ job finished his work, we can release this listener
+ connection.
+
+ Further we are listener for closing of the (possible valid)
+ given frame. We must be shure, that this ressource won't be gone
+ if our internal job is still running.
+*/
+void Job::impl_startListening()
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // listening for office shutdown
+ if (!m_xDesktop.is() && !m_bListenOnDesktop)
+ {
+ try
+ {
+ m_xDesktop = css::uno::Reference< css::frame::XDesktop >(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XTerminateListener > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ if (m_xDesktop.is())
+ {
+ m_xDesktop->addTerminateListener(xThis);
+ m_bListenOnDesktop = sal_True;
+ }
+ }
+ catch(css::uno::Exception&)
+ {
+ m_xDesktop = css::uno::Reference< css::frame::XDesktop >();
+ }
+ }
+
+ // listening for frame closing
+ if (m_xFrame.is() && !m_bListenOnFrame)
+ {
+ try
+ {
+ css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xFrame , css::uno::UNO_QUERY);
+ css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ if (xCloseable.is())
+ {
+ xCloseable->addCloseListener(xThis);
+ m_bListenOnFrame = sal_True;
+ }
+ }
+ catch(css::uno::Exception&)
+ {
+ m_bListenOnFrame = sal_False;
+ }
+ }
+
+ // listening for model closing
+ if (m_xModel.is() && !m_bListenOnModel)
+ {
+ try
+ {
+ css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xModel , css::uno::UNO_QUERY);
+ css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ if (xCloseable.is())
+ {
+ xCloseable->addCloseListener(xThis);
+ m_bListenOnModel = sal_True;
+ }
+ }
+ catch(css::uno::Exception&)
+ {
+ m_bListenOnModel = sal_False;
+ }
+ }
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short release listener connection for office shutdown
+ @descr see description of impl_startListening()
+*/
+void Job::impl_stopListening()
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // stop listening for office shutdown
+ if (m_xDesktop.is() && m_bListenOnDesktop)
+ {
+ try
+ {
+ css::uno::Reference< css::frame::XTerminateListener > xThis(static_cast< ::cppu::OWeakObject* >(this) , css::uno::UNO_QUERY);
+ m_xDesktop->removeTerminateListener(xThis);
+ m_xDesktop = css::uno::Reference< css::frame::XDesktop >();
+ m_bListenOnDesktop = sal_False;
+ }
+ catch(css::uno::Exception&)
+ {
+ }
+ }
+
+ // stop listening for frame closing
+ if (m_xFrame.is() && m_bListenOnFrame)
+ {
+ try
+ {
+ css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xFrame , css::uno::UNO_QUERY);
+ css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ if (xCloseable.is())
+ {
+ xCloseable->removeCloseListener(xThis);
+ m_bListenOnFrame = sal_False;
+ }
+ }
+ catch(css::uno::Exception&)
+ {
+ }
+ }
+
+ // stop listening for model closing
+ if (m_xModel.is() && m_bListenOnModel)
+ {
+ try
+ {
+ css::uno::Reference< css::util::XCloseBroadcaster > xCloseable(m_xModel , css::uno::UNO_QUERY);
+ css::uno::Reference< css::util::XCloseListener > xThis (static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ if (xCloseable.is())
+ {
+ xCloseable->removeCloseListener(xThis);
+ m_bListenOnModel = sal_False;
+ }
+ }
+ catch(css::uno::Exception&)
+ {
+ }
+ }
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short callback from any asynchronous executed job
+
+ @descr Our execute() method waits for this callback.
+ We have to react for the possible results here,
+ to kill the running job and disable the blocked condition
+ so execute() can be finished too.
+
+ @param xJob
+ the job, which was running and inform us now
+
+ @param aResult
+ it's results
+*/
+void SAL_CALL Job::jobFinished( /*IN*/ const css::uno::Reference< css::task::XAsyncJob >& xJob ,
+ /*IN*/ const css::uno::Any& aResult ) throw(css::uno::RuntimeException)
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // It's neccessary to check this.
+ // May this job was cancelled by any other reason
+ // some milliseconds before. :-)
+ if (m_xJob.is() && m_xJob==xJob)
+ {
+ // react for his results
+ // (means enable/disable it for further requests
+ // or save arguments or notify listener ...)
+ impl_reactForJobResult(aResult);
+
+ // Let the job die!
+ m_xJob = css::uno::Reference< css::uno::XInterface >();
+ }
+
+ // And let the start method "execute()" finishing it's job.
+ // But do it everytime. So any outside blocking code can finish
+ // his work too.
+ m_aAsyncWait.set();
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short prevent internal wrapped job against office termination
+ @descr This event is broadcasted by the desktop instance and ask for an office termination.
+ If the internal wrapped job is still in progress, we disagree with that by throwing the
+ right veto exception. If not - we agree. But then we must be aware, that another event
+ notifyTermination() can follow. Then we have no chance to do the same. Then we have to
+ accept that and stop our work instandly.
+
+ @param aEvent
+ describes the broadcaster and must be the desktop instance
+
+ @throw TerminateVetoException
+ if our internal wrapped job is still running.
+ */
+void SAL_CALL Job::queryTermination( /*IN*/ const css::lang::EventObject& ) throw(css::frame::TerminationVetoException,
+ css::uno::RuntimeException )
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+
+ // Otherwhise try to close() it
+ css::uno::Reference< css::util::XCloseable > xClose(m_xJob, css::uno::UNO_QUERY);
+ if (xClose.is())
+ {
+ try
+ {
+ xClose->close(sal_False);
+ m_eRunState = E_STOPPED_OR_FINISHED;
+ }
+ catch(const css::util::CloseVetoException&) {}
+ }
+
+ if (m_eRunState != E_STOPPED_OR_FINISHED)
+ {
+ css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ throw css::frame::TerminationVetoException(DECLARE_ASCII("job still in progress"), xThis);
+ }
+
+ aReadLock.unlock();
+ /* } SAFE */
+}
+
+
+//________________________________
+/**
+ @short inform us about office termination
+ @descr Instead of the method queryTermination(), here is no chance to disagree with that.
+ We have to accept it and cancel all current processes inside.
+ It can occure only, if job was not already started if queryTermination() was called here ..
+ Then we had not throwed a veto exception. But now we must agree with this situation and break
+ all our internal processes. Its not a good idea to mark this instance as non startable any longer
+ inside queryTermination() if no job was unning too. Because that would disable this job and may
+ the office does not realy shutdownm, because another listener has thrown the suitable exception.
+
+ @param aEvent
+ describes the broadcaster and must be the desktop instance
+ */
+void SAL_CALL Job::notifyTermination( /*IN*/ const css::lang::EventObject& ) throw(css::uno::RuntimeException)
+{
+ die();
+ // Do nothing else here. Our internal ressources was released ...
+}
+
+//________________________________
+/**
+ @short prevent internal wrapped job against frame closing
+ @descr This event is broadcasted by the frame instance and ask for closing.
+ If the internal wrapped job is still in progress, we disagree with that by throwing the
+ right veto exception. If not - we agree. But then we must be aware, that another event
+ notifyClosing() can follow. Then we have no chance to do the same. Then we have to
+ accept that and stop our work instandly.
+
+ @param aEvent
+ describes the broadcaster and must be the frame instance
+
+ @param bGetsOwnerShip
+ If it's set to <sal_True> and we throw the right veto excepion, we have to close this frame later
+ if our internal processes will be finished. If it's set to <FALSE/> we can ignore it.
+
+ @throw CloseVetoException
+ if our internal wrapped job is still running.
+ */
+void SAL_CALL Job::queryClosing( const css::lang::EventObject& aEvent ,
+ sal_Bool bGetsOwnership ) throw(css::util::CloseVetoException,
+ css::uno::RuntimeException )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // do nothing, if no internal job is still running ...
+ // The frame or model can be closed then successfully.
+ if (m_eRunState != E_RUNNING)
+ return;
+
+ // try close() first at the job.
+ // The job can agree or disagree with this request.
+ css::uno::Reference< css::util::XCloseable > xClose(m_xJob, css::uno::UNO_QUERY);
+ if (xClose.is())
+ {
+ xClose->close(bGetsOwnership);
+ // Here we can say: "this job was stopped successfully". Because
+ // no veto exception was thrown!
+ m_eRunState = E_STOPPED_OR_FINISHED;
+ return;
+ }
+
+ // try dispose() then
+ // Here the job has no chance for a veto.
+ // But we must be aware of an "already disposed exception"...
+ try
+ {
+ css::uno::Reference< css::lang::XComponent > xDispose(m_xJob, css::uno::UNO_QUERY);
+ if (xDispose.is())
+ {
+ xDispose->dispose();
+ m_eRunState = E_DISPOSED;
+ }
+ }
+ catch(const css::lang::DisposedException&)
+ {
+ // the job was already disposed by any other mechanism !?
+ // But it's not interesting for us. For us this job is stopped now.
+ m_eRunState = E_DISPOSED;
+ }
+
+ if (m_eRunState != E_DISPOSED)
+ {
+ // analyze event source - to find out, which resource called queryClosing() at this
+ // job wrapper. We must bind a "pending close" request to this resource.
+ // Closing of the corresponding resource will be done if our internal job finish it's work.
+ m_bPendingCloseFrame = (m_xFrame.is() && aEvent.Source == m_xFrame);
+ m_bPendingCloseModel = (m_xModel.is() && aEvent.Source == m_xModel);
+
+ // throw suitable veto exception - because the internal job could not be cancelled.
+ css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ throw css::util::CloseVetoException(DECLARE_ASCII("job still in progress"), xThis);
+ }
+
+ // No veto ...
+ // But don't call die() here or free our internal member.
+ // This must be done inside notifyClosing() only. Otherwhise the
+ // might stopped job has no chance to return it's results or
+ // call us back. We must give him the chance to finish it's work successfully.
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short inform us about frame closing
+ @descr Instead of the method queryClosing(), here is no chance to disagree with that.
+ We have to accept it and cancel all current processes inside.
+
+ @param aEvent
+ describes the broadcaster and must be the frame or model instance we know
+ */
+void SAL_CALL Job::notifyClosing( const css::lang::EventObject& ) throw(css::uno::RuntimeException)
+{
+ die();
+ // Do nothing else here. Our internal ressources was released ...
+}
+
+//________________________________
+/**
+ @short shouldn't be called normaly
+ @descr But it doesn't matter, who called it. We have to kill our internal
+ running processes hardly.
+
+ @param aEvent
+ describe the broadcaster
+*/
+void SAL_CALL Job::disposing( const css::lang::EventObject& aEvent ) throw(css::uno::RuntimeException)
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_xDesktop.is() && aEvent.Source == m_xDesktop)
+ {
+ m_xDesktop = css::uno::Reference< css::frame::XDesktop >();
+ m_bListenOnDesktop = sal_False;
+ }
+ else
+ if (m_xFrame.is() && aEvent.Source == m_xFrame)
+ {
+ m_xFrame = css::uno::Reference< css::frame::XFrame >();
+ m_bListenOnFrame = sal_False;
+ }
+ else
+ if (m_xModel.is() && aEvent.Source == m_xModel)
+ {
+ m_xModel = css::uno::Reference< css::frame::XModel >();
+ m_bListenOnModel = sal_False;
+ }
+
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ die();
+ // Do nothing else here. Our internal ressources was released ...
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/jobs/jobdata.cxx b/framework/source/jobs/jobdata.cxx
new file mode 100644
index 000000000000..cef28eb08b0c
--- /dev/null
+++ b/framework/source/jobs/jobdata.cxx
@@ -0,0 +1,751 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//________________________________
+// my own includes
+#include <jobs/jobdata.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <classes/converter.hxx>
+#include <general.h>
+#include <services.h>
+
+//________________________________
+// interface includes
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+
+//________________________________
+// includes of other projects
+#include <tools/wldcrd.hxx>
+#include <unotools/configpathes.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+
+//________________________________
+// namespace
+
+namespace framework{
+
+//________________________________
+// exported const
+
+const sal_Char* JobData::JOBCFG_ROOT = "/org.openoffice.Office.Jobs/Jobs/" ;
+const sal_Char* JobData::JOBCFG_PROP_SERVICE = "Service" ;
+const sal_Char* JobData::JOBCFG_PROP_CONTEXT = "Context" ;
+const sal_Char* JobData::JOBCFG_PROP_ARGUMENTS = "Arguments" ;
+
+const sal_Char* JobData::EVENTCFG_ROOT = "/org.openoffice.Office.Jobs/Events/" ;
+const sal_Char* JobData::EVENTCFG_PATH_JOBLIST = "/JobList" ;
+const sal_Char* JobData::EVENTCFG_PROP_ADMINTIME = "AdminTime" ;
+const sal_Char* JobData::EVENTCFG_PROP_USERTIME = "UserTime" ;
+
+const sal_Char* JobData::PROPSET_CONFIG = "Config" ;
+const sal_Char* JobData::PROPSET_OWNCONFIG = "JobConfig" ;
+const sal_Char* JobData::PROPSET_ENVIRONMENT = "Environment" ;
+const sal_Char* JobData::PROPSET_DYNAMICDATA = "DynamicData" ;
+
+const sal_Char* JobData::PROP_ALIAS = "Alias" ;
+const sal_Char* JobData::PROP_EVENTNAME = "EventName" ;
+const sal_Char* JobData::PROP_ENVTYPE = "EnvType" ;
+const sal_Char* JobData::PROP_FRAME = "Frame" ;
+const sal_Char* JobData::PROP_MODEL = "Model" ;
+const sal_Char* JobData::PROP_SERVICE = "Service" ;
+const sal_Char* JobData::PROP_CONTEXT = "Context" ;
+
+//________________________________
+// non exported definitions
+
+//________________________________
+// declarations
+
+//________________________________
+/**
+ @short standard ctor
+ @descr It initialize this new instance.
+ But for real working it's neccessary to call setAlias() or setService() later.
+ Because we need the job data ...
+
+ @param xSMGR
+ reference to the uno service manager
+*/
+JobData::JobData( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ : ThreadHelpBase(&Application::GetSolarMutex())
+ , m_xSMGR (xSMGR )
+{
+ // share code for member initialization with defaults!
+ impl_reset();
+}
+
+//________________________________
+/**
+ @short copy ctor
+ @descr Sometimes such job data container must be moved from one using place
+ to another one. Then a copy ctor and copy operator must be available.
+
+ @param rCopy
+ the original instance, from which we must copy all data
+*/
+JobData::JobData( const JobData& rCopy )
+ : ThreadHelpBase(&Application::GetSolarMutex())
+{
+ // use the copy operator to share the same code
+ *this = rCopy;
+}
+
+//________________________________
+/**
+ @short operator for coping JobData instances
+ @descr Sometimes such job data container must be moved from one using place
+ to another one. Then a copy ctor and copy operator must be available.
+
+ @param rCopy
+ the original instance, from which we must copy all data
+*/
+void JobData::operator=( const JobData& rCopy )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ // Please don't copy the uno service manager reference.
+ // That can change the uno context, which isn't a good idea!
+ m_eMode = rCopy.m_eMode ;
+ m_eEnvironment = rCopy.m_eEnvironment ;
+ m_sAlias = rCopy.m_sAlias ;
+ m_sService = rCopy.m_sService ;
+ m_sContext = rCopy.m_sContext ;
+ m_sEvent = rCopy.m_sEvent ;
+ m_lArguments = rCopy.m_lArguments ;
+ m_aLastExecutionResult = rCopy.m_aLastExecutionResult;
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short let this instance die
+ @descr There is no chance any longer to work. We have to
+ release all used ressources and free used memory.
+*/
+JobData::~JobData()
+{
+ impl_reset();
+}
+
+//________________________________
+/**
+ @short initalize this instance as a job with configuration
+ @descr They given alias can be used to adress some configuraton data.
+ We read it and fill our internal structures. Of course old informations
+ will be lost doing so.
+
+ @param sAlias
+ the alias name of this job, used to locate job properties inside cfg
+*/
+void JobData::setAlias( const ::rtl::OUString& sAlias )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ // delete all old informations! Otherwhise we mix it with the new one ...
+ impl_reset();
+
+ // take over the new informations
+ m_sAlias = sAlias;
+ m_eMode = E_ALIAS;
+
+ // try to open the configuration set of this job directly and get a property access to it
+ // We open it readonly here
+ ::rtl::OUString sKey(::rtl::OUString::createFromAscii(JOBCFG_ROOT));
+ sKey += ::utl::wrapConfigurationElementName(m_sAlias);
+
+ ConfigAccess aConfig(m_xSMGR, sKey);
+ aConfig.open(ConfigAccess::E_READONLY);
+ if (aConfig.getMode()==ConfigAccess::E_CLOSED)
+ {
+ impl_reset();
+ return;
+ }
+
+ css::uno::Reference< css::beans::XPropertySet > xJobProperties(aConfig.cfg(), css::uno::UNO_QUERY);
+ if (xJobProperties.is())
+ {
+ css::uno::Any aValue;
+
+ // read uno implementation name
+ aValue = xJobProperties->getPropertyValue(::rtl::OUString::createFromAscii(JOBCFG_PROP_SERVICE));
+ aValue >>= m_sService;
+
+ // read module context list
+ aValue = xJobProperties->getPropertyValue(::rtl::OUString::createFromAscii(JOBCFG_PROP_CONTEXT));
+ aValue >>= m_sContext;
+
+ // read whole argument list
+ aValue = xJobProperties->getPropertyValue(::rtl::OUString::createFromAscii(JOBCFG_PROP_ARGUMENTS));
+ css::uno::Reference< css::container::XNameAccess > xArgumentList;
+ if (
+ (aValue >>= xArgumentList) &&
+ (xArgumentList.is() )
+ )
+ {
+ css::uno::Sequence< ::rtl::OUString > lArgumentNames = xArgumentList->getElementNames();
+ sal_Int32 nCount = lArgumentNames.getLength();
+ m_lArguments.realloc(nCount);
+ for (sal_Int32 i=0; i<nCount; ++i)
+ {
+ m_lArguments[i].Name = lArgumentNames[i];
+ m_lArguments[i].Value = xArgumentList->getByName(m_lArguments[i].Name);
+ }
+ }
+ }
+
+ aConfig.close();
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short initalize this instance as a job without configuration
+ @descr This job has no configuration data. We have to forget all old informations
+ and set only some of them new, so this instance can work.
+
+ @param sService
+ the uno service name of this "non configured" job
+*/
+void JobData::setService( const ::rtl::OUString& sService )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // delete all old informations! Otherwhise we mix it with the new one ...
+ impl_reset();
+ // take over the new informations
+ m_sService = sService;
+ m_eMode = E_SERVICE;
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short initialize this instance with new job values.
+ @descr It reads automaticly all properties of the specified
+ job (using it's alias name) and "register it" for the
+ given event. This registration will not be validated against
+ the underlying configuration! (That must be done from outside.
+ Because the caller must have the configuration already open to
+ get the values for sEvent and sAlias! And doing so it can perform
+ only, if the time stanp values are readed outside too.
+ Further it make no sense to initialize and start a disabled job.
+ So this initialization method will be called for enabled jobs only.)
+
+ @param sEvent
+ the triggered event, for which this job should be started
+
+ @param sAlias
+ mark the required job inside event registration list
+*/
+void JobData::setEvent( const ::rtl::OUString& sEvent ,
+ const ::rtl::OUString& sAlias )
+{
+ // share code to read all job properties!
+ setAlias(sAlias);
+
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // take over the new informations - which differ against set on of method setAlias()!
+ m_sEvent = sEvent;
+ m_eMode = E_EVENT;
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short set the new job specific arguments
+ @descr If a job finish his work, it can give us a new list of arguments (which
+ will not interpreted by us). We write it back to the configuration only
+ (if this job has it's own configuration!).
+ So a job can have persistent data without implementing anything
+ or define own config areas for that.
+
+ @param lArguments
+ list of arguments, which should be set for this job
+ */
+void JobData::setJobConfig( const css::uno::Sequence< css::beans::NamedValue >& lArguments )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // update member
+ m_lArguments = lArguments;
+
+ // update the configuration ... if possible!
+ if (m_eMode==E_ALIAS)
+ {
+ // It doesn't matter if this config object was already opened before.
+ // It doesn nothing here then ... or it change the mode automaticly, if
+ // it was opened using another one before.
+ ::rtl::OUString sKey(::rtl::OUString::createFromAscii(JOBCFG_ROOT));
+ sKey += ::utl::wrapConfigurationElementName(m_sAlias);
+
+ ConfigAccess aConfig(m_xSMGR, sKey);
+ aConfig.open(ConfigAccess::E_READWRITE);
+ if (aConfig.getMode()==ConfigAccess::E_CLOSED)
+ return;
+
+ css::uno::Reference< css::beans::XMultiHierarchicalPropertySet > xArgumentList(aConfig.cfg(), css::uno::UNO_QUERY);
+ if (xArgumentList.is())
+ {
+ sal_Int32 nCount = m_lArguments.getLength();
+ css::uno::Sequence< ::rtl::OUString > lNames (nCount);
+ css::uno::Sequence< css::uno::Any > lValues(nCount);
+
+ for (sal_Int32 i=0; i<nCount; ++i)
+ {
+ lNames [i] = m_lArguments[i].Name ;
+ lValues[i] = m_lArguments[i].Value;
+ }
+
+ xArgumentList->setHierarchicalPropertyValues(lNames, lValues);
+ }
+ aConfig.close();
+ }
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short set a new excution result
+ @descr Every executed job can have returned a result.
+ We set it here, so our user can use it may be later.
+ But the outside code can use it too, to analyze it and
+ adopt the configuration of this job too. Because the
+ result uses a protocol, which allow that. And we provide
+ right functionality to save it.
+
+ @param aResult
+ the result of last execution
+ */
+void JobData::setResult( const JobResult& aResult )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // overwrite the last saved result
+ m_aLastExecutionResult = aResult;
+
+ // Don't use his informations to update
+ // e.g. the arguments of this job. It must be done
+ // from outside! Here we save this information only.
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short set a new environment descriptor for this job
+ @descr It must(!) be done everytime this container is initialized
+ with new job datas e.g.: setAlias()/setEvent()/setService() ...
+ Otherwhise the environment will be unknown!
+ */
+void JobData::setEnvironment( EEnvironment eEnvironment )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ m_eEnvironment = eEnvironment;
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short these functions provides access to our internal members
+ @descr These member represent any information about the job
+ and can be used from outside to e.g. start a job.
+ */
+JobData::EMode JobData::getMode() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_eMode;
+ /* } SAFE */
+}
+
+//________________________________
+
+JobData::EEnvironment JobData::getEnvironment() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_eEnvironment;
+ /* } SAFE */
+}
+
+//________________________________
+
+::rtl::OUString JobData::getEnvironmentDescriptor() const
+{
+ ::rtl::OUString sDescriptor;
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ switch(m_eEnvironment)
+ {
+ case E_EXECUTION :
+ sDescriptor = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EXECUTOR"));
+ break;
+
+ case E_DISPATCH :
+ sDescriptor = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DISPATCH"));
+ break;
+
+ case E_DOCUMENTEVENT :
+ sDescriptor = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DOCUMENTEVENT"));
+ break;
+ default:
+ break;
+ }
+ /* } SAFE */
+ return sDescriptor;
+}
+
+//________________________________
+
+::rtl::OUString JobData::getService() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_sService;
+ /* } SAFE */
+}
+
+//________________________________
+
+::rtl::OUString JobData::getEvent() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_sEvent;
+ /* } SAFE */
+}
+
+//________________________________
+
+css::uno::Sequence< css::beans::NamedValue > JobData::getJobConfig() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_lArguments;
+ /* } SAFE */
+}
+
+//________________________________
+
+css::uno::Sequence< css::beans::NamedValue > JobData::getConfig() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Sequence< css::beans::NamedValue > lConfig;
+ if (m_eMode==E_ALIAS)
+ {
+ lConfig.realloc(3);
+ sal_Int32 i = 0;
+
+ lConfig[i].Name = ::rtl::OUString::createFromAscii(PROP_ALIAS);
+ lConfig[i].Value <<= m_sAlias;
+ ++i;
+
+ lConfig[i].Name = ::rtl::OUString::createFromAscii(PROP_SERVICE);
+ lConfig[i].Value <<= m_sService;
+ ++i;
+
+ lConfig[i].Name = ::rtl::OUString::createFromAscii(PROP_CONTEXT);
+ lConfig[i].Value <<= m_sContext;
+ ++i;
+ }
+ aReadLock.unlock();
+ /* } SAFE */
+ return lConfig;
+}
+
+//________________________________
+/**
+ @short return information, if this job is part of the global configuration package
+ org.openoffice.Office.Jobs
+ @descr Because jobs can be executed by the dispatch framework using an uno service name
+ directly - an executed job must not have any configuration realy. Such jobs
+ must provide the right interfaces only! But after finishing jobs can return
+ some informations (e.g. for updating her configuration ...). We must know
+ if such request is valid or not then.
+
+ @return sal_True if the represented job is part of the underlying configuration package.
+ */
+sal_Bool JobData::hasConfig() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return (m_eMode==E_ALIAS || m_eMode==E_EVENT);
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short mark a job as non startable for further requests
+ @descr We don't remove the configuration entry! We set a timestamp value only.
+ And there exist two of them: one for an administrator ... and one for the
+ current user. We change it for the user layer only. So this JobDispatch can't be
+ started any more ... till the administrator change his timestamp.
+ That can be usefull for post setup scenarios, which must run one time only.
+
+ Note: This method don't do anything, if ths represented job doesn't have a configuration!
+ */
+void JobData::disableJob()
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // No configuration - not used from EXECUTOR and not triggered from an event => no chance!
+ if (m_eMode!=E_EVENT)
+ return;
+
+ // update the configuration
+ // It doesn't matter if this config object was already opened before.
+ // It doesn nothing here then ... or it change the mode automaticly, if
+ // it was opened using another one before.
+ ::rtl::OUStringBuffer sKey(256);
+ sKey.appendAscii(JobData::EVENTCFG_ROOT );
+ sKey.append (::utl::wrapConfigurationElementName(m_sEvent));
+ sKey.appendAscii(JobData::EVENTCFG_PATH_JOBLIST );
+ sKey.appendAscii("/" );
+ sKey.append (::utl::wrapConfigurationElementName(m_sAlias));
+
+ ConfigAccess aConfig(m_xSMGR, sKey.makeStringAndClear());
+ aConfig.open(ConfigAccess::E_READWRITE);
+ if (aConfig.getMode()==ConfigAccess::E_CLOSED)
+ return;
+
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(aConfig.cfg(), css::uno::UNO_QUERY);
+ if (xPropSet.is())
+ {
+ // Convert and write the user timestamp to the configuration.
+ css::uno::Any aValue;
+ aValue <<= Converter::convert_DateTime2ISO8601(DateTime());
+ xPropSet->setPropertyValue(::rtl::OUString::createFromAscii(EVENTCFG_PROP_USERTIME), aValue);
+ }
+
+ aConfig.close();
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ */
+sal_Bool isEnabled( const ::rtl::OUString& sAdminTime ,
+ const ::rtl::OUString& sUserTime )
+{
+ /*Attention!
+ To prevent interpreting of TriGraphs inside next const string value,
+ we have to encode all '?' signs. Otherwhise e.g. "??-" will be translated
+ to "~" ...
+ */
+ static ::rtl::OUString PATTERN_ISO8601(RTL_CONSTASCII_USTRINGPARAM("\?\?\?\?-\?\?-\?\?*\0"));
+ WildCard aISOPattern(PATTERN_ISO8601);
+
+ sal_Bool bValidAdmin = aISOPattern.Matches(sAdminTime);
+ sal_Bool bValidUser = aISOPattern.Matches(sUserTime );
+
+ // We check for "isEnabled()" here only.
+ // Note further: ISO8601 formated strings can be compared as strings directly!
+ return (
+ (!bValidAdmin && !bValidUser ) ||
+ ( bValidAdmin && bValidUser && sAdminTime>=sUserTime)
+ );
+}
+
+//________________________________
+/**
+ */
+void JobData::appendEnabledJobsForEvent( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const ::rtl::OUString& sEvent ,
+ ::comphelper::SequenceAsVector< JobData::TJob2DocEventBinding >& lJobs )
+{
+ css::uno::Sequence< ::rtl::OUString > lAdditionalJobs = JobData::getEnabledJobsForEvent(xSMGR, sEvent);
+ sal_Int32 c = lAdditionalJobs.getLength();
+ sal_Int32 i = 0;
+
+ for (i=0; i<c; ++i)
+ {
+ JobData::TJob2DocEventBinding aBinding(lAdditionalJobs[i], sEvent);
+ lJobs.push_back(aBinding);
+ }
+}
+
+//________________________________
+/**
+ */
+sal_Bool JobData::hasCorrectContext(const ::rtl::OUString& rModuleIdent) const
+{
+ sal_Int32 nContextLen = m_sContext.getLength();
+ sal_Int32 nModuleIdLen = rModuleIdent.getLength();
+
+ if ( nContextLen == 0 )
+ return sal_True;
+
+ if ( nModuleIdLen > 0 )
+ {
+ sal_Int32 nIndex = m_sContext.indexOf( rModuleIdent );
+ if ( nIndex >= 0 && ( nIndex+nModuleIdLen <= nContextLen ))
+ {
+ ::rtl::OUString sContextModule = m_sContext.copy( nIndex, nModuleIdLen );
+ return sContextModule.equals( rModuleIdent );
+ }
+ }
+
+ return sal_False;
+}
+
+//________________________________
+/**
+ */
+css::uno::Sequence< ::rtl::OUString > JobData::getEnabledJobsForEvent( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const ::rtl::OUString& sEvent )
+{
+ // these static values may perform following loop for reading time stamp values ...
+ static ::rtl::OUString ADMINTIME = ::rtl::OUString::createFromAscii(JobData::EVENTCFG_PROP_ADMINTIME);
+ static ::rtl::OUString USERTIME = ::rtl::OUString::createFromAscii(JobData::EVENTCFG_PROP_USERTIME );
+ static ::rtl::OUString ROOT = ::rtl::OUString::createFromAscii(JobData::EVENTCFG_ROOT );
+ static ::rtl::OUString JOBLIST = ::rtl::OUString::createFromAscii(JobData::EVENTCFG_PATH_JOBLIST );
+
+ // create a config access to "/org.openoffice.Office.Jobs/Events"
+ ConfigAccess aConfig(xSMGR,ROOT);
+ aConfig.open(ConfigAccess::E_READONLY);
+ if (aConfig.getMode()==ConfigAccess::E_CLOSED)
+ return css::uno::Sequence< ::rtl::OUString >();
+
+ css::uno::Reference< css::container::XHierarchicalNameAccess > xEventRegistry(aConfig.cfg(), css::uno::UNO_QUERY);
+ if (!xEventRegistry.is())
+ return css::uno::Sequence< ::rtl::OUString >();
+
+ // check if the given event exist inside list of registered ones
+ ::rtl::OUString sPath(sEvent);
+ sPath += JOBLIST;
+ if (!xEventRegistry->hasByHierarchicalName(sPath))
+ return css::uno::Sequence< ::rtl::OUString >();
+
+ // step to the job list, which is a child of the event node inside cfg
+ // e.g. "/org.openoffice.Office.Jobs/Events/<event name>/JobList"
+ css::uno::Any aJobList = xEventRegistry->getByHierarchicalName(sPath);
+ css::uno::Reference< css::container::XNameAccess > xJobList;
+ if (!(aJobList >>= xJobList) || !xJobList.is())
+ return css::uno::Sequence< ::rtl::OUString >();
+
+ // get all alias names of jobs, which are part of this job list
+ // But Some of them can be disabled by it's time stamp values.
+ // We create an additional job name list iwth the same size, then the original list ...
+ // step over all job entries ... check her time stamps ... and put only job names to the
+ // destination list, which represent an enabled job.
+ css::uno::Sequence< ::rtl::OUString > lAllJobs = xJobList->getElementNames();
+ ::rtl::OUString* pAllJobs = lAllJobs.getArray();
+ sal_Int32 c = lAllJobs.getLength();
+
+ css::uno::Sequence< ::rtl::OUString > lEnabledJobs(c);
+ ::rtl::OUString* pEnabledJobs = lEnabledJobs.getArray();
+ sal_Int32 d = 0;
+
+ for (sal_Int32 s=0; s<c; ++s)
+ {
+ css::uno::Reference< css::beans::XPropertySet > xJob;
+ if (
+ !(xJobList->getByName(pAllJobs[s]) >>= xJob) ||
+ !(xJob.is() )
+ )
+ {
+ continue;
+ }
+
+ ::rtl::OUString sAdminTime;
+ xJob->getPropertyValue(ADMINTIME) >>= sAdminTime;
+
+ ::rtl::OUString sUserTime;
+ xJob->getPropertyValue(USERTIME) >>= sUserTime;
+
+ if (!isEnabled(sAdminTime, sUserTime))
+ continue;
+
+ pEnabledJobs[d] = pAllJobs[s];
+ ++d;
+ }
+ lEnabledJobs.realloc(d);
+
+ aConfig.close();
+
+ return lEnabledJobs;
+}
+
+//________________________________
+/**
+ @short reset all internal structures
+ @descr If somehwere recycle this instance, he can switch from one
+ using mode to another one. But then we have to reset all currently
+ used informations. Otherwhise we mix it and they can make trouble.
+
+ But note: that does not set defaults for internal used members, which
+ does not relate to any job property! e.g. the reference to the global
+ uno service manager. Such informations are used for internal processes only
+ and are neccessary for our work.
+ */
+void JobData::impl_reset()
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ m_eMode = E_UNKNOWN_MODE;
+ m_eEnvironment = E_UNKNOWN_ENVIRONMENT;
+ m_sAlias = ::rtl::OUString();
+ m_sService = ::rtl::OUString();
+ m_sContext = ::rtl::OUString();
+ m_sEvent = ::rtl::OUString();
+ m_lArguments = css::uno::Sequence< css::beans::NamedValue >();
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/jobs/jobdispatch.cxx b/framework/source/jobs/jobdispatch.cxx
new file mode 100644
index 000000000000..e3bd10fb3d83
--- /dev/null
+++ b/framework/source/jobs/jobdispatch.cxx
@@ -0,0 +1,497 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//________________________________
+// my own includes
+#include <jobs/jobdispatch.hxx>
+#include <jobs/joburl.hxx>
+#include <jobs/job.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <classes/converter.hxx>
+#include <general.h>
+#include <services.h>
+
+//________________________________
+// interface includes
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+
+//________________________________
+// includes of other projects
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+
+//________________________________
+// namespace
+
+namespace framework{
+
+//________________________________
+// non exported const
+
+//________________________________
+// non exported definitions
+
+//________________________________
+// declarations
+
+DEFINE_XINTERFACE_6( JobDispatch ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::frame::XDispatchProvider ),
+ DIRECT_INTERFACE(css::lang::XInitialization ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo),
+ DIRECT_INTERFACE(css::frame::XNotifyingDispatch),
+ DIRECT_INTERFACE(css::frame::XDispatch )
+ )
+
+DEFINE_XTYPEPROVIDER_6( JobDispatch ,
+ css::lang::XTypeProvider ,
+ css::frame::XDispatchProvider ,
+ css::frame::XNotifyingDispatch,
+ css::lang::XInitialization,
+ css::lang::XServiceInfo,
+ css::frame::XDispatch
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE( JobDispatch ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_PROTOCOLHANDLER ,
+ IMPLEMENTATIONNAME_JOBDISPATCH
+ )
+
+DEFINE_INIT_SERVICE( JobDispatch,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+ )
+
+//________________________________
+/**
+ @short standard ctor
+ @descr It initialize this new instance.
+
+ @param xSMGR
+ reference to the uno service manager
+*/
+JobDispatch::JobDispatch( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ : ThreadHelpBase(&Application::GetSolarMutex())
+ , OWeakObject ( )
+ , m_xSMGR (xSMGR )
+{
+}
+
+//________________________________
+/**
+ @short let this instance die
+ @descr We have to release all used ressources and free used memory.
+*/
+JobDispatch::~JobDispatch()
+{
+ // release all used ressources
+ m_xSMGR = css::uno::Reference< css::lang::XMultiServiceFactory >();
+ m_xFrame = css::uno::Reference< css::frame::XFrame >();
+}
+
+//________________________________
+/**
+ @short implementation of XInitalization
+ @descr A protocol handler can provide this functionality, if it wish to get additional informations
+ about the context it runs. In this case the frame reference would be given by the outside code.
+
+ @param lArguments
+ the list of initialization arguments
+ First parameter should be the frame reference we need.
+*/
+void SAL_CALL JobDispatch::initialize( const css::uno::Sequence< css::uno::Any >& lArguments ) throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ for (int a=0; a<lArguments.getLength(); ++a)
+ {
+ if (a==0)
+ {
+ lArguments[a] >>= m_xFrame;
+
+ css::uno::Reference< css::frame::XModuleManager > xModuleManager(
+ m_xSMGR->createInstance(
+ SERVICENAME_MODULEMANAGER ),
+ css::uno::UNO_QUERY_THROW );
+ try
+ {
+ m_sModuleIdentifier = xModuleManager->identify( m_xFrame );
+ }
+ catch( css::uno::Exception& )
+ {}
+ }
+ }
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short implementation of XDispatchProvider::queryDispatches()
+ @descr Every protocol handler will be asked for his agreement, if an URL was queried
+ for which this handler is registered. It's the chance for this handler to validate
+ the given URL and return a dispatch object (may be itself) or not.
+
+ @param aURL
+ the queried URL, which should be checked
+
+ @param sTargetFrameName
+ describes the target frame, in which context this handler will be used
+ Is mostly set to "", "_self", "_blank", "_default" or a non special one
+ using SELF/CREATE as search flags.
+
+ @param nSearchFlags
+ Can be SELF or CREATE only and are set only if sTargetFrameName isn't a special target
+*/
+css::uno::Reference< css::frame::XDispatch > SAL_CALL JobDispatch::queryDispatch( /*IN*/ const css::util::URL& aURL ,
+ /*IN*/ const ::rtl::OUString& /*sTargetFrameName*/ ,
+ /*IN*/ sal_Int32 /*nSearchFlags*/ ) throw(css::uno::RuntimeException)
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatch;
+
+ JobURL aAnalyzedURL(aURL.Complete);
+ if (aAnalyzedURL.isValid())
+ xDispatch = css::uno::Reference< css::frame::XDispatch >( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+
+ return xDispatch;
+}
+
+//________________________________
+/**
+ @short implementation of XDispatchProvider::queryDispatches()
+ @descr It's an optimized access for remote, so you can ask for
+ multiple dispatch objects at the same time.
+
+ @param lDescriptor
+ a list of queryDispatch() parameter
+
+ @return A list of corresponding dispatch objects.
+ NULL references are not skipped. Every result
+ match to one given descriptor item.
+*/
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL JobDispatch::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw(css::uno::RuntimeException)
+{
+ // don't pack resulting list!
+ sal_Int32 nCount = lDescriptor.getLength();
+ css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatches(nCount);
+
+ for (sal_Int32 i=0; i<nCount; ++i)
+ lDispatches[i] = queryDispatch( lDescriptor[i].FeatureURL ,
+ lDescriptor[i].FrameName ,
+ lDescriptor[i].SearchFlags );
+ return lDispatches;
+}
+
+//________________________________
+/**
+ @short implementation of XNotifyingDispatch::dispatchWithNotification()
+ @descr It creates the job service implementation and call execute on it.
+ Further it starts the life time control of it. (important for async job)
+ For synchonrous job we react for the returned result directly ... for asynchronous
+ ones we do it later inside our callback method. But we use the same impl method
+ doing that to share the code. (see impl_finishJob())
+
+ If a job is already running, (it can only occure for asynchronous jobs)
+ don't start the same job a second time. Queue in the given dispatch parameter
+ and return immediatly. If the current running job call us back, we will start this
+ new dispatch request.
+ If no job is running - queue the parameter too! But then start the new job immediatly.
+ We have to queue it every time - because it hold us alive by ref count!
+
+ @param aURL
+ describe the job(s), which should be started
+
+ @param lArgs
+ optional arguments for this request
+
+ @param xListener
+ an interested listener for possible results of this operation
+*/
+void SAL_CALL JobDispatch::dispatchWithNotification( /*IN*/ const css::util::URL& aURL ,
+ /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
+ /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw(css::uno::RuntimeException)
+{
+ JobURL aAnalyzedURL(aURL.Complete);
+ if (aAnalyzedURL.isValid())
+ {
+ ::rtl::OUString sRequest;
+ if (aAnalyzedURL.getEvent(sRequest))
+ impl_dispatchEvent(sRequest, lArgs, xListener);
+ else
+ if (aAnalyzedURL.getService(sRequest))
+ impl_dispatchService(sRequest, lArgs, xListener);
+ else
+ if (aAnalyzedURL.getAlias(sRequest))
+ impl_dispatchAlias(sRequest, lArgs, xListener);
+ }
+}
+
+//________________________________
+/**
+ @short dispatch an event
+ @descr We search all registered jobs for this event and execute it.
+ After doing so, we inform the given listener about the results.
+ (There will be one notify for every executed job!)
+
+ @param sEvent
+ the event, for which jobs can be registered
+
+ @param lArgs
+ optional arguments for this request
+ Currently not used!
+
+ @param xListener
+ an interested listener for possible results of this operation
+*/
+void JobDispatch::impl_dispatchEvent( /*IN*/ const ::rtl::OUString& sEvent ,
+ /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
+ /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
+{
+ // get list of all enabled jobs
+ // The called static helper methods read it from the configuration and
+ // filter disabled jobs using it's time stamp values.
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Sequence< ::rtl::OUString > lJobs = JobData::getEnabledJobsForEvent(m_xSMGR, sEvent);
+ aReadLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+
+ // no jobs ... no execution
+ // But a may given listener will know something ...
+ // I think this operaton was finished successfully.
+ // It's not realy an error, if no registered jobs could be located.
+ // Step over all found jobs and execute it
+ int nExecutedJobs=0;
+ for (int j=0; j<lJobs.getLength(); ++j)
+ {
+ /* SAFE { */
+ aReadLock.lock();
+
+ JobData aCfg(m_xSMGR);
+ aCfg.setEvent(sEvent, lJobs[j]);
+ aCfg.setEnvironment(JobData::E_DISPATCH);
+ const bool bIsEnabled=aCfg.hasCorrectContext(m_sModuleIdentifier);
+
+ /*Attention!
+ Jobs implements interfaces and dies by ref count!
+ And freeing of such uno object is done by uno itself.
+ So we have to use dynamic memory everytimes.
+ */
+ Job* pJob = new Job(m_xSMGR, m_xFrame);
+ css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
+ pJob->setJobData(aCfg);
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ if (!bIsEnabled)
+ continue;
+
+ // Special mode for listener.
+ // We dont notify it directly here. We delegate that
+ // to the job implementation. But we must set ourself there too.
+ // Because this job must fake the source adress of the event.
+ // Otherwhise the listener may will ignore it.
+ if (xListener.is())
+ pJob->setDispatchResultFake(xListener, xThis);
+ pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
+ ++nExecutedJobs;
+ }
+
+ if (nExecutedJobs<1 && xListener.is())
+ {
+ css::frame::DispatchResultEvent aEvent;
+ aEvent.Source = xThis;
+ aEvent.State = css::frame::DispatchResultState::SUCCESS;
+ xListener->dispatchFinished(aEvent);
+ }
+}
+
+//________________________________
+/**
+ @short dispatch a service
+ @descr We use the given name only to create and if possible to initialize
+ it as an uno service. It can be usefully for creating (caching?)
+ of e.g. one instance services.
+
+ @param sService
+ the uno implementation or service name of the job, which should be instanciated
+
+ @param lArgs
+ optional arguments for this request
+ Currently not used!
+
+ @param xListener
+ an interested listener for possible results of this operation
+*/
+void JobDispatch::impl_dispatchService( /*IN*/ const ::rtl::OUString& sService ,
+ /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
+ /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ JobData aCfg(m_xSMGR);
+ aCfg.setService(sService);
+ aCfg.setEnvironment(JobData::E_DISPATCH);
+
+ /*Attention!
+ Jobs implements interfaces and dies by ref count!
+ And freeing of such uno object is done by uno itself.
+ So we have to use dynamic memory everytimes.
+ */
+ Job* pJob = new Job(m_xSMGR, m_xFrame);
+ css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
+ pJob->setJobData(aCfg);
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+
+ // Special mode for listener.
+ // We dont notify it directly here. We delegate that
+ // to the job implementation. But we must set ourself there too.
+ // Because this job must fake the source adress of the event.
+ // Otherwhise the listener may will ignore it.
+ if (xListener.is())
+ pJob->setDispatchResultFake(xListener, xThis);
+ pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
+}
+
+//________________________________
+/**
+ @short dispatch an alias
+ @descr We use this alias to locate a job inside the configuration
+ and execute it. Further we inform the given listener about the results.
+
+ @param sAlias
+ the alias name of the configured job
+
+ @param lArgs
+ optional arguments for this request
+ Currently not used!
+
+ @param xListener
+ an interested listener for possible results of this operation
+*/
+void JobDispatch::impl_dispatchAlias( /*IN*/ const ::rtl::OUString& sAlias ,
+ /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ,
+ /*IN*/ const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ JobData aCfg(m_xSMGR);
+ aCfg.setAlias(sAlias);
+ aCfg.setEnvironment(JobData::E_DISPATCH);
+
+ /*Attention!
+ Jobs implements interfaces and dies by ref count!
+ And freeing of such uno object is done by uno itself.
+ So we have to use dynamic memory everytimes.
+ */
+ Job* pJob = new Job(m_xSMGR, m_xFrame);
+ css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
+ pJob->setJobData(aCfg);
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::frame::XDispatchResultListener > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+
+ // Special mode for listener.
+ // We dont notify it directly here. We delegate that
+ // to the job implementation. But we must set ourself there too.
+ // Because this job must fake the source adress of the event.
+ // Otherwhise the listener may will ignore it.
+ if (xListener.is())
+ pJob->setDispatchResultFake(xListener, xThis);
+ pJob->execute(Converter::convert_seqPropVal2seqNamedVal(lArgs));
+}
+
+//________________________________
+/**
+ @short implementation of XDispatch::dispatch()
+ @descr Because the methods dispatch() and dispatchWithNotification() are different in her parameters
+ only, we can forward this request to dispatchWithNotification() by using an empty listener!
+
+ @param aURL
+ describe the job(s), which should be started
+
+ @param lArgs
+ optional arguments for this request
+
+ @see dispatchWithNotification()
+*/
+void SAL_CALL JobDispatch::dispatch( /*IN*/ const css::util::URL& aURL ,
+ /*IN*/ const css::uno::Sequence< css::beans::PropertyValue >& lArgs ) throw(css::uno::RuntimeException)
+{
+ dispatchWithNotification(aURL, lArgs, css::uno::Reference< css::frame::XDispatchResultListener >());
+}
+
+//________________________________
+/**
+ @short not supported
+*/
+void SAL_CALL JobDispatch::addStatusListener( /*IN*/ const css::uno::Reference< css::frame::XStatusListener >&,
+ /*IN*/ const css::util::URL& ) throw(css::uno::RuntimeException)
+{
+}
+
+//________________________________
+/**
+ @short not supported
+*/
+void SAL_CALL JobDispatch::removeStatusListener( /*IN*/ const css::uno::Reference< css::frame::XStatusListener >&,
+ /*IN*/ const css::util::URL& ) throw(css::uno::RuntimeException)
+{
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/jobs/jobexecutor.cxx b/framework/source/jobs/jobexecutor.cxx
new file mode 100644
index 000000000000..8d773f208ceb
--- /dev/null
+++ b/framework/source/jobs/jobexecutor.cxx
@@ -0,0 +1,388 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//________________________________
+// my own includes
+#include <jobs/jobexecutor.hxx>
+#include <jobs/job.hxx>
+#include <jobs/joburl.hxx>
+
+#include <classes/converter.hxx>
+#include <threadhelp/transactionguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <general.h>
+#include <services.h>
+
+#include "helper/mischelper.hxx"
+
+//________________________________
+// interface includes
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+
+//________________________________
+// includes of other projects
+#include <unotools/configpathes.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+
+#include <rtl/logfile.hxx>
+
+//________________________________
+// namespace
+
+namespace framework{
+
+//________________________________
+// non exported const
+
+//________________________________
+// non exported definitions
+
+//________________________________
+// declarations
+
+DEFINE_XINTERFACE_6( JobExecutor ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::task::XJobExecutor ),
+ DIRECT_INTERFACE(css::container::XContainerListener ),
+ DIRECT_INTERFACE(css::document::XEventListener ),
+ DERIVED_INTERFACE(css::lang::XEventListener,css::document::XEventListener)
+ )
+
+DEFINE_XTYPEPROVIDER_6( JobExecutor ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::task::XJobExecutor ,
+ css::container::XContainerListener,
+ css::document::XEventListener ,
+ css::lang::XEventListener
+ )
+
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE( JobExecutor ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_JOBEXECUTOR ,
+ IMPLEMENTATIONNAME_JOBEXECUTOR
+ )
+
+DEFINE_INIT_SERVICE( JobExecutor,
+ {
+ m_xModuleManager = css::uno::Reference< css::frame::XModuleManager >(
+ m_xSMGR->createInstance(
+ SERVICENAME_MODULEMANAGER ),
+ css::uno::UNO_QUERY_THROW );
+
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ // read the list of all currently registered events inside configuration.
+ // e.g. "/org.openoffice.Office.Jobs/Events/<event name>"
+ // We need it later to check if an incoming event request can be executed successfully
+ // or must be rejected. It's an optimization! Of course we must implement updating of this
+ // list too ... Be listener at the configuration.
+
+ m_aConfig.open(ConfigAccess::E_READONLY);
+ if (m_aConfig.getMode() == ConfigAccess::E_READONLY)
+ {
+ css::uno::Reference< css::container::XNameAccess > xRegistry(m_aConfig.cfg(), css::uno::UNO_QUERY);
+ if (xRegistry.is())
+ m_lEvents = Converter::convert_seqOUString2OUStringList(xRegistry->getElementNames());
+
+ css::uno::Reference< css::container::XContainer > xNotifier(m_aConfig.cfg(), css::uno::UNO_QUERY);
+ if (xNotifier.is())
+ {
+ m_xConfigListener = new WeakContainerListener(this);
+ xNotifier->addContainerListener(m_xConfigListener);
+ }
+
+ // don't close cfg here!
+ // It will be done inside disposing ...
+ }
+ }
+ )
+
+//________________________________
+
+/**
+ @short standard ctor
+ @descr It initialize this new instance.
+
+ @param xSMGR
+ reference to the uno service manager
+ */
+JobExecutor::JobExecutor( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ : ThreadHelpBase (&Application::GetSolarMutex() )
+ , ::cppu::OWeakObject ( )
+ , m_xSMGR (xSMGR )
+ , m_xModuleManager ( )
+ , m_aConfig (xSMGR, ::rtl::OUString::createFromAscii(JobData::EVENTCFG_ROOT) )
+{
+ // Don't do any reference related code here! Do it inside special
+ // impl_ method() ... see DEFINE_INIT_SERVICE() macro for further informations.
+}
+
+JobExecutor::~JobExecutor()
+{
+ css::uno::Reference< css::container::XContainer > xNotifier(m_aConfig.cfg(), css::uno::UNO_QUERY);
+ if (xNotifier.is())
+ xNotifier->removeContainerListener(m_xConfigListener);
+ LOG_ASSERT(m_aConfig.getMode() == ConfigAccess::E_CLOSED, "JobExecutor::~JobExecutor()\nConfiguration don't send dispoing() message!\n")
+}
+
+//________________________________
+
+/**
+ @short implementation of XJobExecutor interface
+ @descr We use the given event to locate any registered job inside our configuration
+ and execute it. Further we control the lifetime of it and supress
+ shutdown of the office till all jobs was finished.
+
+ @param sEvent
+ is used to locate registered jobs
+ */
+void SAL_CALL JobExecutor::trigger( const ::rtl::OUString& sEvent ) throw(css::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT(aLog, "fwk (as96863) JobExecutor::trigger()");
+
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ // Optimization!
+ // Check if the given event name exist inside configuration and reject wrong requests.
+ // This optimization supress using of the cfg api for getting event and job descriptions ...
+ if (m_lEvents.find(sEvent) == m_lEvents.end())
+ return;
+
+ // get list of all enabled jobs
+ // The called static helper methods read it from the configuration and
+ // filter disabled jobs using it's time stamp values.
+ css::uno::Sequence< ::rtl::OUString > lJobs = JobData::getEnabledJobsForEvent(m_xSMGR, sEvent);
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ // step over all enabled jobs and execute it
+ sal_Int32 c = lJobs.getLength();
+ for (sal_Int32 j=0; j<c; ++j)
+ {
+ /* SAFE { */
+ aReadLock.lock();
+
+ JobData aCfg(m_xSMGR);
+ aCfg.setEvent(sEvent, lJobs[j]);
+ aCfg.setEnvironment(JobData::E_EXECUTION);
+
+ /*Attention!
+ Jobs implements interfaces and dies by ref count!
+ And freeing of such uno object is done by uno itself.
+ So we have to use dynamic memory everytimes.
+ */
+ Job* pJob = new Job(m_xSMGR, css::uno::Reference< css::frame::XFrame >());
+ css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
+ pJob->setJobData(aCfg);
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ pJob->execute(css::uno::Sequence< css::beans::NamedValue >());
+ }
+}
+
+//________________________________
+
+void SAL_CALL JobExecutor::notifyEvent( const css::document::EventObject& aEvent ) throw(css::uno::RuntimeException)
+{
+ static ::rtl::OUString EVENT_ON_NEW = DECLARE_ASCII("OnNew" ); // Doc UI event
+ static ::rtl::OUString EVENT_ON_LOAD = DECLARE_ASCII("OnLoad" ); // Doc UI event
+ static ::rtl::OUString EVENT_ON_CREATE = DECLARE_ASCII("OnCreate" ); // Doc API event
+ static ::rtl::OUString EVENT_ON_LOAD_FINISHED = DECLARE_ASCII("OnLoadFinished" ); // Doc API event
+ static ::rtl::OUString EVENT_ON_DOCUMENT_OPENED = DECLARE_ASCII("onDocumentOpened" ); // Job UI event : OnNew or OnLoad
+ static ::rtl::OUString EVENT_ON_DOCUMENT_ADDED = DECLARE_ASCII("onDocumentAdded" ); // Job API event : OnCreate or OnLoadFinished
+
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ ::comphelper::SequenceAsVector< JobData::TJob2DocEventBinding > lJobs;
+
+ // Optimization!
+ // Check if the given event name exist inside configuration and reject wrong requests.
+ // This optimization supress using of the cfg api for getting event and job descriptions.
+ // see using of m_lEvents.find() below ...
+
+ // retrieve event context from event source
+ rtl::OUString aModuleIdentifier;
+ try
+ {
+ aModuleIdentifier = m_xModuleManager->identify( aEvent.Source );
+ }
+ catch( css::uno::Exception& )
+ {}
+
+ // Special feature: If the events "OnNew" or "OnLoad" occures - we generate our own event "onDocumentOpened".
+ if (
+ (aEvent.EventName.equals(EVENT_ON_NEW )) ||
+ (aEvent.EventName.equals(EVENT_ON_LOAD))
+ )
+ {
+ if (m_lEvents.find(EVENT_ON_DOCUMENT_OPENED) != m_lEvents.end())
+ JobData::appendEnabledJobsForEvent(m_xSMGR, EVENT_ON_DOCUMENT_OPENED, lJobs);
+ }
+
+ // Special feature: If the events "OnCreate" or "OnLoadFinished" occures - we generate our own event "onDocumentAdded".
+ if (
+ (aEvent.EventName.equals(EVENT_ON_CREATE )) ||
+ (aEvent.EventName.equals(EVENT_ON_LOAD_FINISHED))
+ )
+ {
+ if (m_lEvents.find(EVENT_ON_DOCUMENT_ADDED) != m_lEvents.end())
+ JobData::appendEnabledJobsForEvent(m_xSMGR, EVENT_ON_DOCUMENT_ADDED, lJobs);
+ }
+
+ // Add all jobs for "real" notified event too .-)
+ if (m_lEvents.find(aEvent.EventName) != m_lEvents.end())
+ JobData::appendEnabledJobsForEvent(m_xSMGR, aEvent.EventName, lJobs);
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ // step over all enabled jobs and execute it
+ ::comphelper::SequenceAsVector< JobData::TJob2DocEventBinding >::const_iterator pIt;
+ for ( pIt = lJobs.begin();
+ pIt != lJobs.end() ;
+ ++pIt )
+ {
+ /* SAFE { */
+ aReadLock.lock();
+
+ const JobData::TJob2DocEventBinding& rBinding = *pIt;
+
+ JobData aCfg(m_xSMGR);
+ aCfg.setEvent(rBinding.m_sDocEvent, rBinding.m_sJobName);
+ aCfg.setEnvironment(JobData::E_DOCUMENTEVENT);
+
+ if (!aCfg.hasCorrectContext(aModuleIdentifier))
+ continue;
+
+ /*Attention!
+ Jobs implements interfaces and dies by ref count!
+ And freeing of such uno object is done by uno itself.
+ So we have to use dynamic memory everytimes.
+ */
+ css::uno::Reference< css::frame::XModel > xModel(aEvent.Source, css::uno::UNO_QUERY);
+ Job* pJob = new Job(m_xSMGR, xModel);
+ css::uno::Reference< css::uno::XInterface > xJob(static_cast< ::cppu::OWeakObject* >(pJob), css::uno::UNO_QUERY);
+ pJob->setJobData(aCfg);
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ pJob->execute(css::uno::Sequence< css::beans::NamedValue >());
+ }
+}
+
+//________________________________
+
+void SAL_CALL JobExecutor::elementInserted( const css::container::ContainerEvent& aEvent ) throw(css::uno::RuntimeException)
+{
+ ::rtl::OUString sValue;
+ if (aEvent.Accessor >>= sValue)
+ {
+ ::rtl::OUString sEvent = ::utl::extractFirstFromConfigurationPath(sValue);
+ if (sEvent.getLength() > 0)
+ {
+ OUStringList::iterator pEvent = m_lEvents.find(sEvent);
+ if (pEvent == m_lEvents.end())
+ m_lEvents.push_back(sEvent);
+ }
+ }
+}
+
+void SAL_CALL JobExecutor::elementRemoved ( const css::container::ContainerEvent& aEvent ) throw(css::uno::RuntimeException)
+{
+ ::rtl::OUString sValue;
+ if (aEvent.Accessor >>= sValue)
+ {
+ ::rtl::OUString sEvent = ::utl::extractFirstFromConfigurationPath(sValue);
+ if (sEvent.getLength() > 0)
+ {
+ OUStringList::iterator pEvent = m_lEvents.find(sEvent);
+ if (pEvent != m_lEvents.end())
+ m_lEvents.erase(pEvent);
+ }
+ }
+}
+
+void SAL_CALL JobExecutor::elementReplaced( const css::container::ContainerEvent& ) throw(css::uno::RuntimeException)
+{
+ // I'm not interested on changed items :-)
+}
+
+//________________________________
+
+/** @short the used cfg changes notifier wish to be released in its reference.
+
+ @descr We close our internal used configuration instance to
+ free this reference.
+
+ @attention For the special feature "bind global document event broadcaster to job execution"
+ this job executor instance was registered from outside code as
+ css.document.XEventListener. So it can be, that this disposing call comes from
+ the global event broadcaster service. But we don't hold any reference to this service
+ which can or must be released. Because this broadcaster itself is an one instance service
+ too, we can ignore this request. On the other side we must relase our internal CFG
+ reference ... SOLUTION => check the given event source and react only, if it's our internal
+ hold configuration object!
+ */
+void SAL_CALL JobExecutor::disposing( const css::lang::EventObject& aEvent ) throw(css::uno::RuntimeException)
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::uno::XInterface > xCFG(m_aConfig.cfg(), css::uno::UNO_QUERY);
+ if (
+ (xCFG == aEvent.Source ) &&
+ (m_aConfig.getMode() != ConfigAccess::E_CLOSED)
+ )
+ {
+ m_aConfig.close();
+ }
+ aReadLock.unlock();
+ /* } SAFE */
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/jobs/jobresult.cxx b/framework/source/jobs/jobresult.cxx
new file mode 100644
index 000000000000..c801ef469bc3
--- /dev/null
+++ b/framework/source/jobs/jobresult.cxx
@@ -0,0 +1,264 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//________________________________
+// my own includes
+
+#include <jobs/jobresult.hxx>
+#include <jobs/jobconst.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <general.h>
+#include <services.h>
+
+//________________________________
+// interface includes
+
+//________________________________
+// includes of other projects
+
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+
+//________________________________
+// namespace
+
+namespace framework{
+
+//________________________________
+// non exported const
+
+//________________________________
+// non exported definitions
+
+//________________________________
+// declarations
+
+//________________________________
+/**
+ @short standard dtor
+ @descr It does nothing else ...
+ but it marks this new instance as non valid!
+*/
+JobResult::JobResult()
+ : ThreadHelpBase(&Application::GetSolarMutex())
+{
+ // reset the flag mask!
+ // It will reset the accessible state of this object.
+ // That can be usefull if something will fail here ...
+ m_eParts = E_NOPART;
+}
+
+//________________________________
+/**
+ @short special ctor
+ @descr It initialize this new instance with a pure job execution result
+ and analyze it. Doing so, we update our other members.
+
+ <p>
+ It's a list of named values, packed inside this any.
+ Following protocol is used:
+ <p>
+ <ul>
+ <li>
+ "SaveArguments" [sequence< css.beans.NamedValue >]
+ <br>
+ The returned list of (for this generic implementation unknown!)
+ properties, will be written directly to the configuration and replace
+ any old values there. There will no check for changes and we doesn't
+ support any mege feature here. They are written only. The job has
+ to modify this list.
+ </li>
+ <li>
+ "SendDispatchResult" [css.frame.DispatchResultEvent]
+ <br>
+ The given event is send to all current registered listener.
+ But it's not guaranteed. In case no listener are available or
+ this job isn't part of the dispatch environment (because it was used
+ by the css..task.XJobExecutor->trigger() implementation) this option
+ will be ignored.
+ </li>
+ <li>
+ "Deactivate" [boolean]
+ <br>
+ The job whish to be disabled. But note: There is no way, to enable it later
+ again by using this implementation. It can be done by using the configuration
+ only. (Means to register this job again.)
+ If a job knows, that there exist some status or result listener, it must use
+ the options "SendDispatchStatus" and "SendDispatchResult" (see before) too, to
+ inform it about the deactivation of this service.
+ </li>
+ </ul>
+
+ @param aResult
+ the job result
+*/
+JobResult::JobResult( /*IN*/ const css::uno::Any& aResult )
+ : ThreadHelpBase(&Application::GetSolarMutex())
+{
+ // safe the pure result
+ // May someone need it later ...
+ m_aPureResult = aResult;
+
+ // reset the flag mask!
+ // It will reset the accessible state of this object.
+ // That can be usefull if something will fail here ...
+ m_eParts = E_NOPART;
+
+ // analyze the result and update our other members
+ ::comphelper::SequenceAsHashMap aProtocol(aResult);
+ if ( aProtocol.empty() )
+ return;
+
+ ::comphelper::SequenceAsHashMap::const_iterator pIt = aProtocol.end();
+
+ pIt = aProtocol.find(JobConst::ANSWER_DEACTIVATE_JOB());
+ if (pIt != aProtocol.end())
+ {
+ pIt->second >>= m_bDeactivate;
+ if (m_bDeactivate)
+ m_eParts |= E_DEACTIVATE;
+ }
+
+ pIt = aProtocol.find(JobConst::ANSWER_SAVE_ARGUMENTS());
+ if (pIt != aProtocol.end())
+ {
+ pIt->second >>= m_lArguments;
+ if (m_lArguments.getLength() > 0)
+ m_eParts |= E_ARGUMENTS;
+ }
+
+ pIt = aProtocol.find(JobConst::ANSWER_SEND_DISPATCHRESULT());
+ if (pIt != aProtocol.end())
+ {
+ if (pIt->second >>= m_aDispatchResult)
+ m_eParts |= E_DISPATCHRESULT;
+ }
+}
+
+//________________________________
+/**
+ @short copy dtor
+ @descr -
+*/
+JobResult::JobResult( const JobResult& rCopy )
+ : ThreadHelpBase(&Application::GetSolarMutex())
+{
+ m_aPureResult = rCopy.m_aPureResult ;
+ m_eParts = rCopy.m_eParts ;
+ m_lArguments = rCopy.m_lArguments ;
+ m_bDeactivate = rCopy.m_bDeactivate ;
+ m_aDispatchResult = rCopy.m_aDispatchResult ;
+}
+
+//________________________________
+/**
+ @short standard dtor
+ @descr Free all internaly used ressources at the end of living.
+*/
+JobResult::~JobResult()
+{
+ // Nothing realy to do here.
+}
+
+//________________________________
+/**
+ @short =operator
+ @descr Must be implemented to overwrite this instance with another one.
+
+ @param rCopy
+ reference to the other instance, which should be used for copying.
+*/
+void JobResult::operator=( const JobResult& rCopy )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ m_aPureResult = rCopy.m_aPureResult ;
+ m_eParts = rCopy.m_eParts ;
+ m_lArguments = rCopy.m_lArguments ;
+ m_bDeactivate = rCopy.m_bDeactivate ;
+ m_aDispatchResult = rCopy.m_aDispatchResult ;
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short checks for existing parts of the analyzed result
+ @descr The internal flag mask was set after analyzing of the pure result.
+ An user of us can check here, if the required part was realy part
+ of this result. Otherwhise it would use invalid informations ...
+ by using our other members!
+
+ @param eParts
+ a flag mask too, which will be compared with our internaly set one.
+
+ @return We return true only, if any set flag of the given mask match.
+*/
+sal_Bool JobResult::existPart( sal_uInt32 eParts ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return ((m_eParts & eParts) == eParts);
+ /* } SAFE */
+}
+
+//________________________________
+/**
+ @short provides access to our internal members
+ @descr The return value will be valid only in case a call of
+ existPart(E_...) before returned true!
+
+ @return It returns the state of the internal member
+ without any checks!
+*/
+css::uno::Sequence< css::beans::NamedValue > JobResult::getArguments() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_lArguments;
+ /* } SAFE */
+}
+
+//________________________________
+
+css::frame::DispatchResultEvent JobResult::getDispatchResult() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_aDispatchResult;
+ /* } SAFE */
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/jobs/joburl.cxx b/framework/source/jobs/joburl.cxx
new file mode 100644
index 000000000000..717fc8a2f2f5
--- /dev/null
+++ b/framework/source/jobs/joburl.cxx
@@ -0,0 +1,660 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//________________________________
+// my own includes
+#include <jobs/joburl.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <general.h>
+
+//________________________________
+// interface includes
+
+//________________________________
+// includes of other projects
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+
+//________________________________
+// namespace
+
+namespace framework{
+
+//________________________________
+// non exported const
+
+//________________________________
+// non exported definitions
+
+//________________________________
+// declarations
+
+//________________________________
+/**
+ @short special ctor
+ @descr It initialize this new instance with a (hopyfully) valid job URL.
+ This URL will be parsed. After that we set our members right,
+ so other interface methods of this class can be used to get
+ all items of this URL. Of course it will be possible to know,
+ if this URL was valid too.
+
+ @param sURL
+ the job URL for parsing
+*/
+JobURL::JobURL( /*IN*/ const ::rtl::OUString& sURL )
+ : ThreadHelpBase( &Application::GetSolarMutex() )
+{
+ #ifdef ENABLE_COMPONENT_SELF_CHECK
+ JobURL::impldbg_checkIt();
+ #endif
+
+ m_eRequest = E_UNKNOWN;
+
+ // syntax: vnd.sun.star.job:{[event=<name>],[alias=<name>],[service=<name>]}
+
+ // check for "vnd.sun.star.job:"
+ if (sURL.matchIgnoreAsciiCaseAsciiL(JOBURL_PROTOCOL_STR,JOBURL_PROTOCOL_LEN,0))
+ {
+ sal_Int32 t = JOBURL_PROTOCOL_LEN;
+ do
+ {
+ // seperate all token of "{[event=<name>],[alias=<name>],[service=<name>]}"
+ ::rtl::OUString sToken = sURL.getToken(0, JOBURL_PART_SEPERATOR, t);
+ ::rtl::OUString sPartValue ;
+ ::rtl::OUString sPartArguments;
+
+ // check for "event="
+ if (
+ (JobURL::implst_split(sToken,JOBURL_EVENT_STR,JOBURL_EVENT_LEN,sPartValue,sPartArguments)) &&
+ (sPartValue.getLength()>0 )
+ )
+ {
+ // set the part value
+ m_sEvent = sPartValue ;
+ m_sEventArgs = sPartArguments;
+ m_eRequest |= E_EVENT ;
+ }
+ else
+ // check for "alias="
+ if (
+ (JobURL::implst_split(sToken,JOBURL_ALIAS_STR,JOBURL_ALIAS_LEN,sPartValue,sPartArguments)) &&
+ (sPartValue.getLength()>0 )
+ )
+ {
+ // set the part value
+ m_sAlias = sPartValue ;
+ m_sAliasArgs = sPartArguments;
+ m_eRequest |= E_ALIAS ;
+ }
+ else
+ // check for "service="
+ if (
+ (JobURL::implst_split(sToken,JOBURL_SERVICE_STR,JOBURL_SERVICE_LEN,sPartValue,sPartArguments)) &&
+ (sPartValue.getLength()>0 )
+ )
+ {
+ // set the part value
+ m_sService = sPartValue ;
+ m_sServiceArgs = sPartArguments;
+ m_eRequest |= E_SERVICE ;
+ }
+ }
+ while(t!=-1);
+ }
+}
+
+//________________________________
+/**
+ @short knows, if this job URL object hold a valid URL inside
+
+ @return <TRUE/> if it represent a valid job URL.
+*/
+sal_Bool JobURL::isValid() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return (m_eRequest!=E_UNKNOWN);
+}
+
+//________________________________
+/**
+ @short get the event item of this job URL
+ @descr Because the three possible parts of such URL (event, alias, service)
+ can't be combined, this method can(!) return a valid value - but it's
+ not a must. Thats why the return value must be used too, to detect a missing
+ event value.
+
+ @param sEvent
+ returns the possible existing event value
+ e.g. "vnd.sun.star.job:event=myEvent" returns "myEvent"
+
+ @return <TRUE/> if an event part of the job URL exist and the out parameter
+ sEvent was filled.
+
+ @attention The out parameter will be reseted everytime. Don't use it if method returns <FALSE/>!
+*/
+sal_Bool JobURL::getEvent( /*OUT*/ ::rtl::OUString& sEvent ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ sEvent = ::rtl::OUString();
+ sal_Bool bSet = ((m_eRequest & E_EVENT) == E_EVENT);
+ if (bSet)
+ sEvent = m_sEvent;
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return bSet;
+}
+
+//________________________________
+/**
+ @short get the alias item of this job URL
+ @descr Because the three possible parts of such URL (event, alias, service)
+ can't be combined, this method can(!) return a valid value - but it's
+ not a must. Thats why the return value must be used too, to detect a missing
+ alias value.
+
+ @param sAlias
+ returns the possible existing alias value
+ e.g. "vnd.sun.star.job:alias=myAlias" returns "myAlias"
+
+ @return <TRUE/> if an alias part of the job URL exist and the out parameter
+ sAlias was filled.
+
+ @attention The out parameter will be reseted everytime. Don't use it if method returns <FALSE/>!
+*/
+sal_Bool JobURL::getAlias( /*OUT*/ ::rtl::OUString& sAlias ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ sAlias = ::rtl::OUString();
+ sal_Bool bSet = ((m_eRequest & E_ALIAS) == E_ALIAS);
+ if (bSet)
+ sAlias = m_sAlias;
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return bSet;
+}
+
+//________________________________
+/**
+ @short get the service item of this job URL
+ @descr Because the three possible parts of such URL (event, service, service)
+ can't be combined, this method can(!) return a valid value - but it's
+ not a must. Thats why the return value must be used too, to detect a missing
+ service value.
+
+ @param sAlias
+ returns the possible existing service value
+ e.g. "vnd.sun.star.job:service=com.sun.star.Service" returns "com.sun.star.Service"
+
+ @return <TRUE/> if an service part of the job URL exist and the out parameter
+ sService was filled.
+
+ @attention The out parameter will be reseted everytime. Don't use it if method returns <FALSE/>!
+*/
+sal_Bool JobURL::getService( /*OUT*/ ::rtl::OUString& sService ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ sService = ::rtl::OUString();
+ sal_Bool bSet = ((m_eRequest & E_SERVICE) == E_SERVICE);
+ if (bSet)
+ sService = m_sService;
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return bSet;
+}
+
+//________________________________
+/**
+ @short searches for a special identifier in the given string and split it
+ @descr If the given identifier could be found at the beginning of the given string,
+ this method split it into different parts and return it.
+ Following schema is used: <partidentifier>=<partvalue>[?<partarguments>]
+
+ @param sPart
+ the string, which should be analyzed
+
+ @param pPartIdentifier
+ the part identifier value, which must be found at the beginning of the
+ parameter <var>sPart</var>
+
+ @param nPartLength
+ the length of the ascii value <var>pPartIdentifier</var>
+
+ @param rPartValue
+ returns the part value if <var>sPart</var> was splitted successfully
+
+ @param rPartArguments
+ returns the part arguments if <var>sPart</var> was splitted successfully
+
+ @return <TRUE/> if the identifier could be found and the string was splitted.
+ <FALSE/> otherwhise.
+*/
+sal_Bool JobURL::implst_split( /*IN*/ const ::rtl::OUString& sPart ,
+ /*IN*/ const sal_Char* pPartIdentifier ,
+ /*IN*/ sal_Int32 nPartLength ,
+ /*OUT*/ ::rtl::OUString& rPartValue ,
+ /*OUT*/ ::rtl::OUString& rPartArguments )
+{
+ // first search for the given identifier
+ sal_Bool bPartFound = (sPart.matchIgnoreAsciiCaseAsciiL(pPartIdentifier,nPartLength,0));
+
+ // If it exist - we can split the part and return sal_True.
+ // Otherwhise we do nothing and return sal_False.
+ if (bPartFound)
+ {
+ // But may the part has optional arguments - seperated by a "?".
+ // Do so - we set the return value with the whole part string.
+ // Arguments will be set to an empty string as default.
+ // If we detect the right sign - we split the arguments and overwrite the default.
+ ::rtl::OUString sValueAndArguments = sPart.copy(nPartLength);
+ ::rtl::OUString sValue = sValueAndArguments ;
+ ::rtl::OUString sArguments;
+
+ sal_Int32 nArgStart = sValueAndArguments.indexOf('?',0);
+ if (nArgStart!=-1)
+ {
+ sValue = sValueAndArguments.copy(0,nArgStart);
+ ++nArgStart; // ignore '?'!
+ sArguments = sValueAndArguments.copy(nArgStart);
+ }
+
+ rPartValue = sValue ;
+ rPartArguments = sArguments;
+ }
+
+ return bPartFound;
+}
+
+//________________________________
+/**
+ @short special debug method
+ @descr It's the entry point method to start a self component check for this class.
+ It's used for internal purposes only and never a part of a legal product.
+ Use it for testing and debug only!
+*/
+#ifdef ENABLE_COMPONENT_SELF_CHECK
+
+#define LOGFILE_JOBURL "joburl.log"
+
+void JobURL::impldbg_checkIt()
+{
+ // check simple URL's
+ JobURL::impldbg_checkURL("vnd.sun.star.job:event=onMyEvent" , E_EVENT , "onMyEvent", "" , "" , NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:alias=myAlias" , E_ALIAS , "" , "myAlias", "" , NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.Service", E_SERVICE, "" , "" , "css.Service", NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:service=;" , E_UNKNOWN, "" , "" , "" , NULL, NULL, NULL);
+
+ // check combinations
+ // Note: No additional spaces or tabs are allowed after a seperator occurred.
+ // Tab and spaces before a seperator will be used as value!
+ JobURL::impldbg_checkURL("vnd.sun.star.job:event=onMyEvent;alias=myAlias;service=css.Service" , E_EVENT | E_ALIAS | E_SERVICE , "onMyEvent", "myAlias", "css.Service" , NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.Service;alias=myAlias" , E_ALIAS | E_SERVICE , "" , "myAlias", "css.Service" , NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.Service ;alias=myAlias" , E_ALIAS | E_SERVICE , "" , "myAlias", "css.Service ", NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.Service; alias=myAlias" , E_UNKNOWN , "" , "" , "" , NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job : event=onMyEvent" , E_UNKNOWN , "" , "" , "" , NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:event=onMyEvent;event=onMyEvent;service=css.Service", E_UNKNOWN , "" , "" , "" , NULL, NULL, NULL);
+
+ // check upper/lower case
+ // fix parts of the URL are case insensitive (e.g. "vnd.SUN.star.job:eVEnt=")
+ // values are case sensitive (e.g. "myAlias" )
+ JobURL::impldbg_checkURL("vnd.SUN.star.job:eVEnt=onMyEvent;aliAs=myAlias;serVice=css.Service", E_EVENT | E_ALIAS | E_SERVICE , "onMyEvent", "myAlias", "css.Service" , NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.SUN.star.job:eVEnt=onMyEVENT;aliAs=myALIAS;serVice=css.SERVICE", E_EVENT | E_ALIAS | E_SERVICE , "onMyEVENT", "myALIAS", "css.SERVICE" , NULL, NULL, NULL);
+
+ // check stupid URLs
+ JobURL::impldbg_checkURL("vnd.sun.star.jobs:service=css.Service" , E_UNKNOWN, "", "", "", NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job service=css.Service" , E_UNKNOWN, "", "", "", NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:service;css.Service" , E_UNKNOWN, "", "", "", NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:service;" , E_UNKNOWN, "", "", "", NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:;alias;service;event=" , E_UNKNOWN, "", "", "", NULL, NULL, NULL);
+ JobURL::impldbg_checkURL("vnd.sun.star.job:alias=a;service=s;event=", E_UNKNOWN, "", "", "", NULL, NULL, NULL);
+
+ // check argument handling
+ JobURL::impldbg_checkURL("vnd.sun.star.job:event=onMyEvent?eventArg1,eventArg2=3,eventArg4," , E_EVENT , "onMyEvent", "" , "" , "eventArg1,eventArg2=3,eventArg4,", NULL , NULL );
+ JobURL::impldbg_checkURL("vnd.sun.star.job:alias=myAlias?aliasArg1,aliasarg2" , E_EVENT , "" , "myAlias", "" , NULL , "aliasArg1,aliasarg2", NULL );
+ JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.myService?serviceArg1" , E_EVENT , "" , "" , "css.myService", NULL , NULL , "serviceArg1" );
+ JobURL::impldbg_checkURL("vnd.sun.star.job:service=css.myService?serviceArg1;alias=myAlias?aliasArg=564", E_EVENT | E_ALIAS, "" , "myAlias", "css.myService", NULL , "aliasArg=564" , "serviceArg1" );
+}
+
+//________________________________
+/**
+ @short helper debug method
+ @descr It uses the given parameter to create a new instance of a JobURL.
+ They results will be compared with the exepected ones.
+ The a log will be written, which contains some detailed informations
+ for this sub test.
+
+ @param pURL
+ the job URL, which should be checked
+
+ @param eExpectedPart
+ the expected result
+
+ @param pExpectedEvent
+ the expected event value
+
+ @param pExpectedAlias
+ the expected alias value
+
+ @param pExpectedService
+ the expected service value
+
+ @param pExpectedEventArgs
+ the expected event arguments
+
+ @param pExpectedAliasArgs
+ the expected alias arguments
+
+ @param pExpectedServiceArgs
+ the expected service arguments
+*/
+void JobURL::impldbg_checkURL( /*IN*/ const sal_Char* pURL ,
+ /*IN*/ sal_uInt32 eExpectedPart ,
+ /*IN*/ const sal_Char* pExpectedEvent ,
+ /*IN*/ const sal_Char* pExpectedAlias ,
+ /*IN*/ const sal_Char* pExpectedService ,
+ /*IN*/ const sal_Char* pExpectedEventArgs ,
+ /*IN*/ const sal_Char* pExpectedAliasArgs ,
+ /*IN*/ const sal_Char* pExpectedServiceArgs )
+{
+ ::rtl::OUString sEvent ;
+ ::rtl::OUString sAlias ;
+ ::rtl::OUString sService ;
+ ::rtl::OUString sEventArgs ;
+ ::rtl::OUString sAliasArgs ;
+ ::rtl::OUString sServiceArgs;
+ ::rtl::OUString sURL (::rtl::OUString::createFromAscii(pURL));
+ sal_Bool bOK = sal_True;
+
+ JobURL aURL(sURL);
+
+ // check if URL is invalid
+ if (eExpectedPart==E_UNKNOWN)
+ bOK = !aURL.isValid();
+
+ // check if URL has the expected event part
+ if (
+ (bOK ) &&
+ ((eExpectedPart & E_EVENT) == E_EVENT)
+ )
+ {
+ bOK = (
+ (aURL.isValid() ) &&
+ (aURL.getEvent(sEvent) ) &&
+ (sEvent.getLength()>0 ) &&
+ (sEvent.compareToAscii(pExpectedEvent)==0)
+ );
+
+ if (bOK && pExpectedEventArgs!=NULL)
+ {
+ bOK = (
+ (aURL.getEventArgs(sEventArgs) ) &&
+ (sEventArgs.compareToAscii(pExpectedEventArgs)==0)
+ );
+ };
+ }
+
+ // check if URL has no event part
+ if (
+ (bOK ) &&
+ ((eExpectedPart & E_EVENT) != E_EVENT)
+ )
+ {
+ bOK = (
+ (!aURL.getEvent(sEvent) ) &&
+ (sEvent.getLength()==0 ) &&
+ (!aURL.getEventArgs(sEventArgs)) &&
+ (sEventArgs.getLength()==0 )
+ );
+ }
+
+ // check if URL has the expected alias part
+ if (
+ (bOK ) &&
+ ((eExpectedPart & E_ALIAS) == E_ALIAS)
+ )
+ {
+ bOK = (
+ (aURL.isValid() ) &&
+ (aURL.getAlias(sAlias) ) &&
+ (sAlias.getLength()>0 ) &&
+ (sAlias.compareToAscii(pExpectedAlias)==0)
+ );
+
+ if (bOK && pExpectedAliasArgs!=NULL)
+ {
+ bOK = (
+ (aURL.getAliasArgs(sAliasArgs) ) &&
+ (sAliasArgs.compareToAscii(pExpectedAliasArgs)==0)
+ );
+ };
+ }
+
+ // check if URL has the no alias part
+ if (
+ (bOK ) &&
+ ((eExpectedPart & E_ALIAS) != E_ALIAS)
+ )
+ {
+ bOK = (
+ (!aURL.getAlias(sAlias) ) &&
+ (sAlias.getLength()==0 ) &&
+ (!aURL.getAliasArgs(sAliasArgs)) &&
+ (sAliasArgs.getLength()==0 )
+ );
+ }
+
+ // check if URL has the expected service part
+ if (
+ (bOK ) &&
+ ((eExpectedPart & E_SERVICE) == E_SERVICE)
+ )
+ {
+ bOK = (
+ (aURL.isValid() ) &&
+ (aURL.getService(sService) ) &&
+ (sService.getLength()>0 ) &&
+ (sService.compareToAscii(pExpectedService)==0)
+ );
+
+ if (bOK && pExpectedServiceArgs!=NULL)
+ {
+ bOK = (
+ (aURL.getServiceArgs(sServiceArgs) ) &&
+ (sServiceArgs.compareToAscii(pExpectedServiceArgs)==0)
+ );
+ };
+ }
+
+ // check if URL has the no service part
+ if (
+ (bOK ) &&
+ ((eExpectedPart & E_SERVICE) != E_SERVICE)
+ )
+ {
+ bOK = (
+ (!aURL.getService(sService) ) &&
+ (sService.getLength()==0 ) &&
+ (!aURL.getServiceArgs(sServiceArgs)) &&
+ (sServiceArgs.getLength()==0 )
+ );
+ }
+
+ ::rtl::OUStringBuffer sMsg(256);
+
+ sMsg.appendAscii("\"" );
+ sMsg.append (sURL );
+ sMsg.appendAscii("\" ");
+
+ if (bOK)
+ {
+ sMsg.appendAscii("... OK\n");
+ }
+ else
+ {
+ sMsg.appendAscii("... failed\n");
+ sMsg.appendAscii("expected was: ");
+ if (eExpectedPart==E_UNKNOWN)
+ sMsg.appendAscii("E_UNKNOWN");
+ if ((eExpectedPart & E_EVENT) == E_EVENT)
+ {
+ sMsg.appendAscii("| E_EVENT e=\"");
+ sMsg.appendAscii(pExpectedEvent );
+ sMsg.appendAscii("\"" );
+ }
+ if ((eExpectedPart & E_ALIAS) == E_ALIAS)
+ {
+ sMsg.appendAscii("| E_ALIAS a=\"");
+ sMsg.appendAscii(pExpectedAlias );
+ sMsg.appendAscii("\"" );
+ }
+ if ((eExpectedPart & E_SERVICE) == E_SERVICE)
+ {
+ sMsg.appendAscii("| E_SERVICE s=\"");
+ sMsg.appendAscii(pExpectedService );
+ sMsg.appendAscii("\"" );
+ }
+ sMsg.appendAscii("\tbut it was : " );
+ sMsg.append (aURL.impldbg_toString());
+ sMsg.appendAscii("\n" );
+ }
+
+ WRITE_LOGFILE(LOGFILE_JOBURL, U2B(sMsg.makeStringAndClear()))
+}
+
+//________________________________
+/**
+ @short helper debug method
+ @descr It returns a representation of the internal object state
+ as string notation.
+
+ @returns The formated string representation.
+*/
+::rtl::OUString JobURL::impldbg_toString() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ ::rtl::OUStringBuffer sBuffer(256);
+
+ if (m_eRequest==E_UNKNOWN)
+ sBuffer.appendAscii("E_UNKNOWN");
+ if ((m_eRequest & E_EVENT) == E_EVENT)
+ sBuffer.appendAscii("| E_EVENT");
+ if ((m_eRequest & E_ALIAS) == E_ALIAS)
+ sBuffer.appendAscii("| E_ALIAS");
+ if ((m_eRequest & E_SERVICE) == E_SERVICE)
+ sBuffer.appendAscii("| E_SERVICE");
+ sBuffer.appendAscii("{ e=\"" );
+ sBuffer.append (m_sEvent );
+ sBuffer.appendAscii("\" - a=\"");
+ sBuffer.append (m_sAlias );
+ sBuffer.appendAscii("\" - s=\"");
+ sBuffer.append (m_sService );
+ sBuffer.appendAscii("\" }" );
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return sBuffer.makeStringAndClear();
+}
+
+//________________________________
+
+sal_Bool JobURL::getServiceArgs( /*OUT*/ ::rtl::OUString& sServiceArgs ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ sServiceArgs = ::rtl::OUString();
+ sal_Bool bSet = ((m_eRequest & E_SERVICE) == E_SERVICE);
+ if (bSet)
+ sServiceArgs = m_sServiceArgs;
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return bSet;
+}
+
+//________________________________
+
+sal_Bool JobURL::getEventArgs( /*OUT*/ ::rtl::OUString& sEventArgs ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ sEventArgs = ::rtl::OUString();
+ sal_Bool bSet = ((m_eRequest & E_EVENT) == E_EVENT);
+ if (bSet)
+ sEventArgs = m_sEventArgs;
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return bSet;
+}
+
+//________________________________
+
+sal_Bool JobURL::getAliasArgs( /*OUT*/ ::rtl::OUString& sAliasArgs ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ sAliasArgs = ::rtl::OUString();
+ sal_Bool bSet = ((m_eRequest & E_ALIAS) == E_ALIAS);
+ if (bSet)
+ sAliasArgs = m_sAliasArgs;
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return bSet;
+}
+
+#endif // ENABLE_COMPONENT_SELF_CHECK
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/jobs/shelljob.cxx b/framework/source/jobs/shelljob.cxx
new file mode 100644
index 000000000000..7cc29e1b686e
--- /dev/null
+++ b/framework/source/jobs/shelljob.cxx
@@ -0,0 +1,217 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// include own header
+
+#include <jobs/shelljob.hxx>
+#include <jobs/jobconst.hxx>
+#include <threadhelp/readguard.hxx>
+#include <services.h>
+
+//_______________________________________________
+// include others
+
+#include <osl/file.hxx>
+#include <osl/process.h>
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+
+//_______________________________________________
+// include interfaces
+
+#include <com/sun/star/system/XSystemShellExecute.hpp>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <com/sun/star/util/XStringSubstitution.hpp>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//_______________________________________________
+// definitions
+
+/** adress job configuration inside argument set provided on method execute(). */
+static const ::rtl::OUString PROP_JOBCONFIG(RTL_CONSTASCII_USTRINGPARAM("JobConfig"));
+
+/** adress job configuration property "Command". */
+static const ::rtl::OUString PROP_COMMAND(RTL_CONSTASCII_USTRINGPARAM("Command"));
+
+/** adress job configuration property "Arguments". */
+static const ::rtl::OUString PROP_ARGUMENTS(RTL_CONSTASCII_USTRINGPARAM("Arguments"));
+
+/** adress job configuration property "DeactivateJobIfDone". */
+static const ::rtl::OUString PROP_DEACTIVATEJOBIFDONE(RTL_CONSTASCII_USTRINGPARAM("DeactivateJobIfDone"));
+
+/** adress job configuration property "CheckExitCode". */
+static const ::rtl::OUString PROP_CHECKEXITCODE(RTL_CONSTASCII_USTRINGPARAM("CheckExitCode"));
+
+//-----------------------------------------------
+
+DEFINE_XSERVICEINFO_MULTISERVICE(ShellJob ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_JOB ,
+ IMPLEMENTATIONNAME_SHELLJOB)
+
+DEFINE_INIT_SERVICE(ShellJob,
+ {
+ /* Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+ )
+
+//-----------------------------------------------
+ShellJob::ShellJob(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase( )
+ , m_xSMGR (xSMGR)
+{
+}
+
+//-----------------------------------------------
+ShellJob::~ShellJob()
+{
+}
+
+//-----------------------------------------------
+css::uno::Any SAL_CALL ShellJob::execute(const css::uno::Sequence< css::beans::NamedValue >& lJobArguments)
+ throw(css::lang::IllegalArgumentException,
+ css::uno::Exception ,
+ css::uno::RuntimeException )
+{
+ ::comphelper::SequenceAsHashMap lArgs (lJobArguments);
+ ::comphelper::SequenceAsHashMap lOwnCfg(lArgs.getUnpackedValueOrDefault(PROP_JOBCONFIG, css::uno::Sequence< css::beans::NamedValue >()));
+
+ const ::rtl::OUString sCommand = lOwnCfg.getUnpackedValueOrDefault(PROP_COMMAND , ::rtl::OUString());
+ const css::uno::Sequence< ::rtl::OUString > lCommandArguments = lOwnCfg.getUnpackedValueOrDefault(PROP_ARGUMENTS , css::uno::Sequence< ::rtl::OUString >());
+ const ::sal_Bool bDeactivateJobIfDone = lOwnCfg.getUnpackedValueOrDefault(PROP_DEACTIVATEJOBIFDONE , sal_True );
+ const ::sal_Bool bCheckExitCode = lOwnCfg.getUnpackedValueOrDefault(PROP_CHECKEXITCODE , sal_True );
+
+ // replace all might existing place holder.
+ ::rtl::OUString sRealCommand = impl_substituteCommandVariables(sCommand);
+
+ // Command is required as minimum.
+ // If it does not exists ... we cant do our job.
+ // Deactivate such miss configured job silently .-)
+ if (sRealCommand.getLength() < 1)
+ return ShellJob::impl_generateAnswer4Deactivation();
+
+ // do it
+ ::sal_Bool bDone = impl_execute(sRealCommand, lCommandArguments, bCheckExitCode);
+ if (! bDone)
+ return css::uno::Any();
+
+ // Job was done ... user configured deactivation of this job
+ // in such case.
+ if (bDeactivateJobIfDone)
+ return ShellJob::impl_generateAnswer4Deactivation();
+
+ // There was no decision about deactivation of this job.
+ // So we have to return nothing here !
+ return css::uno::Any();
+}
+
+//-----------------------------------------------
+css::uno::Any ShellJob::impl_generateAnswer4Deactivation()
+{
+ css::uno::Sequence< css::beans::NamedValue > aAnswer(1);
+ aAnswer[0].Name = JobConst::ANSWER_DEACTIVATE_JOB();
+ aAnswer[0].Value = css::uno::makeAny(sal_True);
+
+ return css::uno::makeAny(aAnswer);
+}
+
+//-----------------------------------------------
+::rtl::OUString ShellJob::impl_substituteCommandVariables(const ::rtl::OUString& sCommand)
+{
+ // SYNCHRONIZED ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SYNCHRONIZED
+
+ try
+ {
+ css::uno::Reference< css::util::XStringSubstitution > xSubst ( xSMGR->createInstance(SERVICENAME_SUBSTITUTEPATHVARIABLES), css::uno::UNO_QUERY_THROW);
+ const ::sal_Bool bSubstRequired = sal_True;
+ const ::rtl::OUString sCompleteCommand = xSubst->substituteVariables(sCommand, bSubstRequired);
+
+ return sCompleteCommand;
+ }
+ catch(const css::uno::Exception&)
+ {}
+
+ return ::rtl::OUString();
+}
+
+//-----------------------------------------------
+::sal_Bool ShellJob::impl_execute(const ::rtl::OUString& sCommand ,
+ const css::uno::Sequence< ::rtl::OUString >& lArguments ,
+ ::sal_Bool bCheckExitCode)
+{
+ ::rtl_uString** pArgs = NULL;
+ const ::sal_Int32 nArgs = lArguments.getLength ();
+ oslProcessOption nOptions = osl_Process_WAIT;
+ oslProcess hProcess(0);
+
+ if (nArgs > 0)
+ pArgs = reinterpret_cast< ::rtl_uString** >(const_cast< ::rtl::OUString* >(lArguments.getConstArray()));
+
+ oslProcessError eError = osl_executeProcess(sCommand.pData, pArgs, nArgs, nOptions, NULL, NULL, NULL, 0, &hProcess);
+
+ // executable not found or couldnt be started
+ if (eError != osl_Process_E_None)
+ return sal_False;
+
+ ::sal_Bool bRet = sal_True;
+ if (bCheckExitCode)
+ {
+ // check its return codes ...
+ oslProcessInfo aInfo;
+ aInfo.Size = sizeof (oslProcessInfo);
+ eError = osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &aInfo);
+
+ if (eError != osl_Process_E_None)
+ bRet = sal_False;
+ else
+ bRet = (aInfo.Code == 0);
+ }
+ osl_freeProcessHandle(hProcess);
+ return bRet;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/layoutmanager/helpers.cxx b/framework/source/layoutmanager/helpers.cxx
new file mode 100644
index 000000000000..a095aa480a3c
--- /dev/null
+++ b/framework/source/layoutmanager/helpers.cxx
@@ -0,0 +1,414 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutmanager.hxx,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+// my own includes
+#include "helpers.hxx"
+#include <threadhelp/resetableguard.hxx>
+#include <services.h>
+
+// interface includes
+#include <com/sun/star/ui/DockingArea.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/frame/XDispatchHelper.hpp>
+#include <com/sun/star/awt/XDockableWindow.hpp>
+#include <com/sun/star/awt/XDockableWindowListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/ui/XUIElement.hpp>
+
+// other includes
+#include <comphelper/mediadescriptor.hxx>
+#include <vcl/svapp.hxx>
+#include <toolkit/unohlp.hxx>
+
+// namespace
+using namespace com::sun::star;
+
+namespace framework
+{
+
+bool hasEmptySize( const:: Size& aSize )
+{
+ return ( aSize.Width() == 0 ) && ( aSize.Height() == 0 );
+}
+
+bool hasDefaultPosValue( const ::Point& aPos )
+{
+ return (( aPos.X() == SAL_MAX_INT32 ) || ( aPos.Y() == SAL_MAX_INT32 ));
+}
+
+bool isDefaultPos( const ::com::sun::star::awt::Point& aPos )
+{
+ return (( aPos.X == SAL_MAX_INT32 ) && ( aPos.Y == SAL_MAX_INT32 ));
+}
+
+bool isDefaultPos( const ::Point& aPos )
+{
+ return (( aPos.X() == SAL_MAX_INT32 ) && ( aPos.Y() == SAL_MAX_INT32 ));
+}
+
+bool isReverseOrderDockingArea( const sal_Int32 nDockArea )
+{
+ ui::DockingArea eDockArea = static_cast< ui::DockingArea >( nDockArea );
+ return (( eDockArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) ||
+ ( eDockArea == ui::DockingArea_DOCKINGAREA_RIGHT ));
+}
+
+bool isToolboxHorizontalAligned( ToolBox* pToolBox )
+{
+ if ( pToolBox )
+ return (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM ));
+ return false;
+}
+
+bool isHorizontalDockingArea( const ui::DockingArea& nDockingArea )
+{
+ return (( nDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ||
+ ( nDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ));
+}
+
+bool isHorizontalDockingArea( const sal_Int32 nDockArea )
+{
+ return isHorizontalDockingArea(static_cast< ui::DockingArea >( nDockArea ));
+}
+
+::rtl::OUString retrieveToolbarNameFromHelpURL( Window* pWindow )
+{
+ ::rtl::OUString aToolbarName;
+
+ if ( pWindow->GetType() == WINDOW_TOOLBOX )
+ {
+ ToolBox* pToolBox = dynamic_cast<ToolBox *>( pWindow );
+ if ( pToolBox )
+ {
+ aToolbarName = rtl::OStringToOUString( pToolBox->GetHelpId(), RTL_TEXTENCODING_UTF8 );
+ sal_Int32 i = aToolbarName.lastIndexOf( ':' );
+ if (( aToolbarName.getLength() > 0 ) && ( i > 0 ) && (( i+ 1 ) < aToolbarName.getLength() ))
+ aToolbarName = aToolbarName.copy( i+1 ); // Remove ".HelpId:" protocol from toolbar name
+ else
+ aToolbarName = ::rtl::OUString();
+ }
+ }
+ return aToolbarName;
+}
+
+ToolBox* getToolboxPtr( Window* pWindow )
+{
+ ToolBox* pToolbox(NULL);
+ if ( pWindow->GetType() == WINDOW_TOOLBOX )
+ pToolbox = dynamic_cast<ToolBox*>( pWindow );
+ return pToolbox;
+}
+
+Window* getWindowFromXUIElement( const uno::Reference< ui::XUIElement >& xUIElement )
+{
+ SolarMutexGuard aGuard;
+ uno::Reference< awt::XWindow > xWindow;
+ if ( xUIElement.is() )
+ xWindow = uno::Reference< awt::XWindow >( xUIElement->getRealInterface(), uno::UNO_QUERY );
+ return VCLUnoHelper::GetWindow( xWindow );
+}
+
+SystemWindow* getTopSystemWindow( const uno::Reference< awt::XWindow >& xWindow )
+{
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ while ( pWindow && !pWindow->IsSystemWindow() )
+ pWindow = pWindow->GetParent();
+
+ if ( pWindow )
+ return (SystemWindow *)pWindow;
+ else
+ return 0;
+}
+
+void setZeroRectangle( ::Rectangle& rRect )
+{
+ rRect.setX(0);
+ rRect.setY(0);
+ rRect.setWidth(0);
+ rRect.setHeight(0);
+}
+
+// ATTENTION!
+// This value is directly copied from the sfx2 project.
+// You have to change BOTH values, see sfx2/inc/sfx2/sfxsids.hrc (SID_DOCKWIN_START)
+static const sal_Int32 DOCKWIN_ID_BASE = 9800;
+
+bool lcl_checkUIElement(const uno::Reference< ui::XUIElement >& xUIElement, awt::Rectangle& _rPosSize, uno::Reference< awt::XWindow >& _xWindow)
+{
+ bool bRet = xUIElement.is();
+ if ( bRet )
+ {
+ SolarMutexGuard aGuard;
+ _xWindow.set( xUIElement->getRealInterface(), uno::UNO_QUERY );
+ _rPosSize = _xWindow->getPosSize();
+
+ Window* pWindow = VCLUnoHelper::GetWindow( _xWindow );
+ if ( pWindow->GetType() == WINDOW_TOOLBOX )
+ {
+ ::Size aSize = ((ToolBox*)pWindow)->CalcWindowSizePixel( 1 );
+ _rPosSize.Width = aSize.Width();
+ _rPosSize.Height = aSize.Height();
+ }
+ } // if ( xUIElement.is() )
+ return bRet;
+}
+
+uno::Reference< awt::XWindowPeer > createToolkitWindow( const uno::Reference< lang::XMultiServiceFactory >& rFactory, const uno::Reference< awt::XWindowPeer >& rParent, const char* pService )
+{
+ const rtl::OUString aAWTToolkit( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ));
+
+ uno::Reference< awt::XWindowPeer > xPeer;
+ if ( rFactory.is() )
+ {
+ uno::Reference< awt::XToolkit > xToolkit( rFactory->createInstance( aAWTToolkit ), uno::UNO_QUERY_THROW );
+ if ( xToolkit.is() )
+ {
+ // describe window properties.
+ css::awt::WindowDescriptor aDescriptor;
+ aDescriptor.Type = awt::WindowClass_SIMPLE;
+ aDescriptor.WindowServiceName = ::rtl::OUString::createFromAscii( pService );
+ aDescriptor.ParentIndex = -1;
+ aDescriptor.Parent = uno::Reference< awt::XWindowPeer >( rParent, uno::UNO_QUERY );
+ aDescriptor.Bounds = awt::Rectangle(0,0,0,0);
+ aDescriptor.WindowAttributes = 0;
+
+ // create a awt window
+ xPeer = xToolkit->createWindow( aDescriptor );
+ }
+ }
+
+ return xPeer;
+}
+
+// convert alignment constant to vcl's WindowAlign type
+WindowAlign ImplConvertAlignment( sal_Int16 aAlignment )
+{
+ if ( aAlignment == ui::DockingArea_DOCKINGAREA_LEFT )
+ return WINDOWALIGN_LEFT;
+ else if ( aAlignment == ui::DockingArea_DOCKINGAREA_RIGHT )
+ return WINDOWALIGN_RIGHT;
+ else if ( aAlignment == ui::DockingArea_DOCKINGAREA_TOP )
+ return WINDOWALIGN_TOP;
+ else
+ return WINDOWALIGN_BOTTOM;
+}
+
+::rtl::OUString getElementTypeFromResourceURL( const ::rtl::OUString& aResourceURL )
+{
+ ::rtl::OUString aType;
+
+ ::rtl::OUString aUIResourceURL( UIRESOURCE_URL );
+ if ( aResourceURL.indexOf( aUIResourceURL ) == 0 )
+ {
+ sal_Int32 nIndex = 0;
+ ::rtl::OUString aPathPart = aResourceURL.copy( aUIResourceURL.getLength() );
+ ::rtl::OUString aUIResource = aPathPart.getToken( 0, (sal_Unicode)'/', nIndex );
+
+ return aPathPart.getToken( 0, (sal_Unicode)'/', nIndex );
+ }
+
+ return aType;
+}
+
+void parseResourceURL( const rtl::OUString& aResourceURL, rtl::OUString& aElementType, rtl::OUString& aElementName )
+{
+ ::rtl::OUString aUIResourceURL( UIRESOURCE_URL );
+ if ( aResourceURL.indexOf( aUIResourceURL ) == 0 )
+ {
+ sal_Int32 nIndex = 0;
+ ::rtl::OUString aPathPart = aResourceURL.copy( aUIResourceURL.getLength() );
+ ::rtl::OUString aUIResource = aPathPart.getToken( 0, (sal_Unicode)'/', nIndex );
+
+ aElementType = aPathPart.getToken( 0, (sal_Unicode)'/', nIndex );
+ aElementName = aPathPart.getToken( 0, (sal_Unicode)'/', nIndex );
+ }
+}
+
+::com::sun::star::awt::Rectangle putRectangleValueToAWT( const ::Rectangle& rRect )
+{
+ css::awt::Rectangle aRect;
+ aRect.X = rRect.Left();
+ aRect.Y = rRect.Top();
+ aRect.Width = rRect.Right();
+ aRect.Height = rRect.Bottom();
+
+ return aRect;
+}
+
+::Rectangle putAWTToRectangle( const ::com::sun::star::awt::Rectangle& rRect )
+{
+ ::Rectangle aRect;
+ aRect.Left() = rRect.X;
+ aRect.Top() = rRect.Y;
+ aRect.Right() = rRect.Width;
+ aRect.Bottom() = rRect.Height;
+
+ return aRect;
+}
+
+css::awt::Rectangle convertRectangleToAWT( const ::Rectangle& rRect )
+{
+ css::awt::Rectangle aRect;
+ aRect.X = rRect.Left();
+ aRect.Y = rRect.Top();
+ aRect.Width = rRect.GetWidth();
+ aRect.Height = rRect.GetHeight();
+ return aRect;
+}
+
+::Rectangle convertAWTToRectangle( const ::com::sun::star::awt::Rectangle& rRect )
+{
+ ::Rectangle aRect;
+ aRect.Left() = rRect.X;
+ aRect.Top() = rRect.Y;
+ aRect.Right() = rRect.X + rRect.Width;
+ aRect.Bottom() = rRect.Y + rRect.Height;
+
+ return aRect;
+}
+
+bool equalRectangles( const css::awt::Rectangle& rRect1,
+ const css::awt::Rectangle& rRect2 )
+{
+ return (( rRect1.X == rRect2.X ) &&
+ ( rRect1.Y == rRect2.Y ) &&
+ ( rRect1.Width == rRect2.Width ) &&
+ ( rRect1.Height == rRect2.Height ));
+}
+
+uno::Reference< frame::XModel > impl_getModelFromFrame( const uno::Reference< frame::XFrame >& rFrame )
+{
+ // Query for the model to get check the context information
+ uno::Reference< frame::XModel > xModel;
+ if ( rFrame.is() )
+ {
+ uno::Reference< frame::XController > xController( rFrame->getController(), uno::UNO_QUERY );
+ if ( xController.is() )
+ xModel = xController->getModel();
+ }
+
+ return xModel;
+}
+
+sal_Bool implts_isPreviewModel( const uno::Reference< frame::XModel >& xModel )
+{
+ if ( xModel.is() )
+ {
+ ::comphelper::MediaDescriptor aDesc( xModel->getArgs() );
+ return aDesc.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PREVIEW(), (sal_Bool)sal_False);
+ }
+ else
+ return sal_False;
+}
+
+sal_Bool implts_isFrameOrWindowTop( const uno::Reference< frame::XFrame >& xFrame )
+{
+ if (xFrame->isTop())
+ return sal_True;
+
+ uno::Reference< awt::XTopWindow > xWindowCheck(xFrame->getContainerWindow(), uno::UNO_QUERY); // dont use _THROW here ... its a check only
+ if (xWindowCheck.is())
+ {
+ // --> PB 2007-06-18 #i76867# top and system window is required.
+ SolarMutexGuard aGuard;
+ uno::Reference< awt::XWindow > xWindow( xWindowCheck, uno::UNO_QUERY );
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ return ( pWindow && pWindow->IsSystemWindow() );
+ // <--
+ }
+
+ return sal_False;
+}
+
+void impl_setDockingWindowVisibility( const css::uno::Reference< css::lang::XMultiServiceFactory>& rSMGR, const css::uno::Reference< css::frame::XFrame >& rFrame, const ::rtl::OUString& rDockingWindowName, bool bVisible )
+{
+ const ::rtl::OUString aDockWinPrefixCommand( RTL_CONSTASCII_USTRINGPARAM( "DockingWindow" ));
+ css::uno::WeakReference< css::frame::XDispatchHelper > xDispatchHelper;
+
+ sal_Int32 nID = rDockingWindowName.toInt32();
+ sal_Int32 nIndex = nID - DOCKWIN_ID_BASE;
+
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider(rFrame, css::uno::UNO_QUERY);
+ if ( nIndex >= 0 && xProvider.is() )
+ {
+ ::rtl::OUString aDockWinCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
+ ::rtl::OUString aDockWinArgName( aDockWinPrefixCommand );
+
+ aDockWinArgName += ::rtl::OUString::valueOf( nIndex );
+
+ css::uno::Sequence< css::beans::PropertyValue > aArgs(1);
+ aArgs[0].Name = aDockWinArgName;
+ aArgs[0].Value = css::uno::makeAny( bVisible );
+
+ css::uno::Reference< css::frame::XDispatchHelper > xDispatcher( xDispatchHelper );
+ if ( !xDispatcher.is())
+ {
+ xDispatcher = css::uno::Reference< css::frame::XDispatchHelper >(
+ rSMGR->createInstance(SERVICENAME_DISPATCHHELPER), css::uno::UNO_QUERY_THROW);
+ }
+
+ aDockWinCommand = aDockWinCommand + aDockWinArgName;
+ xDispatcher->executeDispatch(
+ xProvider,
+ aDockWinCommand,
+ ::rtl::OUString::createFromAscii("_self"),
+ 0,
+ aArgs);
+ }
+}
+
+void impl_addWindowListeners(
+ const css::uno::Reference< css::uno::XInterface >& xThis,
+ const css::uno::Reference< css::ui::XUIElement >& xUIElement )
+{
+ css::uno::Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), css::uno::UNO_QUERY );
+ if ( xDockWindow.is() && xWindow.is() )
+ {
+ try
+ {
+ xDockWindow->addDockableWindowListener(
+ css::uno::Reference< css::awt::XDockableWindowListener >(
+ xThis, css::uno::UNO_QUERY ));
+ xWindow->addWindowListener(
+ css::uno::Reference< css::awt::XWindowListener >(
+ xThis, css::uno::UNO_QUERY ));
+ xDockWindow->enableDocking( sal_True );
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+ }
+}
+
+} // namespace framework
diff --git a/framework/source/layoutmanager/helpers.hxx b/framework/source/layoutmanager/helpers.hxx
new file mode 100644
index 000000000000..d4e9ce313d0e
--- /dev/null
+++ b/framework/source/layoutmanager/helpers.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutmanager.hxx,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_LAYOUTMANAGER_HELPERS_HXX_
+#define __FRAMEWORK_LAYOUTMANAGER_HELPERS_HXX_
+
+// my own includes
+#include <macros/generic.hxx>
+#include <stdtypes.h>
+#include <properties.h>
+
+// interface includes
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/ui/XUIElement.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <com/sun/star/ui/DockingArea.hpp>
+#include <com/sun/star/awt/Point.hpp>
+
+// other includes
+#include <vcl/window.hxx>
+#include <vcl/toolbox.hxx>
+
+#define UIRESOURCE_PROTOCO_ASCII "private:"
+#define UIRESOURCE_RESOURCE_ASCII "resource"
+#define UIRESOURCE_URL_ASCII "private:resource"
+#define UIRESOURCE_URL rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UIRESOURCE_URL_ASCII ))
+#define UIRESOURCETYPE_TOOLBAR "toolbar"
+#define UIRESOURCETYPE_STATUSBAR "statusbar"
+#define UIRESOURCETYPE_MENUBAR "menubar"
+
+namespace framework
+{
+
+bool hasEmptySize( const:: Size& aSize );
+bool hasDefaultPosValue( const ::Point& aPos );
+bool isDefaultPos( const ::com::sun::star::awt::Point& aPos );
+bool isDefaultPos( const ::Point& aPos );
+bool isToolboxHorizontalAligned( ToolBox* pToolBox );
+bool isReverseOrderDockingArea( const sal_Int32 nDockArea );
+bool isHorizontalDockingArea( const sal_Int32 nDockArea );
+bool isHorizontalDockingArea( const ::com::sun::star::ui::DockingArea& nDockArea );
+::rtl::OUString retrieveToolbarNameFromHelpURL( Window* pWindow );
+ToolBox* getToolboxPtr( Window* pWindow );
+Window* getWindowFromXUIElement( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& xUIElement );
+SystemWindow* getTopSystemWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& xWindow );
+bool equalRectangles( const css::awt::Rectangle& rRect1, const css::awt::Rectangle& rRect2 );
+void setZeroRectangle( ::Rectangle& rRect );
+bool lcl_checkUIElement(const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& xUIElement,::com::sun::star::awt::Rectangle& _rPosSize, ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xWindow);
+::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > createToolkitWindow( const css::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rFactory, const css::uno::Reference< ::com::sun::star::awt::XWindowPeer >& rParent, const char* pService );
+WindowAlign ImplConvertAlignment( sal_Int16 aAlignment );
+::rtl::OUString getElementTypeFromResourceURL( const ::rtl::OUString& aResourceURL );
+void parseResourceURL( const rtl::OUString& aResourceURL, rtl::OUString& aElementType, rtl::OUString& aElementName );
+::Rectangle putAWTToRectangle( const ::com::sun::star::awt::Rectangle& rRect );
+::com::sun::star::awt::Rectangle putRectangleValueToAWT( const ::Rectangle& rRect );
+::com::sun::star::awt::Rectangle convertRectangleToAWT( const ::Rectangle& rRect );
+::Rectangle convertAWTToRectangle( const ::com::sun::star::awt::Rectangle& rRect );
+::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > impl_getModelFromFrame( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame );
+sal_Bool implts_isPreviewModel( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel );
+sal_Bool implts_isFrameOrWindowTop( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame );
+void impl_setDockingWindowVisibility( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& rSMGR, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const ::rtl::OUString& rDockingWindowName, bool bVisible );
+void impl_addWindowListeners( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xThis, const ::com::sun::star::uno::Reference< css::ui::XUIElement >& xUIElement );
+::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > implts_createToolkitWindow( const css::uno::Reference< ::com::sun::star::awt::XToolkit >& rToolkit, const css::uno::Reference< ::com::sun::star::awt::XWindowPeer >& rParent );
+
+}
+
+#endif // __FRAMEWORK_LAYOUTMANAGER_HELPERS_HXX_
diff --git a/framework/source/layoutmanager/layoutmanager.cxx b/framework/source/layoutmanager/layoutmanager.cxx
new file mode 100644
index 000000000000..745ce809def6
--- /dev/null
+++ b/framework/source/layoutmanager/layoutmanager.cxx
@@ -0,0 +1,3254 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutmanager.cxx,v $
+ * $Revision: 1.72 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+// my own includes
+#include <services/layoutmanager.hxx>
+#include <helpers.hxx>
+#include <panelmanager.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <services.h>
+
+#include <framework/sfxhelperfunctions.hxx>
+#include <framework/sfxhelperfunctions.hxx>
+#include <uielement/menubarwrapper.hxx>
+#include <framework/addonsoptions.hxx>
+#include <uiconfiguration/windowstateconfiguration.hxx>
+#include <classes/fwkresid.hxx>
+#include <classes/resource.hrc>
+#include <toolkit/helper/convert.hxx>
+#include <uielement/progressbarwrapper.hxx>
+#include <uiconfiguration/globalsettings.hxx>
+#include <toolbarlayoutmanager.hxx>
+
+// interface includes
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/FrameAction.hpp>
+#include <com/sun/star/frame/XUIControllerRegistration.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
+#include <com/sun/star/lang/SystemDependent.hpp>
+#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/frame/LayoutManagerEvents.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XDispatchHelper.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+// other includes
+#include <svtools/imgdef.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/window.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/dockingarea.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <vcl/wall.hxx>
+#include <toolkit/unohlp.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <toolkit/awt/vclxmenu.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/uno3.hxx>
+#include <rtl/logfile.hxx>
+#include <unotools/cmdoptions.hxx>
+
+#include <algorithm>
+#include <boost/bind.hpp>
+
+// using namespace
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::ui;
+using namespace ::com::sun::star::frame;
+
+
+// ATTENTION!
+// This value is directly copied from the sfx2 project.
+// You have to change BOTH values, see sfx2/inc/sfx2/sfxsids.hrc (SID_DOCKWIN_START)
+static const sal_Int32 DOCKWIN_ID_BASE = 9800;
+
+namespace framework
+{
+
+IMPLEMENT_FORWARD_XTYPEPROVIDER2( LayoutManager, LayoutManager_Base, LayoutManager_PBase )
+IMPLEMENT_FORWARD_XINTERFACE2( LayoutManager, LayoutManager_Base, LayoutManager_PBase )
+DEFINE_XSERVICEINFO_MULTISERVICE( LayoutManager, ::cppu::OWeakObject, SERVICENAME_LAYOUTMANAGER, IMPLEMENTATIONNAME_LAYOUTMANAGER)
+DEFINE_INIT_SERVICE( LayoutManager, {} )
+
+LayoutManager::LayoutManager( const Reference< XMultiServiceFactory >& xServiceManager ) : LayoutManager_Base()
+ , ThreadHelpBase( &Application::GetSolarMutex())
+ , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex())
+ , LayoutManager_PBase( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
+ , m_xSMGR( xServiceManager )
+ , m_xURLTransformer( xServiceManager->createInstance( SERVICENAME_URLTRANSFORMER ), UNO_QUERY )
+ , m_xDisplayAccess( xServiceManager->createInstance( SERVICENAME_DISPLAYACCESS ), UNO_QUERY )
+ , m_nLockCount( 0 )
+ , m_bActive( false )
+ , m_bInplaceMenuSet( false )
+ , m_bDockingInProgress( false )
+ , m_bMenuVisible( true )
+ , m_bComponentAttached( false )
+ , m_bDoLayout( false )
+ , m_bVisible( true )
+ , m_bParentWindowVisible( false )
+ , m_bMustDoLayout( true )
+ , m_bAutomaticToolbars( true )
+ , m_bStoreWindowState( false )
+ , m_bHideCurrentUI( false )
+ , m_bGlobalSettings( false )
+ , m_bPreserveContentSize( false )
+ , m_bMenuBarCloser( false )
+ , m_pInplaceMenuBar( NULL )
+ , m_xModuleManager( Reference< XModuleManager >( xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY ))
+ , m_xUIElementFactoryManager( Reference< ui::XUIElementFactory >(
+ xServiceManager->createInstance( SERVICENAME_UIELEMENTFACTORYMANAGER ), UNO_QUERY ))
+ , m_xPersistentWindowStateSupplier( Reference< XNameAccess >(
+ xServiceManager->createInstance( SERVICENAME_WINDOWSTATECONFIGURATION ), UNO_QUERY ))
+ , m_pGlobalSettings( 0 )
+ , m_aStatusBarAlias( RTL_CONSTASCII_USTRINGPARAM( "private:resource/statusbar/statusbar" ))
+ , m_aProgressBarAlias( RTL_CONSTASCII_USTRINGPARAM( "private:resource/progressbar/progressbar" ))
+ , m_aPropDocked( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_DOCKED ))
+ , m_aPropVisible( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_VISIBLE ))
+ , m_aPropDockingArea( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_DOCKINGAREA ))
+ , m_aPropDockPos( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_DOCKPOS ))
+ , m_aPropPos( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_POS ))
+ , m_aPropSize( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_SIZE ))
+ , m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_UINAME ))
+ , m_aPropStyle( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_STYLE ))
+ , m_aPropLocked( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_LOCKED ))
+ , m_aCustomizeCmd( RTL_CONSTASCII_USTRINGPARAM( "ConfigureDialog" ))
+ , m_aListenerContainer( m_aLock.getShareableOslMutex() )
+ , m_pPanelManager( 0 )
+ , m_pToolbarManager( 0 )
+{
+ // Initialize statusbar member
+ const sal_Bool bRefreshVisibility = sal_False;
+ m_aStatusBarElement.m_aType = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "statusbar" ));
+ m_aStatusBarElement.m_aName = m_aStatusBarAlias;
+
+ m_pToolbarManager = new ToolbarLayoutManager( xServiceManager, m_xUIElementFactoryManager, this );
+ m_xToolbarManager = uno::Reference< ui::XUIConfigurationListener >( static_cast< OWeakObject* >( m_pToolbarManager ), uno::UNO_QUERY );
+
+ Application::AddEventListener( LINK( this, LayoutManager, SettingsChanged ) );
+
+ m_aAsyncLayoutTimer.SetTimeout( 50 );
+ m_aAsyncLayoutTimer.SetTimeoutHdl( LINK( this, LayoutManager, AsyncLayoutHdl ) );
+
+ registerProperty( LAYOUTMANAGER_PROPNAME_AUTOMATICTOOLBARS, LAYOUTMANAGER_PROPHANDLE_AUTOMATICTOOLBARS, css::beans::PropertyAttribute::TRANSIENT, &m_bAutomaticToolbars, ::getCppuType( &m_bAutomaticToolbars ) );
+ registerProperty( LAYOUTMANAGER_PROPNAME_HIDECURRENTUI, LAYOUTMANAGER_PROPHANDLE_HIDECURRENTUI, beans::PropertyAttribute::TRANSIENT, &m_bHideCurrentUI, ::getCppuType( &m_bHideCurrentUI ) );
+ registerProperty( LAYOUTMANAGER_PROPNAME_LOCKCOUNT, LAYOUTMANAGER_PROPHANDLE_LOCKCOUNT, beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY, &m_nLockCount, getCppuType( &m_nLockCount ) );
+ registerProperty( LAYOUTMANAGER_PROPNAME_MENUBARCLOSER, LAYOUTMANAGER_PROPHANDLE_MENUBARCLOSER, beans::PropertyAttribute::TRANSIENT, &m_bMenuBarCloser, ::getCppuType( &m_bMenuBarCloser ) );
+ registerPropertyNoMember( LAYOUTMANAGER_PROPNAME_REFRESHVISIBILITY, LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY, beans::PropertyAttribute::TRANSIENT, ::getCppuType( &bRefreshVisibility ), &bRefreshVisibility );
+ registerProperty( LAYOUTMANAGER_PROPNAME_PRESERVE_CONTENT_SIZE, LAYOUTMANAGER_PROPHANDLE_PRESERVE_CONTENT_SIZE, beans::PropertyAttribute::TRANSIENT, &m_bPreserveContentSize, ::getCppuType( &m_bPreserveContentSize ) );
+}
+
+LayoutManager::~LayoutManager()
+{
+ Application::RemoveEventListener( LINK( this, LayoutManager, SettingsChanged ) );
+ m_aAsyncLayoutTimer.Stop();
+}
+
+// Internal helper function
+void LayoutManager::impl_clearUpMenuBar()
+{
+ implts_lock();
+
+ // Clear up VCL menu bar to prepare shutdown
+ if ( m_xContainerWindow.is() )
+ {
+ SolarMutexGuard aGuard;
+
+ SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
+ if ( pSysWindow )
+ {
+ MenuBar* pSetMenuBar = 0;
+ if ( m_xInplaceMenuBar.is() )
+ pSetMenuBar = (MenuBar *)m_pInplaceMenuBar->GetMenuBar();
+ else
+ {
+ Reference< awt::XMenuBar > xMenuBar;
+
+ Reference< XPropertySet > xPropSet( m_xMenuBar, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMenuBar" ))) >>= xMenuBar;
+ }
+ catch ( beans::UnknownPropertyException ) {}
+ catch ( lang::WrappedTargetException ) {}
+ }
+
+ VCLXMenu* pAwtMenuBar = VCLXMenu::GetImplementation( xMenuBar );
+ if ( pAwtMenuBar )
+ pSetMenuBar = (MenuBar*)pAwtMenuBar->GetMenu();
+ }
+
+ MenuBar* pTopMenuBar = pSysWindow->GetMenuBar();
+ if ( pSetMenuBar == pTopMenuBar )
+ pSysWindow->SetMenuBar( 0 );
+ }
+ }
+
+ // reset inplace menubar manager
+ m_pInplaceMenuBar = 0;
+ if ( m_xInplaceMenuBar.is() )
+ {
+ m_xInplaceMenuBar->dispose();
+ m_xInplaceMenuBar.clear();
+ }
+
+ Reference< XComponent > xComp( m_xMenuBar, UNO_QUERY );
+ if ( xComp.is() )
+ xComp->dispose();
+ m_xMenuBar.clear();
+ implts_unlock();
+}
+
+void LayoutManager::implts_lock()
+{
+ WriteGuard aWriteLock( m_aLock );
+ ++m_nLockCount;
+}
+
+sal_Bool LayoutManager::implts_unlock()
+{
+ WriteGuard aWriteLock( m_aLock );
+ m_nLockCount = std::max( m_nLockCount-1, static_cast<sal_Int32>(0) );
+ return ( m_nLockCount == 0 );
+}
+
+void LayoutManager::implts_reset( sal_Bool bAttached )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+ Reference< XFrame > xFrame = m_xFrame;
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+ Reference< XUIConfiguration > xModuleCfgMgr( m_xModuleCfgMgr, UNO_QUERY );
+ Reference< XUIConfiguration > xDocCfgMgr( m_xDocCfgMgr, UNO_QUERY );
+ Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
+ Reference< XMultiServiceFactory > xServiceManager( m_xSMGR );
+ Reference< XNameAccess > xPersistentWindowStateSupplier( m_xPersistentWindowStateSupplier );
+ Reference< awt::XWindowListener > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY );
+ ToolbarLayoutManager* pToolbarManager( m_pToolbarManager );
+ ::rtl::OUString aModuleIdentifier( m_aModuleIdentifier );
+ bool bAutomaticToolbars( m_bAutomaticToolbars );
+ aReadLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ implts_lock();
+
+ Reference< XModel > xModel;
+ if ( xFrame.is() )
+ {
+ if ( bAttached )
+ {
+ ::rtl::OUString aOldModuleIdentifier( aModuleIdentifier );
+ try
+ {
+ aModuleIdentifier = m_xModuleManager->identify( Reference< XInterface >( xFrame, UNO_QUERY ) );
+ }
+ catch( Exception& ) {}
+
+ if ( aModuleIdentifier.getLength() && aOldModuleIdentifier != aModuleIdentifier )
+ {
+ Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier;
+ if ( xServiceManager.is() )
+ xModuleCfgSupplier = Reference< XModuleUIConfigurationManagerSupplier >(
+ xServiceManager->createInstance( SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), UNO_QUERY );
+
+ if ( xModuleCfgMgr.is() )
+ {
+ try
+ {
+ // Remove listener to old module ui configuration manager
+ xModuleCfgMgr->removeConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& ) {}
+ }
+
+ try
+ {
+ // Add listener to new module ui configuration manager
+ xModuleCfgMgr = Reference< XUIConfiguration >( xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier ), UNO_QUERY );
+ if ( xModuleCfgMgr.is() )
+ xModuleCfgMgr->addConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& ) {}
+
+ try
+ {
+ // Retrieve persistent window state reference for our new module
+ if ( xPersistentWindowStateSupplier.is() )
+ xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= xPersistentWindowState;
+ }
+ catch ( NoSuchElementException& ) {}
+ catch ( WrappedTargetException& ) {}
+ }
+
+ xModel = impl_getModelFromFrame( xFrame );
+ if ( xModel.is() )
+ {
+ Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY );
+ if ( xUIConfigurationManagerSupplier.is() )
+ {
+ if ( xDocCfgMgr.is() )
+ {
+ try
+ {
+ // Remove listener to old ui configuration manager
+ xDocCfgMgr->removeConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& ) {}
+ }
+
+ try
+ {
+ xDocCfgMgr = Reference< XUIConfiguration >( xUIConfigurationManagerSupplier->getUIConfigurationManager(), UNO_QUERY );
+ if ( xDocCfgMgr.is() )
+ xDocCfgMgr->addConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& ) {}
+ }
+ }
+ }
+ else
+ {
+ // Remove configuration listeners before we can release our references
+ if ( xModuleCfgMgr.is() )
+ {
+ try
+ {
+ xModuleCfgMgr->removeConfigurationListener(
+ Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& ) {}
+ }
+
+ if ( xDocCfgMgr.is() )
+ {
+ try
+ {
+ xDocCfgMgr->removeConfigurationListener(
+ Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& ) {}
+ }
+
+ // Release references to our configuration managers as we currently don't have
+ // an attached module.
+ xModuleCfgMgr.clear();
+ xDocCfgMgr.clear();
+ xPersistentWindowState.clear();
+ aModuleIdentifier = ::rtl::OUString();
+ }
+
+ Reference< XUIConfigurationManager > xModCfgMgr( xModuleCfgMgr, UNO_QUERY );
+ Reference< XUIConfigurationManager > xDokCfgMgr( xDocCfgMgr, UNO_QUERY );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ m_xModel = xModel;
+ m_aDockingArea = awt::Rectangle();
+ m_bComponentAttached = bAttached;
+ m_aModuleIdentifier = aModuleIdentifier;
+ m_xModuleCfgMgr = xModCfgMgr;
+ m_xDocCfgMgr = xDokCfgMgr;
+ m_xPersistentWindowState = xPersistentWindowState;
+ m_aStatusBarElement.m_bStateRead = sal_False; // reset state to read data again!
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ // reset/notify toolbar layout manager
+ if ( pToolbarManager )
+ {
+ if ( bAttached )
+ {
+ pToolbarManager->attach( xFrame, xModCfgMgr, xDokCfgMgr, xPersistentWindowState );
+ uno::Reference< awt::XWindowPeer > xParent( xContainerWindow, UNO_QUERY );
+ pToolbarManager->setParentWindow( xParent );
+ if ( bAutomaticToolbars )
+ pToolbarManager->createStaticToolbars();
+ }
+ else
+ {
+ pToolbarManager->reset();
+ implts_destroyElements();
+ }
+ }
+ }
+
+ implts_unlock();
+}
+
+sal_Bool LayoutManager::implts_isEmbeddedLayoutManager() const
+{
+ ReadGuard aReadLock( m_aLock );
+ Reference< XFrame > xFrame = m_xFrame;
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+ aReadLock.unlock();
+
+ Reference< awt::XWindow > xFrameContainerWindow = xFrame->getContainerWindow();
+ if ( xFrameContainerWindow == xContainerWindow )
+ return sal_False;
+ else
+ return sal_True;
+}
+
+void LayoutManager::implts_destroyElements()
+{
+ WriteGuard aWriteLock( m_aLock );
+ uno::Reference< ui::XUIConfigurationListener > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aWriteLock.unlock();
+
+ if ( pToolbarManager )
+ pToolbarManager->destroyToolbars();
+
+ implts_destroyStatusBar();
+
+ aWriteLock.lock();
+ impl_clearUpMenuBar();
+ aWriteLock.unlock();
+}
+
+void LayoutManager::implts_toggleFloatingUIElementsVisibility( sal_Bool bActive )
+{
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< ui::XUIConfigurationListener > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ pToolbarManager->setFloatingToolbarsVisibility( bActive );
+}
+
+uno::Reference< ui::XUIElement > LayoutManager::implts_findElement( const rtl::OUString& aName )
+{
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+
+ parseResourceURL( aName, aElementType, aElementName );
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" ))
+ return m_xMenuBar;
+ else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || ( m_aStatusBarElement.m_aName == aName ))
+ return m_aStatusBarElement.m_xUIElement;
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ))
+ return m_aProgressBarElement.m_xUIElement;
+
+ return uno::Reference< ui::XUIElement >();
+}
+
+UIElement& LayoutManager::impl_findElement( const rtl::OUString& aName )
+{
+ static UIElement aEmptyElement;
+
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+
+ parseResourceURL( aName, aElementType, aElementName );
+ if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || ( m_aStatusBarElement.m_aName == aName ))
+ return m_aStatusBarElement;
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ))
+ return m_aProgressBarElement;
+
+ return aEmptyElement;
+}
+
+sal_Bool LayoutManager::implts_readWindowStateData( const rtl::OUString& aName, UIElement& rElementData )
+{
+ sal_Bool bGetSettingsState( sal_False );
+
+ WriteGuard aWriteLock( m_aLock );
+ Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
+ aWriteLock.unlock();
+
+ if ( xPersistentWindowState.is() )
+ {
+ aWriteLock.lock();
+ sal_Bool bGlobalSettings( m_bGlobalSettings );
+ GlobalSettings* pGlobalSettings( 0 );
+ if ( m_pGlobalSettings == 0 )
+ {
+ m_pGlobalSettings = new GlobalSettings( m_xSMGR );
+ bGetSettingsState = sal_True;
+ }
+ pGlobalSettings = m_pGlobalSettings;
+ aWriteLock.unlock();
+
+ try
+ {
+ Sequence< PropertyValue > aWindowState;
+ if ( xPersistentWindowState->hasByName( aName ) && (xPersistentWindowState->getByName( aName ) >>= aWindowState) )
+ {
+ sal_Bool bValue( sal_False );
+ for ( sal_Int32 n = 0; n < aWindowState.getLength(); n++ )
+ {
+ if ( aWindowState[n].Name == m_aPropDocked )
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bFloating = !bValue;
+ }
+ else if ( aWindowState[n].Name == m_aPropVisible )
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bVisible = bValue;
+ }
+ else if ( aWindowState[n].Name == m_aPropDockingArea )
+ {
+ ui::DockingArea eDockingArea;
+ if ( aWindowState[n].Value >>= eDockingArea )
+ rElementData.m_aDockedData.m_nDockedArea = sal_Int16( eDockingArea );
+ }
+ else if ( aWindowState[n].Name == m_aPropDockPos )
+ {
+ awt::Point aPoint;
+ if ( aWindowState[n].Value >>= aPoint )
+ {
+ rElementData.m_aDockedData.m_aPos.X() = aPoint.X;
+ rElementData.m_aDockedData.m_aPos.Y() = aPoint.Y;
+ }
+ }
+ else if ( aWindowState[n].Name == m_aPropPos )
+ {
+ awt::Point aPoint;
+ if ( aWindowState[n].Value >>= aPoint )
+ {
+ rElementData.m_aFloatingData.m_aPos.X() = aPoint.X;
+ rElementData.m_aFloatingData.m_aPos.Y() = aPoint.Y;
+ }
+ }
+ else if ( aWindowState[n].Name == m_aPropSize )
+ {
+ awt::Size aSize;
+ if ( aWindowState[n].Value >>= aSize )
+ {
+ rElementData.m_aFloatingData.m_aSize.Width() = aSize.Width;
+ rElementData.m_aFloatingData.m_aSize.Height() = aSize.Height;
+ }
+ }
+ else if ( aWindowState[n].Name == m_aPropUIName )
+ aWindowState[n].Value >>= rElementData.m_aUIName;
+ else if ( aWindowState[n].Name == m_aPropStyle )
+ {
+ sal_Int32 nStyle = 0;
+ if ( aWindowState[n].Value >>= nStyle )
+ rElementData.m_nStyle = sal_Int16( nStyle );
+ }
+ else if ( aWindowState[n].Name == m_aPropLocked )
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_aDockedData.m_bLocked = bValue;
+ }
+ else if ( aWindowState[n].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(WINDOWSTATE_PROPERTY_CONTEXT)))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bContextSensitive = bValue;
+ }
+ else if ( aWindowState[n].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(WINDOWSTATE_PROPERTY_NOCLOSE)))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bNoClose = bValue;
+ }
+ else if ( aWindowState[n].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(WINDOWSTATE_PROPERTY_CONTEXTACTIVE)))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bContextActive = bValue;
+ }
+ else if ( aWindowState[n].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(WINDOWSTATE_PROPERTY_SOFTCLOSE)))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bSoftClose = bValue;
+ }
+ }
+ }
+
+ // oversteer values with global settings
+ if ( pGlobalSettings && ( bGetSettingsState || bGlobalSettings ))
+ {
+ if ( pGlobalSettings->HasStatesInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR ))
+ {
+ WriteGuard aWriteLock2( m_aLock );
+ m_bGlobalSettings = sal_True;
+ aWriteLock2.unlock();
+
+ uno::Any aValue;
+ sal_Bool bValue = sal_Bool();
+ if ( pGlobalSettings->GetStateInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR,
+ GlobalSettings::STATEINFO_LOCKED,
+ aValue ))
+ aValue >>= rElementData.m_aDockedData.m_bLocked;
+ if ( pGlobalSettings->GetStateInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR,
+ GlobalSettings::STATEINFO_DOCKED,
+ aValue ))
+ {
+ if ( aValue >>= bValue )
+ rElementData.m_bFloating = !bValue;
+ }
+ }
+ }
+
+ return sal_True;
+ }
+ catch ( NoSuchElementException& ) {}
+ }
+
+ return sal_False;
+}
+
+void LayoutManager::implts_writeWindowStateData( const rtl::OUString& aName, const UIElement& rElementData )
+{
+ WriteGuard aWriteLock( m_aLock );
+ Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
+
+ // set flag to determine that we triggered the notification
+ m_bStoreWindowState = sal_True;
+ aWriteLock.unlock();
+
+ sal_Bool bPersistent( sal_False );
+ Reference< XPropertySet > xPropSet( rElementData.m_xUIElement, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ // Check persistent flag of the user interface element
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" ))) >>= bPersistent;
+ }
+ catch ( beans::UnknownPropertyException )
+ {
+ // Non-configurable elements should at least store their dimension/position
+ bPersistent = sal_True;
+ }
+ catch ( lang::WrappedTargetException ) {}
+ }
+
+ if ( bPersistent && xPersistentWindowState.is() )
+ {
+ try
+ {
+ Sequence< PropertyValue > aWindowState( 8 );
+
+ aWindowState[0].Name = m_aPropDocked;
+ aWindowState[0].Value = makeAny( sal_Bool( !rElementData.m_bFloating ));
+ aWindowState[1].Name = m_aPropVisible;
+ aWindowState[1].Value = makeAny( sal_Bool( rElementData.m_bVisible ));
+
+ aWindowState[2].Name = m_aPropDockingArea;
+ aWindowState[2].Value = makeAny( static_cast< DockingArea >( rElementData.m_aDockedData.m_nDockedArea ) );
+
+ awt::Point aPos;
+ aPos.X = rElementData.m_aDockedData.m_aPos.X();
+ aPos.Y = rElementData.m_aDockedData.m_aPos.Y();
+ aWindowState[3].Name = m_aPropDockPos;
+ aWindowState[3].Value <<= aPos;
+
+ aPos.X = rElementData.m_aFloatingData.m_aPos.X();
+ aPos.Y = rElementData.m_aFloatingData.m_aPos.Y();
+ aWindowState[4].Name = m_aPropPos;
+ aWindowState[4].Value <<= aPos;
+
+ awt::Size aSize;
+ aSize.Width = rElementData.m_aFloatingData.m_aSize.Width();
+ aSize.Height = rElementData.m_aFloatingData.m_aSize.Height();
+ aWindowState[5].Name = m_aPropSize;
+ aWindowState[5].Value <<= aSize;
+ aWindowState[6].Name = m_aPropUIName;
+ aWindowState[6].Value = makeAny( rElementData.m_aUIName );
+ aWindowState[7].Name = m_aPropLocked;
+ aWindowState[7].Value = makeAny( rElementData.m_aDockedData.m_bLocked );
+
+ if ( xPersistentWindowState->hasByName( aName ))
+ {
+ Reference< XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY );
+ xReplace->replaceByName( aName, makeAny( aWindowState ));
+ }
+ else
+ {
+ Reference< XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY );
+ xInsert->insertByName( aName, makeAny( aWindowState ));
+ }
+ }
+ catch ( Exception& ) {}
+ }
+
+ // Reset flag
+ aWriteLock.lock();
+ m_bStoreWindowState = sal_False;
+ aWriteLock.unlock();
+}
+
+::Size LayoutManager::implts_getContainerWindowOutputSize()
+{
+ ::Size aContainerWinSize;
+ Window* pContainerWindow( 0 );
+
+ // Retrieve output size from container Window
+ SolarMutexGuard aGuard;
+ pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
+ if ( pContainerWindow )
+ aContainerWinSize = pContainerWindow->GetOutputSizePixel();
+
+ return aContainerWinSize;
+}
+
+Reference< XUIElement > LayoutManager::implts_createElement( const rtl::OUString& aName )
+{
+ Reference< ui::XUIElement > xUIElement;
+
+ ReadGuard aReadLock( m_aLock );
+ Sequence< PropertyValue > aPropSeq( 2 );
+ aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropSeq[0].Value <<= m_xFrame;
+ aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" ));
+ aPropSeq[1].Value <<= sal_True;
+
+ try
+ {
+ xUIElement = m_xUIElementFactoryManager->createUIElement( aName, aPropSeq );
+ }
+ catch ( NoSuchElementException& ) {}
+ catch ( IllegalArgumentException& ) {}
+
+ return xUIElement;
+}
+
+void LayoutManager::implts_setVisibleState( sal_Bool bShow )
+{
+ WriteGuard aWriteLock( m_aLock );
+ m_aStatusBarElement.m_bMasterHide = !bShow;
+ aWriteLock.unlock();
+
+ implts_updateUIElementsVisibleState( bShow );
+}
+
+void LayoutManager::implts_updateUIElementsVisibleState( sal_Bool bSetVisible )
+{
+ // notify listeners
+ uno::Any a;
+ if ( bSetVisible )
+ implts_notifyListeners( frame::LayoutManagerEvents::VISIBLE, a );
+ else
+ implts_notifyListeners( frame::LayoutManagerEvents::INVISIBLE, a );
+ std::vector< Reference< awt::XWindow > > aWinVector;
+
+ WriteGuard aWriteLock( m_aLock );
+ Reference< XUIElement > xMenuBar( m_xMenuBar, UNO_QUERY );
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+ Reference< XComponent > xInplaceMenuBar( m_xInplaceMenuBar );
+ MenuBarManager* pInplaceMenuBar( m_pInplaceMenuBar );
+ aWriteLock.unlock();
+
+ bool bMustDoLayout(false);
+ if (( xMenuBar.is() || xInplaceMenuBar.is() ) && xContainerWindow.is() )
+ {
+ SolarMutexGuard aGuard;
+
+ MenuBar* pMenuBar( 0 );
+ if ( xInplaceMenuBar.is() )
+ pMenuBar = (MenuBar *)pInplaceMenuBar->GetMenuBar();
+ else
+ {
+ MenuBarWrapper* pMenuBarWrapper = SAL_STATIC_CAST( MenuBarWrapper*, xMenuBar.get() );
+ pMenuBar = (MenuBar *)pMenuBarWrapper->GetMenuBarManager()->GetMenuBar();
+ }
+
+ SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
+ if ( pSysWindow )
+ {
+ if ( bSetVisible )
+ pSysWindow->SetMenuBar( pMenuBar );
+ else
+ pSysWindow->SetMenuBar( 0 );
+ bMustDoLayout = true;
+ }
+ }
+
+ // Hide/show the statusbar according to bSetVisible
+ if ( bSetVisible )
+ bMustDoLayout = !implts_showStatusBar();
+ else
+ bMustDoLayout = !implts_hideStatusBar();
+
+ aWriteLock.lock();
+ uno::Reference< ui::XUIConfigurationListener > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager( m_pToolbarManager );
+ aWriteLock.unlock();
+
+ if ( pToolbarManager )
+ {
+ pToolbarManager->setVisible( bSetVisible );
+ bMustDoLayout = pToolbarManager->isLayoutDirty();
+ }
+
+ if ( bMustDoLayout )
+ implts_doLayout_notify( sal_False );
+}
+
+void LayoutManager::implts_setCurrentUIVisibility( sal_Bool bShow )
+{
+ WriteGuard aWriteLock( m_aLock );
+ if ( !bShow && m_aStatusBarElement.m_bVisible && m_aStatusBarElement.m_xUIElement.is() )
+ m_aStatusBarElement.m_bMasterHide = true;
+ else if ( bShow && m_aStatusBarElement.m_bVisible )
+ m_aStatusBarElement.m_bMasterHide = false;
+ aWriteLock.unlock();
+
+ implts_updateUIElementsVisibleState( bShow );
+}
+
+void LayoutManager::implts_destroyStatusBar()
+{
+ Reference< XComponent > xCompStatusBar;
+
+ WriteGuard aWriteLock( m_aLock );
+ m_aStatusBarElement.m_aName = rtl::OUString();
+ xCompStatusBar = Reference< XComponent >( m_aStatusBarElement.m_xUIElement, UNO_QUERY );
+ m_aStatusBarElement.m_xUIElement.clear();
+ aWriteLock.unlock();
+
+ if ( xCompStatusBar.is() )
+ xCompStatusBar->dispose();
+
+ implts_destroyProgressBar();
+}
+
+void LayoutManager::implts_createStatusBar( const rtl::OUString& aStatusBarName )
+{
+ WriteGuard aWriteLock( m_aLock );
+ if ( !m_aStatusBarElement.m_xUIElement.is() )
+ {
+ implts_readStatusBarState( aStatusBarName );
+ m_aStatusBarElement.m_aName = aStatusBarName;
+ m_aStatusBarElement.m_xUIElement = implts_createElement( aStatusBarName );
+ }
+ aWriteLock.unlock();
+
+ implts_createProgressBar();
+}
+
+void LayoutManager::implts_readStatusBarState( const rtl::OUString& rStatusBarName )
+{
+ WriteGuard aWriteLock( m_aLock );
+ if ( !m_aStatusBarElement.m_bStateRead )
+ {
+ // Read persistent data for status bar if not yet read!
+ if ( implts_readWindowStateData( rStatusBarName, m_aStatusBarElement ))
+ m_aStatusBarElement.m_bStateRead = sal_True;
+ }
+}
+
+void LayoutManager::implts_createProgressBar()
+{
+ Reference< XUIElement > xStatusBar;
+ Reference< XUIElement > xProgressBar;
+ Reference< XUIElement > xProgressBarBackup;
+ Reference< awt::XWindow > xContainerWindow;
+
+ WriteGuard aWriteLock( m_aLock );
+ xStatusBar = Reference< XUIElement >( m_aStatusBarElement.m_xUIElement, UNO_QUERY );
+ xProgressBar = Reference< XUIElement >( m_aProgressBarElement.m_xUIElement, UNO_QUERY );
+ xProgressBarBackup = m_xProgressBarBackup;
+ m_xProgressBarBackup.clear();
+ xContainerWindow = m_xContainerWindow;
+ aWriteLock.unlock();
+
+ sal_Bool bRecycled = xProgressBarBackup.is();
+ ProgressBarWrapper* pWrapper = 0;
+ if ( bRecycled )
+ pWrapper = (ProgressBarWrapper*)xProgressBarBackup.get();
+ else if ( xProgressBar.is() )
+ pWrapper = (ProgressBarWrapper*)xProgressBar.get();
+ else
+ pWrapper = new ProgressBarWrapper();
+
+ if ( xStatusBar.is() )
+ {
+ Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY );
+ pWrapper->setStatusBar( xWindow );
+ }
+ else
+ {
+ Reference< awt::XWindow > xStatusBarWindow = pWrapper->getStatusBar();
+
+ SolarMutexGuard aGuard;
+ Window* pStatusBarWnd = VCLUnoHelper::GetWindow( xStatusBarWindow );
+ if ( !pStatusBarWnd )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ if ( pWindow )
+ {
+ StatusBar* pStatusBar = new StatusBar( pWindow, WinBits( WB_LEFT | WB_3DLOOK ) );
+ Reference< awt::XWindow > xStatusBarWindow2( VCLUnoHelper::GetInterface( pStatusBar ));
+ pWrapper->setStatusBar( xStatusBarWindow2, sal_True );
+ }
+ }
+ }
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ aWriteLock.lock();
+ m_aProgressBarElement.m_xUIElement = Reference< XUIElement >(
+ static_cast< cppu::OWeakObject* >( pWrapper ), UNO_QUERY );
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ if ( bRecycled )
+ implts_showProgressBar();
+}
+
+void LayoutManager::implts_backupProgressBarWrapper()
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_xProgressBarBackup.is())
+ return;
+
+ // safe a backup copy of the current progress!
+ // This copy will be used automaticly inside createProgressBar() which is called
+ // implictly from implts_doLayout() .-)
+ m_xProgressBarBackup = m_aProgressBarElement.m_xUIElement;
+
+ // remove the relation between this old progress bar and our old status bar.
+ // Otherwhise we work on disposed items ...
+ // The internal used ProgressBarWrapper can handle a NULL reference.
+ if ( m_xProgressBarBackup.is() )
+ {
+ ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)m_xProgressBarBackup.get();
+ if ( pWrapper )
+ pWrapper->setStatusBar( Reference< awt::XWindow >(), sal_False );
+ }
+
+ // prevent us from dispose() the m_aProgressBarElement.m_xUIElement inside implts_reset()
+ m_aProgressBarElement.m_xUIElement.clear();
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+void LayoutManager::implts_destroyProgressBar()
+{
+ // dont remove the progressbar in general
+ // We must reuse it if a new status bar is created later.
+ // Of course there exists one backup only.
+ // And further this backup will be released inside our dtor.
+ implts_backupProgressBarWrapper();
+}
+
+void LayoutManager::implts_setStatusBarPosSize( const ::Point& rPos, const ::Size& rSize )
+{
+ Reference< XUIElement > xStatusBar;
+ Reference< XUIElement > xProgressBar;
+ Reference< awt::XWindow > xContainerWindow;
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+ xStatusBar = Reference< XUIElement >( m_aStatusBarElement.m_xUIElement, UNO_QUERY );
+ xProgressBar = Reference< XUIElement >( m_aProgressBarElement.m_xUIElement, UNO_QUERY );
+ xContainerWindow = m_xContainerWindow;
+
+ Reference< awt::XWindow > xWindow;
+ if ( xStatusBar.is() )
+ xWindow = Reference< awt::XWindow >( xStatusBar->getRealInterface(), UNO_QUERY );
+ else if ( xProgressBar.is() )
+ {
+ ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)xProgressBar.get();
+ if ( pWrapper )
+ xWindow = pWrapper->getStatusBar();
+ }
+ aReadLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ if ( xWindow.is() )
+ {
+ SolarMutexGuard aGuard;
+ Window* pParentWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pParentWindow && ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR ))
+ {
+ Window* pOldParentWindow = pWindow->GetParent();
+ if ( pParentWindow != pOldParentWindow )
+ pWindow->SetParent( pParentWindow );
+ ((StatusBar *)pWindow)->SetPosSizePixel( rPos, rSize );
+ }
+ }
+}
+
+sal_Bool LayoutManager::implts_showProgressBar()
+{
+ Reference< XUIElement > xStatusBar;
+ Reference< XUIElement > xProgressBar;
+ Reference< awt::XWindow > xWindow;
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ xStatusBar = Reference< XUIElement >( m_aStatusBarElement.m_xUIElement, UNO_QUERY );
+ xProgressBar = Reference< XUIElement >( m_aProgressBarElement.m_xUIElement, UNO_QUERY );
+ sal_Bool bVisible( m_bVisible );
+
+ m_aProgressBarElement.m_bVisible = sal_True;
+ if ( bVisible )
+ {
+ if ( xStatusBar.is() && !m_aStatusBarElement.m_bMasterHide )
+ {
+ xWindow = Reference< awt::XWindow >( xStatusBar->getRealInterface(), UNO_QUERY );
+ }
+ else if ( xProgressBar.is() )
+ {
+ ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)xProgressBar.get();
+ if ( pWrapper )
+ xWindow = pWrapper->getStatusBar();
+ }
+ }
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow )
+ {
+ if ( !pWindow->IsVisible() )
+ {
+ implts_setOffset( pWindow->GetSizePixel().Height() );
+ pWindow->Show();
+ implts_doLayout_notify( sal_False );
+ }
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+sal_Bool LayoutManager::implts_hideProgressBar()
+{
+ Reference< XUIElement > xProgressBar;
+ Reference< awt::XWindow > xWindow;
+ sal_Bool bHideStatusBar( sal_False );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ xProgressBar = Reference< XUIElement >( m_aProgressBarElement.m_xUIElement, UNO_QUERY );
+
+ sal_Bool bInternalStatusBar( sal_False );
+ if ( xProgressBar.is() )
+ {
+ Reference< awt::XWindow > xStatusBar;
+ ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)xProgressBar.get();
+ if ( pWrapper )
+ xWindow = pWrapper->getStatusBar();
+ Reference< ui::XUIElement > xStatusBarElement = m_aStatusBarElement.m_xUIElement;
+ if ( xStatusBarElement.is() )
+ xStatusBar = Reference< awt::XWindow >( xStatusBarElement->getRealInterface(), UNO_QUERY );
+ bInternalStatusBar = xStatusBar != xWindow;
+ }
+ m_aProgressBarElement.m_bVisible = sal_False;
+ implts_readStatusBarState( m_aStatusBarAlias );
+ bHideStatusBar = !m_aStatusBarElement.m_bVisible;
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->IsVisible() && ( bHideStatusBar || bInternalStatusBar ))
+ {
+ implts_setOffset( 0 );
+ pWindow->Hide();
+ implts_doLayout_notify( sal_False );
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+sal_Bool LayoutManager::implts_showStatusBar( sal_Bool bStoreState )
+{
+ WriteGuard aWriteLock( m_aLock );
+ Reference< ui::XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement;
+ if ( bStoreState )
+ m_aStatusBarElement.m_bVisible = sal_True;
+ aWriteLock.unlock();
+
+ if ( xStatusBar.is() )
+ {
+ Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY );
+
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && !pWindow->IsVisible() )
+ {
+ implts_setOffset( pWindow->GetSizePixel().Height() );
+ pWindow->Show();
+ implts_doLayout_notify( sal_False );
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+sal_Bool LayoutManager::implts_hideStatusBar( sal_Bool bStoreState )
+{
+ WriteGuard aWriteLock( m_aLock );
+ Reference< ui::XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement;
+ if ( bStoreState )
+ m_aStatusBarElement.m_bVisible = sal_False;
+ aWriteLock.unlock();
+
+ if ( xStatusBar.is() )
+ {
+ Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY );
+
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->IsVisible() )
+ {
+ implts_setOffset( 0 );
+ pWindow->Hide();
+ implts_doLayout_notify( sal_False );
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+void LayoutManager::implts_setOffset( const sal_Int32 nBottomOffset )
+{
+ ::Rectangle aOffsetRect;
+ setZeroRectangle( aOffsetRect );
+ aOffsetRect.setHeight( nBottomOffset );
+
+ // make sure that the toolbar manager refernence/pointer is valid
+ uno::Reference< ui::XUIConfigurationListener > xThis( m_xToolbarManager );
+ if ( xThis.is() )
+ m_pToolbarManager->setDockingAreaOffsets( aOffsetRect );
+}
+
+void LayoutManager::implts_setInplaceMenuBar( const Reference< XIndexAccess >& xMergedMenuBar )
+throw (uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ if ( !m_bInplaceMenuSet )
+ {
+ SolarMutexGuard aGuard;
+
+ // Reset old inplace menubar!
+ m_pInplaceMenuBar = 0;
+ if ( m_xInplaceMenuBar.is() )
+ m_xInplaceMenuBar->dispose();
+ m_xInplaceMenuBar.clear();
+ m_bInplaceMenuSet = sal_False;
+
+ if ( m_xFrame.is() && m_xContainerWindow.is() )
+ {
+ rtl::OUString aModuleIdentifier;
+ Reference< XDispatchProvider > xDispatchProvider;
+
+ MenuBar* pMenuBar = new MenuBar;
+ m_pInplaceMenuBar = new MenuBarManager( m_xSMGR, m_xFrame, m_xURLTransformer,xDispatchProvider, aModuleIdentifier, pMenuBar, sal_True, sal_True );
+ m_pInplaceMenuBar->SetItemContainer( xMergedMenuBar );
+
+ SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
+ if ( pSysWindow )
+ pSysWindow->SetMenuBar( pMenuBar );
+
+ m_bInplaceMenuSet = sal_True;
+ m_xInplaceMenuBar = Reference< XComponent >( (OWeakObject *)m_pInplaceMenuBar, UNO_QUERY );
+ }
+
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ implts_updateMenuBarClose();
+ }
+}
+
+void LayoutManager::implts_resetInplaceMenuBar()
+throw (uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ m_bInplaceMenuSet = sal_False;
+
+ if ( m_xContainerWindow.is() )
+ {
+ SolarMutexGuard aGuard;
+ MenuBarWrapper* pMenuBarWrapper = SAL_STATIC_CAST( MenuBarWrapper*, m_xMenuBar.get() );
+ SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
+ if ( pSysWindow )
+ {
+ if ( pMenuBarWrapper )
+ pSysWindow->SetMenuBar( (MenuBar *)pMenuBarWrapper->GetMenuBarManager()->GetMenuBar() );
+ else
+ pSysWindow->SetMenuBar( 0 );
+ }
+ }
+
+ // Remove inplace menu bar
+ m_pInplaceMenuBar = 0;
+ if ( m_xInplaceMenuBar.is() )
+ m_xInplaceMenuBar->dispose();
+ m_xInplaceMenuBar.clear();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+}
+
+void SAL_CALL LayoutManager::attachFrame( const Reference< XFrame >& xFrame )
+throw (uno::RuntimeException)
+{
+ WriteGuard aWriteLock( m_aLock );
+ m_xFrame = xFrame;
+}
+
+void SAL_CALL LayoutManager::reset()
+throw (RuntimeException)
+{
+ implts_reset( sal_True );
+}
+
+void SAL_CALL LayoutManager::setInplaceMenuBar( sal_Int64 )
+throw (uno::RuntimeException)
+{
+ OSL_FAIL( "This method is obsolete and should not be used!\n" );
+}
+
+void SAL_CALL LayoutManager::resetInplaceMenuBar()
+throw (uno::RuntimeException)
+{
+ OSL_FAIL( "This method is obsolete and should not be used!\n" );
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XMenuBarMergingAcceptor
+//---------------------------------------------------------------------------------------------------------
+sal_Bool SAL_CALL LayoutManager::setMergedMenuBar(
+ const Reference< XIndexAccess >& xMergedMenuBar )
+throw (uno::RuntimeException)
+{
+ implts_setInplaceMenuBar( xMergedMenuBar );
+
+ uno::Any a;
+ implts_notifyListeners( frame::LayoutManagerEvents::MERGEDMENUBAR, a );
+ return sal_True;
+}
+
+void SAL_CALL LayoutManager::removeMergedMenuBar()
+throw (uno::RuntimeException)
+{
+ implts_resetInplaceMenuBar();
+}
+
+awt::Rectangle SAL_CALL LayoutManager::getCurrentDockingArea()
+throw ( RuntimeException )
+{
+ ReadGuard aReadLock( m_aLock );
+ return m_aDockingArea;
+}
+
+Reference< XDockingAreaAcceptor > SAL_CALL LayoutManager::getDockingAreaAcceptor()
+throw (uno::RuntimeException)
+{
+ ReadGuard aReadLock( m_aLock );
+ return m_xDockingAreaAcceptor;
+}
+
+void SAL_CALL LayoutManager::setDockingAreaAcceptor( const Reference< ui::XDockingAreaAcceptor >& xDockingAreaAcceptor )
+throw ( RuntimeException )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ if (( m_xDockingAreaAcceptor == xDockingAreaAcceptor ) || !m_xFrame.is() )
+ return;
+
+ // IMPORTANT: Be sure to stop layout timer if don't have a docking area acceptor!
+ if ( !xDockingAreaAcceptor.is() )
+ m_aAsyncLayoutTimer.Stop();
+
+ sal_Bool bAutomaticToolbars( m_bAutomaticToolbars );
+ std::vector< Reference< awt::XWindow > > oldDockingAreaWindows;
+
+ uno::Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+
+ if ( !xDockingAreaAcceptor.is() )
+ m_aAsyncLayoutTimer.Stop();
+
+ // Remove listener from old docking area acceptor
+ if ( m_xDockingAreaAcceptor.is() )
+ {
+ Reference< awt::XWindow > xWindow( m_xDockingAreaAcceptor->getContainerWindow() );
+ if ( xWindow.is() && ( m_xFrame->getContainerWindow() != m_xContainerWindow || !xDockingAreaAcceptor.is() ) )
+ xWindow->removeWindowListener( Reference< awt::XWindowListener >( static_cast< OWeakObject * >( this ), UNO_QUERY ));
+
+ m_aDockingArea = awt::Rectangle();
+ if ( pToolbarManager )
+ pToolbarManager->resetDockingArea();
+
+ Window* pContainerWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pContainerWindow )
+ pContainerWindow->RemoveChildEventListener( LINK( this, LayoutManager, WindowEventListener ) );
+ }
+
+ Reference< ui::XDockingAreaAcceptor > xOldDockingAreaAcceptor( m_xDockingAreaAcceptor );
+ m_xDockingAreaAcceptor = xDockingAreaAcceptor;
+ if ( m_xDockingAreaAcceptor.is() )
+ {
+ m_aDockingArea = awt::Rectangle();
+ m_xContainerWindow = m_xDockingAreaAcceptor->getContainerWindow();
+ m_xContainerTopWindow.set( m_xContainerWindow, UNO_QUERY );
+ m_xContainerWindow->addWindowListener( Reference< awt::XWindowListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+
+ // we always must keep a connection to the window of our frame for resize events
+ if ( m_xContainerWindow != m_xFrame->getContainerWindow() )
+ m_xFrame->getContainerWindow()->addWindowListener( Reference< awt::XWindowListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+
+ // #i37884# set initial visibility state - in the plugin case the container window is already shown
+ // and we get no notification anymore
+ {
+ SolarMutexGuard aGuard;
+ Window* pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
+ if( pContainerWindow )
+ m_bParentWindowVisible = pContainerWindow->IsVisible();
+ }
+
+ uno::Reference< awt::XWindowPeer > xParent( m_xContainerWindow, UNO_QUERY );
+ }
+
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ if ( xDockingAreaAcceptor.is() )
+ {
+ SolarMutexGuard aGuard;
+
+ // Add layout manager as listener to get notifications about toolbar button activties
+ Window* pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
+ if ( pContainerWindow )
+ pContainerWindow->AddChildEventListener( LINK( this, LayoutManager, WindowEventListener ) );
+
+ // We have now a new container window, reparent all child windows!
+ implts_reparentChildWindows();
+ }
+ else
+ implts_destroyElements(); // remove all elements
+
+ if ( !oldDockingAreaWindows.empty() )
+ {
+ // Reset docking area size for our old docking area acceptor
+ awt::Rectangle aEmptyRect;
+ xOldDockingAreaAcceptor->setDockingAreaSpace( aEmptyRect );
+ }
+
+ if ( xDockingAreaAcceptor.is() )
+ {
+ if ( bAutomaticToolbars )
+ {
+ lock();
+ pToolbarManager->createStaticToolbars();
+ unlock();
+ }
+ implts_doLayout( sal_True, sal_False );
+ }
+}
+
+void LayoutManager::implts_reparentChildWindows()
+{
+ WriteGuard aWriteLock( m_aLock );
+ UIElement aStatusBarElement = m_aStatusBarElement;
+ uno::Reference< awt::XWindow > xContainerWindow = m_xContainerWindow;
+ aWriteLock.unlock();
+
+ uno::Reference< awt::XWindow > xStatusBarWindow;
+ if ( aStatusBarElement.m_xUIElement.is() )
+ {
+ try
+ {
+ xStatusBarWindow = Reference< awt::XWindow >( aStatusBarElement.m_xUIElement->getRealInterface(), UNO_QUERY );
+ }
+ catch ( RuntimeException& ) { throw; }
+ catch ( Exception& ) {}
+ }
+
+ if ( xStatusBarWindow.is() )
+ {
+ SolarMutexGuard aGuard;
+ Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ Window* pWindow = VCLUnoHelper::GetWindow( xStatusBarWindow );
+ if ( pWindow && pContainerWindow )
+ pWindow->SetParent( pContainerWindow );
+ }
+
+ implts_resetMenuBar();
+
+ aWriteLock.lock();
+ uno::Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ if ( pToolbarManager )
+ pToolbarManager->setParentWindow( uno::Reference< awt::XWindowPeer >( xContainerWindow, uno::UNO_QUERY ));
+ aWriteLock.unlock();
+}
+
+uno::Reference< ui::XUIElement > LayoutManager::implts_createDockingWindow( const ::rtl::OUString& aElementName )
+{
+ Reference< XUIElement > xUIElement = implts_createElement( aElementName );
+ return xUIElement;
+}
+
+IMPL_LINK( LayoutManager, WindowEventListener, VclSimpleEvent*, pEvent )
+{
+ long nResult( 1 );
+
+ if ( pEvent && pEvent->ISA( VclWindowEvent ))
+ {
+ Window* pWindow = static_cast< VclWindowEvent* >(pEvent)->GetWindow();
+ if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< ui::XUIConfigurationListener > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager( m_pToolbarManager );
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ nResult = pToolbarManager->childWindowEvent( pEvent );
+ }
+ }
+
+ return nResult;
+}
+
+void SAL_CALL LayoutManager::createElement( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::createElement" );
+
+ ReadGuard aReadLock( m_aLock );
+ Reference< XFrame > xFrame = m_xFrame;
+ Reference< XURLTransformer > xURLTransformer = m_xURLTransformer;
+ sal_Bool bInPlaceMenu = m_bInplaceMenuSet;
+ aReadLock.unlock();
+
+ if ( !xFrame.is() )
+ return;
+
+ Reference< XModel > xModel( impl_getModelFromFrame( xFrame ) );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ bool bMustBeLayouted( false );
+ bool bNotify( false );
+
+ if ( m_xContainerWindow.is() && !implts_isPreviewModel( xModel ) ) // no UI elements on preview frames
+ {
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+
+ parseResourceURL( aName, aElementType, aElementName );
+
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ) && m_pToolbarManager != NULL )
+ {
+ bNotify = m_pToolbarManager->createToolbar( aName );
+ bMustBeLayouted = m_pToolbarManager->isLayoutDirty();
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" ))
+ {
+ // PB 2004-12-15 #i38743# don't create a menubar if frame isn't top
+ if ( !bInPlaceMenu && !m_xMenuBar.is() && implts_isFrameOrWindowTop( xFrame ))
+ {
+ m_xMenuBar = implts_createElement( aName );
+ if ( m_xMenuBar.is() )
+ {
+ SolarMutexGuard aGuard;
+
+ SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
+ if ( pSysWindow )
+ {
+ Reference< awt::XMenuBar > xMenuBar;
+
+ Reference< XPropertySet > xPropSet( m_xMenuBar, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMenuBar" ))) >>= xMenuBar;
+ }
+ catch ( beans::UnknownPropertyException ) {}
+ catch ( lang::WrappedTargetException ) {}
+ }
+
+ if ( xMenuBar.is() )
+ {
+ VCLXMenu* pAwtMenuBar = VCLXMenu::GetImplementation( xMenuBar );
+ if ( pAwtMenuBar )
+ {
+ MenuBar* pMenuBar = (MenuBar*)pAwtMenuBar->GetMenu();
+ if ( pMenuBar )
+ {
+ pSysWindow->SetMenuBar( pMenuBar );
+ pMenuBar->SetDisplayable( m_bMenuVisible );
+ if ( m_bMenuVisible )
+ bNotify = sal_True;
+ implts_updateMenuBarClose();
+ }
+ }
+ }
+ }
+ }
+ }
+ aWriteLock.unlock();
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && ( implts_isFrameOrWindowTop(xFrame) || implts_isEmbeddedLayoutManager() ))
+ {
+ implts_createStatusBar( aName );
+ bNotify = sal_True;
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ) && implts_isFrameOrWindowTop(xFrame) )
+ {
+ implts_createProgressBar();
+ bNotify = sal_True;
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" ))
+ {
+ // Add layout manager as listener for docking and other window events
+ uno::Reference< uno::XInterface > xThis( static_cast< OWeakObject* >(this), uno::UNO_QUERY );
+ uno::Reference< ui::XUIElement > xUIElement( implts_createDockingWindow( aName ));
+
+ if ( xUIElement.is() )
+ {
+ impl_addWindowListeners( xThis, xUIElement );
+ m_pPanelManager->addDockingWindow( aName, xUIElement );
+ }
+
+ // The docking window is created by a factory method located in the sfx2 library.
+// CreateDockingWindow( xFrame, aElementName );
+ }
+ }
+
+ if ( bMustBeLayouted )
+ implts_doLayout_notify( sal_True );
+
+ if ( bNotify )
+ {
+ // UI element is invisible - provide information to listeners
+ implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::makeAny( aName ) );
+ }
+}
+
+void SAL_CALL LayoutManager::destroyElement( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::destroyElement" );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ bool bMustBeLayouted( sal_False );
+ bool bMustBeDestroyed( sal_False );
+ bool bNotify( sal_False );
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+
+ Reference< XComponent > xComponent;
+ parseResourceURL( aName, aElementType, aElementName );
+
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" ))
+ {
+ if ( !m_bInplaceMenuSet )
+ {
+ impl_clearUpMenuBar();
+ m_xMenuBar.clear();
+ bNotify = true;
+ }
+ }
+ else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) ||
+ ( m_aStatusBarElement.m_aName == aName ))
+ {
+ aWriteLock.unlock();
+ implts_destroyStatusBar();
+ bMustBeLayouted = true;
+ bNotify = true;
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ))
+ {
+ aWriteLock.unlock();
+ implts_createProgressBar();
+ bMustBeLayouted = true;
+ bNotify = sal_True;
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ) && m_pToolbarManager != NULL )
+ {
+ aWriteLock.unlock();
+ bNotify = m_pToolbarManager->destroyToolbar( aName );
+ bMustBeLayouted = m_pToolbarManager->isLayoutDirty();
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" ))
+ {
+ uno::Reference< frame::XFrame > xFrame( m_xFrame );
+ uno::Reference< lang::XMultiServiceFactory > xSMGR( m_xSMGR );
+ aWriteLock.unlock();
+
+ impl_setDockingWindowVisibility( xSMGR, xFrame, aElementName, false );
+ bMustBeLayouted = false;
+ bNotify = false;
+ }
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ if ( bMustBeDestroyed )
+ {
+ if ( xComponent.is() )
+ xComponent->dispose();
+ bNotify = true;
+ }
+
+ if ( bMustBeLayouted )
+ doLayout();
+
+ if ( bNotify )
+ implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_INVISIBLE, uno::makeAny( aName ) );
+}
+
+::sal_Bool SAL_CALL LayoutManager::requestElement( const ::rtl::OUString& rResourceURL )
+throw (uno::RuntimeException)
+{
+ bool bResult( false );
+ bool bNotify( false );
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+
+ parseResourceURL( rResourceURL, aElementType, aElementName );
+
+ WriteGuard aWriteLock( m_aLock );
+
+ ::rtl::OString aResName = rtl::OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US );
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "framework (cd100003) Element %s requested.", aResName.getStr() );
+
+ if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || ( m_aStatusBarElement.m_aName == rResourceURL ))
+ {
+ implts_readStatusBarState( rResourceURL );
+ if ( m_aStatusBarElement.m_bVisible && !m_aStatusBarElement.m_bMasterHide )
+ {
+ aWriteLock.unlock();
+ createElement( rResourceURL );
+
+ // There are some situation where we are not able to create an element.
+ // Therefore we have to check the reference before further action.
+ // See #i70019#
+ uno::Reference< ui::XUIElement > xUIElement( m_aStatusBarElement.m_xUIElement );
+ if ( xUIElement.is() )
+ {
+ // we need VCL here to pass special flags to Show()
+ SolarMutexGuard aGuard;
+ Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY );
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow )
+ {
+ pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ bResult = true;
+ bNotify = true;
+ }
+ }
+ }
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ) )
+ {
+ aWriteLock.unlock();
+ implts_showProgressBar();
+ bResult = true;
+ bNotify = true;
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ) && m_bVisible )
+ {
+ bool bComponentAttached( m_aModuleIdentifier.getLength() > 0 );
+ uno::Reference< uno::XInterface > xThis( m_xToolbarManager, uno::UNO_QUERY );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aWriteLock.unlock();
+
+ if ( pToolbarManager && bComponentAttached )
+ {
+ bNotify = pToolbarManager->requestToolbar( rResourceURL );
+ }
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" ))
+ {
+ uno::Reference< frame::XFrame > xFrame( m_xFrame );
+ aWriteLock.unlock();
+
+ CreateDockingWindow( xFrame, aElementName );
+ }
+
+ if ( bNotify )
+ implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::makeAny( rResourceURL ) );
+
+ return bResult;
+}
+
+Reference< XUIElement > SAL_CALL LayoutManager::getElement( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ Reference< XUIElement > xUIElement = implts_findElement( aName );
+ if ( !xUIElement.is() )
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager( m_pToolbarManager );
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ xUIElement = pToolbarManager->getToolbar( aName );
+ }
+
+ return xUIElement;
+}
+
+Sequence< Reference< ui::XUIElement > > SAL_CALL LayoutManager::getElements()
+throw (uno::RuntimeException)
+{
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< ui::XUIElement > xMenuBar( m_xMenuBar );
+ uno::Reference< ui::XUIElement > xStatusBar( m_aStatusBarElement.m_xUIElement );
+ uno::Reference< uno::XInterface > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager( m_pToolbarManager );
+ aReadLock.unlock();
+
+ Sequence< Reference< ui::XUIElement > > aSeq;
+ if ( pToolbarManager )
+ aSeq = pToolbarManager->getToolbars();
+
+ sal_Int32 nSize = aSeq.getLength();
+ sal_Int32 nMenuBarIndex(-1);
+ sal_Int32 nStatusBarIndex(-1);
+ if ( xMenuBar.is() )
+ {
+ nMenuBarIndex = nSize;
+ ++nSize;
+ }
+ if ( xStatusBar.is() )
+ {
+ nStatusBarIndex = nSize;
+ ++nSize;
+ }
+
+ aSeq.realloc(nSize);
+ if ( nMenuBarIndex >= 0 )
+ aSeq[nMenuBarIndex] = xMenuBar;
+ if ( nStatusBarIndex >= 0 )
+ aSeq[nStatusBarIndex] = xStatusBar;
+
+ return aSeq;
+}
+
+sal_Bool SAL_CALL LayoutManager::showElement( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::showElement" );
+
+ bool bResult( false );
+ bool bNotify( false );
+ bool bMustLayout( false );
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+
+ parseResourceURL( aName, aElementType, aElementName );
+
+ ::rtl::OString aResName = rtl::OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US );
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "framework (cd100003) Element %s", aResName.getStr() );
+
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" ))
+ {
+ WriteGuard aWriteLock( m_aLock );
+ m_bMenuVisible = sal_True;
+ aWriteLock.unlock();
+
+ bResult = implts_resetMenuBar();
+ bNotify = bResult;
+ }
+ else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || ( m_aStatusBarElement.m_aName == aName ))
+ {
+ WriteGuard aWriteLock( m_aLock );
+ if ( m_aStatusBarElement.m_xUIElement.is() && !m_aStatusBarElement.m_bMasterHide &&
+ implts_showStatusBar( sal_True ))
+ {
+ aWriteLock.unlock();
+
+ implts_writeWindowStateData( m_aStatusBarAlias, m_aStatusBarElement );
+ bMustLayout = true;
+ bResult = true;
+ bNotify = true;
+ }
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ))
+ {
+ bNotify = bResult = implts_showProgressBar();
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< awt::XWindowListener > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ {
+ bNotify = pToolbarManager->showToolbar( aName );
+ bMustLayout = pToolbarManager->isLayoutDirty();
+ }
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" ))
+ {
+ ReadGuard aReadGuard( m_aLock );
+ uno::Reference< frame::XFrame > xFrame( m_xFrame );
+ uno::Reference< lang::XMultiServiceFactory > xSMGR( m_xSMGR );
+ aReadGuard.unlock();
+
+ impl_setDockingWindowVisibility( xSMGR, xFrame, aElementName, true );
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolpanel" ))
+ {
+ ReadGuard aReadGuard( m_aLock );
+ uno::Reference< frame::XFrame > xFrame( m_xFrame );
+ aReadGuard.unlock();
+ ActivateToolPanel( m_xFrame, aName );
+ }
+
+ if ( bMustLayout )
+ doLayout();
+
+ if ( bNotify )
+ implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::makeAny( aName ) );
+
+ return bResult;
+}
+
+sal_Bool SAL_CALL LayoutManager::hideElement( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::hideElement" );
+
+ bool bNotify( false );
+ bool bMustLayout( false );
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+
+ parseResourceURL( aName, aElementType, aElementName );
+ ::rtl::OString aResName = rtl::OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US );
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "framework (cd100003) Element %s", aResName.getStr() );
+
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" ))
+ {
+ WriteGuard aWriteLock( m_aLock );
+
+ if ( m_xContainerWindow.is() )
+ {
+ m_bMenuVisible = sal_False;
+
+ SolarMutexGuard aGuard;
+ SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
+ if ( pSysWindow )
+ {
+ MenuBar* pMenuBar = pSysWindow->GetMenuBar();
+ if ( pMenuBar )
+ {
+ pMenuBar->SetDisplayable( sal_False );
+ bNotify = true;
+ }
+ }
+ }
+ }
+ else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || ( m_aStatusBarElement.m_aName == aName ))
+ {
+ WriteGuard aWriteLock( m_aLock );
+ if ( m_aStatusBarElement.m_xUIElement.is() && !m_aStatusBarElement.m_bMasterHide &&
+ implts_hideStatusBar( sal_True ))
+ {
+ implts_writeWindowStateData( m_aStatusBarAlias, m_aStatusBarElement );
+ bMustLayout = sal_True;
+ bNotify = sal_True;
+ }
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ))
+ {
+ bNotify = implts_hideProgressBar();
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ bNotify = pToolbarManager->hideToolbar( aName );
+ bMustLayout = pToolbarManager->isLayoutDirty();
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" ))
+ {
+ ReadGuard aReadGuard( m_aLock );
+ uno::Reference< frame::XFrame > xFrame( m_xFrame );
+ uno::Reference< lang::XMultiServiceFactory > xSMGR( m_xSMGR );
+ aReadGuard.unlock();
+
+ impl_setDockingWindowVisibility( xSMGR, xFrame, aElementName, false );
+ }
+
+ if ( bMustLayout )
+ doLayout();
+
+ if ( bNotify )
+ implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_INVISIBLE, uno::makeAny( aName ) );
+
+ return sal_False;
+}
+
+sal_Bool SAL_CALL LayoutManager::dockWindow( const ::rtl::OUString& aName, DockingArea DockingArea, const awt::Point& Pos )
+throw (RuntimeException)
+{
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+
+ parseResourceURL( aName, aElementType, aElementName );
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ {
+ pToolbarManager->dockToolbar( aName, DockingArea, Pos );
+ if ( pToolbarManager->isLayoutDirty() )
+ doLayout();
+ }
+ }
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL LayoutManager::dockAllWindows( ::sal_Int16 /*nElementType*/ ) throw (uno::RuntimeException)
+{
+ ReadGuard aReadLock( m_aLock );
+ bool bResult( false );
+ uno::Reference< uno::XInterface > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ {
+ bResult = pToolbarManager->dockAllToolbars();
+ if ( pToolbarManager->isLayoutDirty() )
+ doLayout();
+ }
+ return bResult;
+}
+
+sal_Bool SAL_CALL LayoutManager::floatWindow( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ bool bResult( false );
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ {
+ bResult = pToolbarManager->floatToolbar( aName );
+ if ( pToolbarManager->isLayoutDirty() )
+ doLayout();
+ }
+ }
+ return bResult;
+}
+
+::sal_Bool SAL_CALL LayoutManager::lockWindow( const ::rtl::OUString& aName )
+throw (uno::RuntimeException)
+{
+ bool bResult( false );
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ {
+ bResult = pToolbarManager->lockToolbar( aName );
+ if ( pToolbarManager->isLayoutDirty() )
+ doLayout();
+ }
+ }
+ return bResult;
+}
+
+::sal_Bool SAL_CALL LayoutManager::unlockWindow( const ::rtl::OUString& aName )
+throw (uno::RuntimeException)
+{
+ bool bResult( false );
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ {
+ bResult = pToolbarManager->unlockToolbar( aName );
+ if ( pToolbarManager->isLayoutDirty() )
+ doLayout();
+ }
+ }
+ return bResult;
+}
+
+void SAL_CALL LayoutManager::setElementSize( const ::rtl::OUString& aName, const awt::Size& aSize )
+throw (RuntimeException)
+{
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xThis( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ {
+ pToolbarManager->setToolbarSize( aName, aSize );
+ if ( pToolbarManager->isLayoutDirty() )
+ doLayout();
+ }
+ }
+}
+
+void SAL_CALL LayoutManager::setElementPos( const ::rtl::OUString& aName, const awt::Point& aPos )
+throw (RuntimeException)
+{
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager( m_pToolbarManager );
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ {
+ pToolbarManager->setToolbarPos( aName, aPos );
+ if ( pToolbarManager->isLayoutDirty() )
+ doLayout();
+ }
+ }
+}
+
+void SAL_CALL LayoutManager::setElementPosSize( const ::rtl::OUString& aName, const awt::Point& aPos, const awt::Size& aSize )
+throw (RuntimeException)
+{
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager( m_pToolbarManager );
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ {
+ pToolbarManager->setToolbarPosSize( aName, aPos, aSize );
+ if ( pToolbarManager->isLayoutDirty() )
+ doLayout();
+ }
+ }
+}
+
+sal_Bool SAL_CALL LayoutManager::isElementVisible( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+
+ parseResourceURL( aName, aElementType, aElementName );
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ if ( m_xContainerWindow.is() )
+ {
+ aReadLock.unlock();
+
+ SolarMutexGuard aGuard;
+ SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
+ if ( pSysWindow )
+ {
+ MenuBar* pMenuBar = pSysWindow->GetMenuBar();
+ if ( pMenuBar && pMenuBar->IsDisplayable() )
+ return sal_True;
+ }
+ else
+ {
+ aReadLock.lock();
+ return m_bMenuVisible;
+ }
+ }
+ }
+ else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || ( m_aStatusBarElement.m_aName == aName ))
+ {
+ if ( m_aStatusBarElement.m_xUIElement.is() )
+ {
+ Reference< awt::XWindow > xWindow( m_aStatusBarElement.m_xUIElement->getRealInterface(), UNO_QUERY );
+ if ( xWindow.is() )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->IsVisible() )
+ return sal_True;
+ else
+ return sal_False;
+ }
+ }
+ }
+ else if (( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" )))
+ {
+ if ( m_aProgressBarElement.m_xUIElement.is() )
+ return m_aProgressBarElement.m_bVisible;
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< frame::XLayoutManager > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ return pToolbarManager->isToolbarVisible( aName );
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" ))
+ {
+ ReadGuard aReadGuard( m_aLock );
+ uno::Reference< frame::XFrame > xFrame( m_xFrame );
+ aReadGuard.unlock();
+
+ return IsDockingWindowVisible( xFrame, aElementName );
+ }
+
+ return sal_False;
+}
+
+sal_Bool SAL_CALL LayoutManager::isElementFloating( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ return pToolbarManager->isToolbarFloating( aName );
+ }
+
+ return sal_False;
+}
+
+sal_Bool SAL_CALL LayoutManager::isElementDocked( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ return pToolbarManager->isToolbarDocked( aName );
+ }
+
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL LayoutManager::isElementLocked( const ::rtl::OUString& aName )
+throw (uno::RuntimeException)
+{
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ return pToolbarManager->isToolbarLocked( aName );
+ }
+
+ return sal_False;
+}
+
+awt::Size SAL_CALL LayoutManager::getElementSize( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ return pToolbarManager->getToolbarSize( aName );
+ }
+
+ return awt::Size();
+}
+
+awt::Point SAL_CALL LayoutManager::getElementPos( const ::rtl::OUString& aName )
+throw (RuntimeException)
+{
+ if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ return pToolbarManager->getToolbarPos( aName );
+ }
+
+ return awt::Point();
+}
+
+void SAL_CALL LayoutManager::lock()
+throw (RuntimeException)
+{
+ implts_lock();
+
+ ReadGuard aReadLock( m_aLock );
+ sal_Int32 nLockCount( m_nLockCount );
+ aReadLock.unlock();
+
+ RTL_LOGFILE_TRACE1( "framework (cd100003) ::LayoutManager::lock lockCount=%d", nLockCount );
+#ifdef DBG_UTIL
+ ByteString aStr("LayoutManager::lock ");
+ aStr += ByteString::CreateFromInt32((long)this);
+ aStr += " - ";
+ aStr += ByteString::CreateFromInt32(nLockCount);
+ OSL_TRACE( aStr.GetBuffer() );
+#endif
+
+ Any a( nLockCount );
+ implts_notifyListeners( frame::LayoutManagerEvents::LOCK, a );
+}
+
+void SAL_CALL LayoutManager::unlock()
+throw (RuntimeException)
+{
+ sal_Bool bDoLayout( implts_unlock() );
+
+ ReadGuard aReadLock( m_aLock );
+ sal_Int32 nLockCount( m_nLockCount );
+ aReadLock.unlock();
+
+ RTL_LOGFILE_TRACE1( "framework (cd100003) ::LayoutManager::unlock lockCount=%d", nLockCount );
+#ifdef DBG_UTIL
+ ByteString aStr("LayoutManager::unlock ");
+ aStr += ByteString::CreateFromInt32((long)this);
+ aStr += " - ";
+ aStr += ByteString::CreateFromInt32(nLockCount);
+ OSL_TRACE( aStr.GetBuffer() );
+#endif
+ // conform to documentation: unlock with lock count == 0 means force a layout
+
+ WriteGuard aWriteLock( m_aLock );
+ if ( bDoLayout )
+ m_aAsyncLayoutTimer.Stop();
+ aWriteLock.unlock();
+
+ Any a( nLockCount );
+ implts_notifyListeners( frame::LayoutManagerEvents::UNLOCK, a );
+
+ if ( bDoLayout )
+ implts_doLayout_notify( sal_True );
+}
+
+void SAL_CALL LayoutManager::doLayout()
+throw (RuntimeException)
+{
+ implts_doLayout_notify( sal_True );
+}
+
+//---------------------------------------------------------------------------------------------------------
+// ILayoutNotifications
+//---------------------------------------------------------------------------------------------------------
+void LayoutManager::requestLayout( Hint eHint )
+{
+ if ( eHint == HINT_TOOLBARSPACE_HAS_CHANGED )
+ doLayout();
+}
+
+void LayoutManager::implts_doLayout_notify( sal_Bool bOuterResize )
+{
+ bool bLayouted = implts_doLayout( false, bOuterResize );
+ if ( bLayouted )
+ implts_notifyListeners( frame::LayoutManagerEvents::LAYOUT, Any() );
+}
+
+sal_Bool LayoutManager::implts_doLayout( sal_Bool bForceRequestBorderSpace, sal_Bool bOuterResize )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::implts_doLayout" );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ if ( !m_xFrame.is() || !m_bParentWindowVisible )
+ return sal_False;
+
+ bool bPreserveContentSize( m_bPreserveContentSize );
+ bool bMustDoLayout( m_bMustDoLayout );
+ bool bNoLock = ( m_nLockCount == 0 );
+ awt::Rectangle aCurrBorderSpace( m_aDockingArea );
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+ Reference< awt::XTopWindow2 > xContainerTopWindow( m_xContainerTopWindow );
+ Reference< awt::XWindow > xComponentWindow( m_xFrame->getComponentWindow() );
+ Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor );
+ aReadLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ sal_Bool bLayouted( sal_False );
+
+ if ( bNoLock && xDockingAreaAcceptor.is() && xContainerWindow.is() && xComponentWindow.is() )
+ {
+ bLayouted = sal_True;
+
+ WriteGuard aWriteGuard( m_aLock );
+ m_bDoLayout = sal_True;
+ aWriteGuard.unlock();
+
+ awt::Rectangle aDockSpace( implts_calcDockingAreaSizes() );
+ awt::Rectangle aBorderSpace( aDockSpace );
+ sal_Bool bGotRequestedBorderSpace( sal_True );
+
+ // We have to add the height of a possible status bar
+ aBorderSpace.Height += implts_getStatusBarSize().Height();
+
+ if ( !equalRectangles( aBorderSpace, aCurrBorderSpace ) || bForceRequestBorderSpace || bMustDoLayout )
+ {
+ // we always resize the content window (instead of the complete container window) if we're not set up
+ // to (attempt to) preserve the content window's size
+ if ( bOuterResize && !bPreserveContentSize )
+ bOuterResize = sal_False;
+
+ // maximized windows can resized their content window only, not their container window
+ if ( bOuterResize && xContainerTopWindow.is() && xContainerTopWindow->getIsMaximized() )
+ bOuterResize = sal_False;
+
+ // if the component window does not have a size (yet), then we can't use it to calc the container
+ // window size
+ awt::Rectangle aComponentRect = xComponentWindow->getPosSize();
+ if ( bOuterResize && ( aComponentRect.Width == 0 ) && ( aComponentRect.Height == 0 ) )
+ bOuterResize = sal_False;
+
+ bGotRequestedBorderSpace = sal_False;
+ if ( bOuterResize )
+ {
+ Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY );
+ awt::DeviceInfo aContainerInfo = xDevice->getInfo();
+
+ awt::Size aRequestedSize( aComponentRect.Width + aContainerInfo.LeftInset + aContainerInfo.RightInset + aBorderSpace.X + aBorderSpace.Width,
+ aComponentRect.Height + aContainerInfo.TopInset + aContainerInfo.BottomInset + aBorderSpace.Y + aBorderSpace.Height );
+ awt::Point aComponentPos( aBorderSpace.X, aBorderSpace.Y );
+
+ bGotRequestedBorderSpace = implts_resizeContainerWindow( aRequestedSize, aComponentPos );
+ }
+
+ // if we did not do an container window resize, or it failed, then use the DockingAcceptor as usual
+ if ( !bGotRequestedBorderSpace )
+ bGotRequestedBorderSpace = xDockingAreaAcceptor->requestDockingAreaSpace( aBorderSpace );
+
+ if ( bGotRequestedBorderSpace )
+ {
+ aWriteGuard.lock();
+ m_aDockingArea = aBorderSpace;
+ m_bMustDoLayout = sal_False;
+ aWriteGuard.unlock();
+ }
+ }
+
+ if ( bGotRequestedBorderSpace )
+ {
+ ::Size aContainerSize;
+ ::Size aStatusBarSize;
+
+ // Interim solution to let the layout method within the
+ // toolbar layout manager.
+ implts_setOffset( implts_getStatusBarSize().Height() );
+ m_pToolbarManager->setDockingArea( aDockSpace );
+
+ // Subtract status bar size from our container output size. Docking area windows
+ // don't contain the status bar!
+ aStatusBarSize = implts_getStatusBarSize();
+ aContainerSize = implts_getContainerWindowOutputSize();
+ aContainerSize.Height() -= aStatusBarSize.Height();
+
+ m_pToolbarManager->doLayout(aContainerSize);
+
+ // Position the status bar
+ if ( aStatusBarSize.Height() > 0 )
+ {
+ implts_setStatusBarPosSize( ::Point( 0, std::max(( aContainerSize.Height() ), long( 0 ))),
+ ::Size( aContainerSize.Width(),aStatusBarSize.Height() ));
+ }
+
+ xDockingAreaAcceptor->setDockingAreaSpace( aBorderSpace );
+
+ aWriteGuard.lock();
+ m_bDoLayout = sal_False;
+ aWriteGuard.unlock();
+ }
+ }
+
+ return bLayouted;
+}
+
+sal_Bool LayoutManager::implts_resizeContainerWindow( const awt::Size& rContainerSize,
+ const awt::Point& rComponentPos )
+{
+ ReadGuard aReadLock( m_aLock );
+ Reference< awt::XWindow > xContainerWindow = m_xContainerWindow;
+ Reference< awt::XTopWindow2 > xContainerTopWindow = m_xContainerTopWindow;
+ Reference< awt::XWindow > xComponentWindow = m_xFrame->getComponentWindow();
+ Reference< container::XIndexAccess > xDisplayAccess = m_xDisplayAccess;
+ aReadLock.unlock();
+
+ // calculate the maximum size we have for the container window
+ awt::Rectangle aWorkArea;
+ try
+ {
+ sal_Int32 nDisplay = xContainerTopWindow->getDisplay();
+ Reference< beans::XPropertySet > xDisplayInfo( xDisplayAccess->getByIndex( nDisplay ), UNO_QUERY_THROW );
+ OSL_VERIFY( xDisplayInfo->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WorkArea" ) ) ) >>= aWorkArea );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ if (( aWorkArea.Width > 0 ) && ( aWorkArea.Height > 0 ))
+ {
+ if (( rContainerSize.Width > aWorkArea.Width ) || ( rContainerSize.Height > aWorkArea.Height ))
+ return sal_False;
+ // Strictly, this is not correct. If we have a multi-screen display (css.awt.DisplayAccess.MultiDisplay == true),
+ // the the "effective work area" would be much larger than the work area of a single display, since we could in theory
+ // position the container window across multiple screens.
+ // However, this should suffice as a heuristics here ... (nobody really wants to check whether the different screens are
+ // stacked horizontally or vertically, whether their work areas can really be combined, or are separated by non-work-areas,
+ // and the like ... right?)
+ }
+
+ // resize our container window
+ xContainerWindow->setPosSize( 0, 0, rContainerSize.Width, rContainerSize.Height, awt::PosSize::SIZE );
+ // position the component window
+ xComponentWindow->setPosSize( rComponentPos.X, rComponentPos.Y, 0, 0, awt::PosSize::POS );
+ return sal_True;
+}
+
+void SAL_CALL LayoutManager::setVisible( sal_Bool bVisible )
+throw (uno::RuntimeException)
+{
+ WriteGuard aWriteLock( m_aLock );
+ sal_Bool bWasVisible( m_bVisible );
+ m_bVisible = bVisible;
+ aWriteLock.unlock();
+
+ if ( bWasVisible != bVisible )
+ implts_setVisibleState( bVisible );
+}
+
+sal_Bool SAL_CALL LayoutManager::isVisible()
+throw (uno::RuntimeException)
+{
+ ReadGuard aReadLock( m_aLock );
+ return m_bVisible;
+}
+
+::Size LayoutManager::implts_getStatusBarSize()
+{
+ ReadGuard aReadLock( m_aLock );
+ bool bStatusBarVisible( isElementVisible( m_aStatusBarAlias ));
+ bool bProgressBarVisible( isElementVisible( m_aProgressBarAlias ));
+ bool bVisible( m_bVisible );
+ Reference< XUIElement > xStatusBar( m_aStatusBarElement.m_xUIElement );
+ Reference< XUIElement > xProgressBar( m_aProgressBarElement.m_xUIElement );
+
+ Reference< awt::XWindow > xWindow;
+ if ( bStatusBarVisible && bVisible && xStatusBar.is() )
+ xWindow = Reference< awt::XWindow >( xStatusBar->getRealInterface(), UNO_QUERY );
+ else if ( xProgressBar.is() && !xStatusBar.is() && bProgressBarVisible )
+ {
+ ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)xProgressBar.get();
+ if ( pWrapper )
+ xWindow = pWrapper->getStatusBar();
+ }
+ aReadLock.unlock();
+
+ if ( xWindow.is() )
+ {
+ awt::Rectangle aPosSize = xWindow->getPosSize();
+ return ::Size( aPosSize.Width, aPosSize.Height );
+ }
+ else
+ return ::Size();
+}
+
+awt::Rectangle LayoutManager::implts_calcDockingAreaSizes()
+{
+ ReadGuard aReadLock( m_aLock );
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+ Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor );
+ aReadLock.unlock();
+
+ awt::Rectangle aBorderSpace;
+ if ( xDockingAreaAcceptor.is() && xContainerWindow.is() )
+ aBorderSpace = m_pToolbarManager->getDockingArea();
+
+ return aBorderSpace;
+}
+
+void LayoutManager::implts_setDockingAreaWindowSizes( const awt::Rectangle& /*rBorderSpace*/ )
+{
+ ReadGuard aReadLock( m_aLock );
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+ aReadLock.unlock();
+
+ uno::Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY );
+ // Convert relativ size to output size.
+ awt::Rectangle aRectangle = xContainerWindow->getPosSize();
+ awt::DeviceInfo aInfo = xDevice->getInfo();
+ awt::Size aContainerClientSize = awt::Size( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset,
+ aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
+ ::Size aStatusBarSize = implts_getStatusBarSize();
+
+ // Position the status bar
+ if ( aStatusBarSize.Height() > 0 )
+ {
+ implts_setStatusBarPosSize( ::Point( 0, std::max(( aContainerClientSize.Height - aStatusBarSize.Height() ), long( 0 ))),
+ ::Size( aContainerClientSize.Width, aStatusBarSize.Height() ));
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XMenuCloser
+//---------------------------------------------------------------------------------------------------------
+void LayoutManager::implts_updateMenuBarClose()
+{
+ WriteGuard aWriteLock( m_aLock );
+ bool bShowCloser( m_bMenuBarCloser );
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+ aWriteLock.unlock();
+
+ if ( xContainerWindow.is() )
+ {
+ SolarMutexGuard aGuard;
+
+ SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
+ if ( pSysWindow )
+ {
+ MenuBar* pMenuBar = pSysWindow->GetMenuBar();
+ if ( pMenuBar )
+ {
+ // TODO remove link on sal_False ?!
+ pMenuBar->ShowCloser( bShowCloser );
+ pMenuBar->SetCloserHdl( LINK( this, LayoutManager, MenuBarClose ));
+ }
+ }
+ }
+}
+
+sal_Bool LayoutManager::implts_resetMenuBar()
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ sal_Bool bMenuVisible( m_bMenuVisible );
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+
+ MenuBar* pSetMenuBar = 0;
+ if ( m_xInplaceMenuBar.is() )
+ pSetMenuBar = (MenuBar *)m_pInplaceMenuBar->GetMenuBar();
+ else
+ {
+ MenuBarWrapper* pMenuBarWrapper = static_cast< MenuBarWrapper* >( m_xMenuBar.get() );
+ if ( pMenuBarWrapper )
+ pSetMenuBar = (MenuBar *)pMenuBarWrapper->GetMenuBarManager()->GetMenuBar();
+ }
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ SolarMutexGuard aGuard;
+ SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
+ if ( pSysWindow && bMenuVisible && pSetMenuBar )
+ {
+ pSysWindow->SetMenuBar( pSetMenuBar );
+ pSetMenuBar->SetDisplayable( sal_True );
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void LayoutManager::implts_setMenuBarCloser(sal_Bool bCloserState)
+{
+ WriteGuard aWriteLock( m_aLock );
+ m_bMenuBarCloser = bCloserState;
+ aWriteLock.unlock();
+
+ implts_updateMenuBarClose();
+}
+
+IMPL_LINK( LayoutManager, MenuBarClose, MenuBar *, EMPTYARG )
+{
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< frame::XDispatchProvider > xProvider(m_xFrame, uno::UNO_QUERY);
+ uno::Reference< lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+
+ if ( !xProvider.is())
+ return 0;
+
+ uno::Reference< frame::XDispatchHelper > xDispatcher(
+ xSMGR->createInstance(SERVICENAME_DISPATCHHELPER), uno::UNO_QUERY_THROW);
+
+ xDispatcher->executeDispatch(
+ xProvider,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self")),
+ 0,
+ uno::Sequence< beans::PropertyValue >());
+
+ return 0;
+}
+
+IMPL_LINK( LayoutManager, SettingsChanged, void*, EMPTYARG )
+{
+ return 1;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XLayoutManagerEventBroadcaster
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL LayoutManager::addLayoutManagerEventListener( const uno::Reference< frame::XLayoutManagerListener >& xListener )
+throw (uno::RuntimeException)
+{
+ m_aListenerContainer.addInterface( ::getCppuType( (const uno::Reference< frame::XLayoutManagerListener >*)NULL ), xListener );
+}
+
+void SAL_CALL LayoutManager::removeLayoutManagerEventListener( const uno::Reference< frame::XLayoutManagerListener >& xListener )
+throw (uno::RuntimeException)
+{
+ m_aListenerContainer.removeInterface( ::getCppuType( (const uno::Reference< frame::XLayoutManagerListener >*)NULL ), xListener );
+}
+
+void LayoutManager::implts_notifyListeners( short nEvent, uno::Any aInfoParam )
+{
+ lang::EventObject aSource( static_cast< ::cppu::OWeakObject*>(this) );
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const uno::Reference< frame::XLayoutManagerListener >*) NULL ) );
+ if (pContainer!=NULL)
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ ((frame::XLayoutManagerListener*)pIterator.next())->layoutEvent( aSource, nEvent, aInfoParam );
+ }
+ catch( uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XWindowListener
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL LayoutManager::windowResized( const awt::WindowEvent& aEvent )
+throw( uno::RuntimeException )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ if ( !m_xDockingAreaAcceptor.is() )
+ return;
+
+ // Request to set docking area space again.
+ awt::Rectangle aDockingArea( m_aDockingArea );
+ Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor );
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+
+ Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY );
+ if ( xIfac == aEvent.Source && m_bVisible )
+ {
+ // We have to call our resize handler at least once synchronously, as some
+ // application modules need this. So we have to check if this is the first
+ // call after the async layout time expired.
+ m_bMustDoLayout = sal_True;
+ if ( !m_aAsyncLayoutTimer.IsActive() )
+ {
+ const Link& aLink = m_aAsyncLayoutTimer.GetTimeoutHdl();
+ if ( aLink.IsSet() )
+ aLink.Call( &m_aAsyncLayoutTimer );
+ }
+ if ( m_nLockCount == 0 )
+ m_aAsyncLayoutTimer.Start();
+ }
+ else if ( m_xFrame.is() && aEvent.Source == m_xFrame->getContainerWindow() )
+ {
+ // the container window of my DockingAreaAcceptor is not the same as of my frame
+ // I still have to resize my frames' window as nobody else will do it
+ Reference< awt::XWindow > xComponentWindow( m_xFrame->getComponentWindow() );
+ if( xComponentWindow.is() == sal_True )
+ {
+ uno::Reference< awt::XDevice > xDevice( m_xFrame->getContainerWindow(), uno::UNO_QUERY );
+
+ // Convert relativ size to output size.
+ awt::Rectangle aRectangle = m_xFrame->getContainerWindow()->getPosSize();
+ awt::DeviceInfo aInfo = xDevice->getInfo();
+ awt::Size aSize( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
+ aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
+
+ // Resize our component window.
+ xComponentWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, awt::PosSize::POSSIZE );
+ }
+ }
+}
+
+void SAL_CALL LayoutManager::windowMoved( const awt::WindowEvent& ) throw( uno::RuntimeException )
+{
+}
+
+void SAL_CALL LayoutManager::windowShown( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
+{
+ ReadGuard aReadLock( m_aLock );
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+ bool bParentWindowVisible( m_bParentWindowVisible );
+ aReadLock.unlock();
+
+ Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY );
+ if ( xIfac == aEvent.Source )
+ {
+ bool bSetVisible = false;
+
+ WriteGuard aWriteLock( m_aLock );
+ m_bParentWindowVisible = true;
+ bSetVisible = ( m_bParentWindowVisible != bParentWindowVisible );
+ aWriteLock.unlock();
+
+ if ( bSetVisible )
+ implts_updateUIElementsVisibleState( sal_True );
+ }
+}
+
+void SAL_CALL LayoutManager::windowHidden( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
+{
+ ReadGuard aReadLock( m_aLock );
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+ bool bParentWindowVisible( m_bParentWindowVisible );
+ aReadLock.unlock();
+
+ Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY );
+ if ( xIfac == aEvent.Source )
+ {
+ bool bSetInvisible = false;
+
+ WriteGuard aWriteLock( m_aLock );
+ m_bParentWindowVisible = false;
+ bSetInvisible = ( m_bParentWindowVisible != bParentWindowVisible );
+ aWriteLock.unlock();
+
+ if ( bSetInvisible )
+ implts_updateUIElementsVisibleState( sal_False );
+ }
+}
+
+IMPL_LINK( LayoutManager, AsyncLayoutHdl, Timer *, EMPTYARG )
+{
+ ReadGuard aReadLock( m_aLock );
+ m_aAsyncLayoutTimer.Stop();
+
+ if( !m_xContainerWindow.is() )
+ return 0;
+
+ awt::Rectangle aDockingArea( m_aDockingArea );
+ ::Size aStatusBarSize( implts_getStatusBarSize() );
+
+ // Subtract status bar height
+ aDockingArea.Height -= aStatusBarSize.Height();
+ aReadLock.unlock();
+
+ implts_setDockingAreaWindowSizes( aDockingArea );
+ implts_doLayout( sal_True, sal_False );
+
+ return 0;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XFrameActionListener
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL LayoutManager::frameAction( const FrameActionEvent& aEvent )
+throw ( RuntimeException )
+{
+ if (( aEvent.Action == FrameAction_COMPONENT_ATTACHED ) || ( aEvent.Action == FrameAction_COMPONENT_REATTACHED ))
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::frameAction (COMPONENT_ATTACHED|REATTACHED)" );
+
+ WriteGuard aWriteLock( m_aLock );
+ m_bComponentAttached = sal_True;
+ m_bMustDoLayout = sal_True;
+ aWriteLock.unlock();
+
+ implts_reset( sal_True );
+ implts_doLayout( sal_True, sal_False );
+ implts_doLayout( sal_True, sal_True );
+ }
+ else if (( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED ) || ( aEvent.Action == FrameAction_FRAME_UI_DEACTIVATING ))
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::frameAction (FRAME_UI_ACTIVATED|DEACTIVATING)" );
+
+ WriteGuard aWriteLock( m_aLock );
+ m_bActive = ( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED );
+ aWriteLock.unlock();
+
+ implts_toggleFloatingUIElementsVisibility( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED );
+ }
+ else if ( aEvent.Action == FrameAction_COMPONENT_DETACHING )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::frameAction (COMPONENT_DETACHING)" );
+
+ WriteGuard aWriteLock( m_aLock );
+ m_bComponentAttached = sal_False;
+ aWriteLock.unlock();
+
+ implts_reset( sal_False );
+ }
+}
+
+// ______________________________________________
+
+void SAL_CALL LayoutManager::disposing( const lang::EventObject& rEvent )
+throw( RuntimeException )
+{
+ sal_Bool bDisposeAndClear( sal_False );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ if ( rEvent.Source == Reference< XInterface >( m_xFrame, UNO_QUERY ))
+ {
+ // Our frame gets disposed, release all our references that depends on a working frame reference.
+ Application::RemoveEventListener( LINK( this, LayoutManager, SettingsChanged ) );
+
+ // destroy all elements, it's possible that dettaching is NOT called!
+ implts_destroyElements();
+ impl_clearUpMenuBar();
+ m_xMenuBar.clear();
+ if ( m_xInplaceMenuBar.is() )
+ {
+ m_pInplaceMenuBar = 0;
+ m_xInplaceMenuBar->dispose();
+ }
+ m_xInplaceMenuBar.clear();
+ m_xContainerWindow.clear();
+ m_xContainerTopWindow.clear();
+
+ // forward disposing call to toolbar manager
+ if ( m_pToolbarManager != NULL )
+ m_pToolbarManager->disposing(rEvent);
+
+ if ( m_xModuleCfgMgr.is() )
+ {
+ try
+ {
+ Reference< XUIConfiguration > xModuleCfgMgr( m_xModuleCfgMgr, UNO_QUERY );
+ xModuleCfgMgr->removeConfigurationListener(
+ Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& ) {}
+ }
+
+ if ( m_xDocCfgMgr.is() )
+ {
+ try
+ {
+ Reference< XUIConfiguration > xDocCfgMgr( m_xDocCfgMgr, UNO_QUERY );
+ xDocCfgMgr->removeConfigurationListener(
+ Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& ) {}
+ }
+
+ m_xDocCfgMgr.clear();
+ m_xModuleCfgMgr.clear();
+ m_xFrame.clear();
+ delete m_pGlobalSettings;
+ m_pGlobalSettings = 0;
+ m_xDockingAreaAcceptor = Reference< ui::XDockingAreaAcceptor >();
+
+ bDisposeAndClear = sal_True;
+ }
+ else if ( rEvent.Source == Reference< XInterface >( m_xContainerWindow, UNO_QUERY ))
+ {
+ // Our container window gets disposed. Remove all user interface elements.
+ uno::Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ if ( pToolbarManager )
+ {
+ uno::Reference< awt::XWindowPeer > aEmptyWindowPeer;
+ pToolbarManager->setParentWindow( aEmptyWindowPeer );
+ }
+ impl_clearUpMenuBar();
+ m_xMenuBar.clear();
+ if ( m_xInplaceMenuBar.is() )
+ {
+ m_pInplaceMenuBar = 0;
+ m_xInplaceMenuBar->dispose();
+ }
+ m_xInplaceMenuBar.clear();
+ m_xContainerWindow.clear();
+ m_xContainerTopWindow.clear();
+ }
+ else if ( rEvent.Source == Reference< XInterface >( m_xDocCfgMgr, UNO_QUERY ))
+ m_xDocCfgMgr.clear();
+ else if ( rEvent.Source == Reference< XInterface >( m_xModuleCfgMgr , UNO_QUERY ))
+ m_xModuleCfgMgr.clear();
+
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ // Send disposing to our listener when we have lost our frame.
+ if ( bDisposeAndClear )
+ {
+ // Send message to all listener and forget her references.
+ uno::Reference< frame::XLayoutManager > xThis( static_cast< ::cppu::OWeakObject* >(this), uno::UNO_QUERY );
+ lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+ }
+}
+
+void SAL_CALL LayoutManager::elementInserted( const ui::ConfigurationEvent& Event ) throw (uno::RuntimeException)
+{
+ ReadGuard aReadLock( m_aLock );
+ Reference< XFrame > xFrame( m_xFrame );
+ Reference< ui::XUIConfigurationListener > xUICfgListener( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( xFrame.is() )
+ {
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+ bool bRefreshLayout(false);
+
+ parseResourceURL( Event.ResourceURL, aElementType, aElementName );
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ if ( xUICfgListener.is() )
+ {
+ xUICfgListener->elementInserted( Event );
+ bRefreshLayout = pToolbarManager->isLayoutDirty();
+ }
+ }
+ else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_MENUBAR ))
+ {
+ Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL );
+ Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY );
+ if ( xElementSettings.is() )
+ {
+ ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
+ uno::Reference< XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ if ( Event.Source == uno::Reference< uno::XInterface >( m_xDocCfgMgr, uno::UNO_QUERY ))
+ xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( m_xDocCfgMgr ));
+ }
+ xElementSettings->updateSettings();
+ }
+ }
+
+ if ( bRefreshLayout )
+ doLayout();
+ }
+}
+
+void SAL_CALL LayoutManager::elementRemoved( const ui::ConfigurationEvent& Event ) throw (uno::RuntimeException)
+{
+ ReadGuard aReadLock( m_aLock );
+ Reference< frame::XFrame > xFrame( m_xFrame );
+ Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager );
+ Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
+ Reference< ui::XUIElement > xMenuBar( m_xMenuBar );
+ Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr );
+ Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( xFrame.is() )
+ {
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+ bool bRefreshLayout(false);
+
+ parseResourceURL( Event.ResourceURL, aElementType, aElementName );
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ if ( xToolbarManager.is() )
+ {
+ xToolbarManager->elementRemoved( Event );
+ bRefreshLayout = pToolbarManager->isLayoutDirty();
+ }
+ }
+ else
+ {
+ Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL );
+ Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY );
+ if ( xElementSettings.is() )
+ {
+ bool bNoSettings( false );
+ ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
+ Reference< XInterface > xElementCfgMgr;
+ Reference< XPropertySet > xPropSet( xElementSettings, UNO_QUERY );
+
+ if ( xPropSet.is() )
+ xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr;
+
+ if ( !xElementCfgMgr.is() )
+ return;
+
+ // Check if the same UI configuration manager has changed => check further
+ if ( Event.Source == xElementCfgMgr )
+ {
+ // Same UI configuration manager where our element has its settings
+ if ( Event.Source == Reference< XInterface >( xDocCfgMgr, UNO_QUERY ))
+ {
+ // document settings removed
+ if ( xModuleCfgMgr->hasSettings( Event.ResourceURL ))
+ {
+ xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( m_xModuleCfgMgr ));
+ xElementSettings->updateSettings();
+ return;
+ }
+ }
+
+ bNoSettings = true;
+ }
+
+ // No settings anymore, element must be destroyed
+ if ( xContainerWindow.is() && bNoSettings )
+ {
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" ))
+ {
+ SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
+ if ( pSysWindow && !m_bInplaceMenuSet )
+ pSysWindow->SetMenuBar( 0 );
+
+ Reference< XComponent > xComp( xMenuBar, UNO_QUERY );
+ if ( xComp.is() )
+ xComp->dispose();
+
+ WriteGuard aWriteLock( m_aLock );
+ m_xMenuBar.clear();
+ }
+ }
+ }
+ }
+
+ if ( bRefreshLayout )
+ doLayout();
+ }
+}
+
+void SAL_CALL LayoutManager::elementReplaced( const ui::ConfigurationEvent& Event ) throw (uno::RuntimeException)
+{
+ ReadGuard aReadLock( m_aLock );
+ Reference< XFrame > xFrame( m_xFrame );
+ Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ aReadLock.unlock();
+
+ if ( xFrame.is() )
+ {
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+ bool bRefreshLayout(false);
+
+ parseResourceURL( Event.ResourceURL, aElementType, aElementName );
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ))
+ {
+ if ( xToolbarManager.is() )
+ {
+ xToolbarManager->elementReplaced( Event );
+ bRefreshLayout = pToolbarManager->isLayoutDirty();
+ }
+ }
+ else
+ {
+ Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL );
+ Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY );
+ if ( xElementSettings.is() )
+ {
+ ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
+ Reference< XInterface > xElementCfgMgr;
+ Reference< XPropertySet > xPropSet( xElementSettings, UNO_QUERY );
+
+ if ( xPropSet.is() )
+ xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr;
+
+ if ( !xElementCfgMgr.is() )
+ return;
+
+ // Check if the same UI configuration manager has changed => update settings
+ if ( Event.Source == xElementCfgMgr )
+ xElementSettings->updateSettings();
+ }
+ }
+
+ if ( bRefreshLayout )
+ doLayout();
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------
+// OPropertySetHelper
+//---------------------------------------------------------------------------------------------------------
+sal_Bool SAL_CALL LayoutManager::convertFastPropertyValue( Any& aConvertedValue,
+ Any& aOldValue,
+ sal_Int32 nHandle,
+ const Any& aValue ) throw( lang::IllegalArgumentException )
+{
+ return LayoutManager_PBase::convertFastPropertyValue( aConvertedValue, aOldValue, nHandle, aValue );
+}
+
+void SAL_CALL LayoutManager::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,
+ const uno::Any& aValue ) throw( uno::Exception )
+{
+ if ( nHandle != LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY )
+ LayoutManager_PBase::setFastPropertyValue_NoBroadcast( nHandle, aValue );
+
+ switch( nHandle )
+ {
+ case LAYOUTMANAGER_PROPHANDLE_MENUBARCLOSER:
+ implts_updateMenuBarClose();
+ break;
+
+ case LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY:
+ {
+ sal_Bool bValue(sal_False);
+ if (( aValue >>= bValue ) && bValue )
+ {
+ ReadGuard aReadLock( m_aLock );
+ Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager );
+ ToolbarLayoutManager* pToolbarManager = m_pToolbarManager;
+ bool bAutomaticToolbars( m_bAutomaticToolbars );
+ aReadLock.unlock();
+
+ if ( pToolbarManager )
+ pToolbarManager->refreshToolbarsVisibility( bAutomaticToolbars );
+ }
+ break;
+ }
+
+ case LAYOUTMANAGER_PROPHANDLE_HIDECURRENTUI:
+ implts_setCurrentUIVisibility( !m_bHideCurrentUI );
+ break;
+ default: break;
+ }
+}
+
+void SAL_CALL LayoutManager::getFastPropertyValue( uno::Any& aValue, sal_Int32 nHandle ) const
+{
+ LayoutManager_PBase::getFastPropertyValue( aValue, nHandle );
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL LayoutManager::getInfoHelper()
+{
+ static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ if( pInfoHelper == NULL )
+ {
+ uno::Sequence< beans::Property > aProperties;
+ describeProperties( aProperties );
+ static ::cppu::OPropertyArrayHelper aInfoHelper( aProperties, sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return(*pInfoHelper);
+}
+
+uno::Reference< beans::XPropertySetInfo > SAL_CALL LayoutManager::getPropertySetInfo() throw (uno::RuntimeException)
+{
+ static uno::Reference< beans::XPropertySetInfo >* pInfo = NULL;
+
+ if( pInfo == NULL )
+ {
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ if( pInfo == NULL )
+ {
+ static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/layoutmanager/panel.cxx b/framework/source/layoutmanager/panel.cxx
new file mode 100644
index 000000000000..f980df8164d8
--- /dev/null
+++ b/framework/source/layoutmanager/panel.cxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutmanager.hxx,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "panel.hxx"
+#include "helpers.hxx"
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+#include <toolkit/unohlp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star;
+
+namespace framework
+{
+
+Panel::Panel(
+ const uno::Reference< lang::XMultiServiceFactory >& rSMGR,
+ const uno::Reference< awt::XWindow >& rParent,
+ PanelPosition nPanel ) :
+ m_xSMGR(rSMGR), m_nPanelPosition(nPanel)
+{
+ uno::Reference< awt::XWindowPeer > xWindowPeer( rParent, uno::UNO_QUERY );
+ m_xPanelWindow = uno::Reference< awt::XWindow >( createToolkitWindow( rSMGR, xWindowPeer, "splitwindow" ), uno::UNO_QUERY );
+
+ SolarMutexGuard aGuard;
+ SplitWindow* pSplitWindow = dynamic_cast< SplitWindow* >( VCLUnoHelper::GetWindow( m_xPanelWindow ));
+
+ if ( pSplitWindow )
+ {
+ // Set alignment
+ if (nPanel == PANEL_TOP)
+ pSplitWindow->SetAlign( WINDOWALIGN_TOP );
+ else if (nPanel == PANEL_BOTTOM)
+ pSplitWindow->SetAlign( WINDOWALIGN_BOTTOM );
+ else if (nPanel == PANEL_LEFT)
+ pSplitWindow->SetAlign( WINDOWALIGN_LEFT );
+ else
+ pSplitWindow->SetAlign( WINDOWALIGN_RIGHT );
+ }
+}
+
+Panel::~Panel()
+{
+}
+
+} // namespace framework
diff --git a/framework/source/layoutmanager/panel.hxx b/framework/source/layoutmanager/panel.hxx
new file mode 100644
index 000000000000..1401374f123d
--- /dev/null
+++ b/framework/source/layoutmanager/panel.hxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutmanager.hxx,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_LAYOUTMANAGER_PANEL_HXX_
+#define __FRAMEWORK_LAYOUTMANAGER_PANEL_HXX_
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <macros/generic.hxx>
+#include <stdtypes.h>
+#include <properties.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/window.hxx>
+#include <vcl/splitwin.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+
+enum PanelPosition
+{
+ PANEL_TOP,
+ PANEL_LEFT,
+ PANEL_RIGHT,
+ PANEL_BOTTOM,
+ PANEL_COUNT
+};
+
+class Panel
+{
+ public:
+ Panel( const css::uno::Reference< css::lang::XMultiServiceFactory >& rSMGR,
+ const css::uno::Reference< css::awt::XWindow >& rParent,
+ PanelPosition nPanel );
+ virtual ~Panel();
+
+ private:
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+ css::uno::Reference< css::awt::XWindow > m_xPanelWindow;
+ PanelPosition m_nPanelPosition;
+};
+
+}
+
+#endif // __FRAMEWORK_LAYOUTMANAGER_PANEL_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/layoutmanager/panelmanager.cxx b/framework/source/layoutmanager/panelmanager.cxx
new file mode 100644
index 000000000000..7ec2fd0f9f9a
--- /dev/null
+++ b/framework/source/layoutmanager/panelmanager.cxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutmanager.hxx,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "panelmanager.hxx"
+#include "services.h"
+#include "services/modelwinservice.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+#include <toolkit/unohlp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star;
+
+namespace framework
+{
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+
+PanelManager::PanelManager(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSMGR,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame ) :
+ m_xSMGR( rSMGR ),
+ m_xFrame( rFrame )
+{
+ m_aPanels[PANEL_TOP] = 0;
+ m_aPanels[PANEL_BOTTOM] = 0;
+ m_aPanels[PANEL_LEFT] = 0;
+ m_aPanels[PANEL_RIGHT] = 0;
+}
+
+PanelManager::~PanelManager()
+{
+}
+
+//---------------------------------------------------------------------------------------------------------
+// Creation and layouting
+//---------------------------------------------------------------------------------------------------------
+bool PanelManager::createPanels()
+{
+ if ( m_xFrame.is() )
+ {
+ SolarMutexGuard aGuard;
+ uno::Reference< awt::XWindow > xWindow( m_xFrame->getContainerWindow(), uno::UNO_QUERY );
+ if ( xWindow.is() )
+ {
+ // destroy old panel windows
+ delete m_aPanels[PANEL_TOP ];
+ delete m_aPanels[PANEL_BOTTOM];
+ delete m_aPanels[PANEL_LEFT ];
+ delete m_aPanels[PANEL_RIGHT ];
+
+ m_aPanels[PANEL_TOP ] = new Panel( m_xSMGR, xWindow, PANEL_TOP );
+ m_aPanels[PANEL_BOTTOM] = new Panel( m_xSMGR, xWindow, PANEL_BOTTOM );
+ m_aPanels[PANEL_LEFT ] = new Panel( m_xSMGR, xWindow, PANEL_LEFT );
+ m_aPanels[PANEL_RIGHT ] = new Panel( m_xSMGR, xWindow, PANEL_RIGHT );
+ return true;
+ }
+ }
+
+ return false;
+}
+
+awt::Rectangle PanelManager::getPreferredSize() const
+{
+ return awt::Rectangle();
+}
+
+void PanelManager::layoutPanels( const awt::Rectangle /*newSize*/ )
+{
+}
+
+//---------------------------------------------------------------------------------------------------------
+// Panel functions
+//---------------------------------------------------------------------------------------------------------
+UIElement* PanelManager::findDockingWindow( const ::rtl::OUString& /*rResourceName*/ )
+{
+ return NULL;
+}
+
+bool PanelManager::addDockingWindow( const ::rtl::OUString& /*rResourceName*/, const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& /*xUIElement*/ )
+{
+ return false;
+}
+
+bool PanelManager::destroyDockingWindow( const ::rtl::OUString& /*rResourceName*/ )
+{
+ return false;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XDockableWindowListener
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL PanelManager::startDocking( const awt::DockingEvent& )
+throw (uno::RuntimeException)
+{
+}
+
+awt::DockingData SAL_CALL PanelManager::docking( const awt::DockingEvent& )
+throw (uno::RuntimeException)
+{
+ return awt::DockingData();
+}
+
+void SAL_CALL PanelManager::endDocking( const awt::EndDockingEvent& )
+throw (uno::RuntimeException)
+{
+}
+
+sal_Bool SAL_CALL PanelManager::prepareToggleFloatingMode( const lang::EventObject& )
+throw (uno::RuntimeException)
+{
+ return false;
+}
+
+void SAL_CALL PanelManager::toggleFloatingMode( const lang::EventObject& )
+throw (uno::RuntimeException)
+{
+}
+
+void SAL_CALL PanelManager::closed( const lang::EventObject& )
+throw (uno::RuntimeException)
+{
+}
+
+void SAL_CALL PanelManager::endPopupMode( const awt::EndPopupModeEvent& )
+throw (uno::RuntimeException)
+{
+}
+
+} // namespace framework
diff --git a/framework/source/layoutmanager/panelmanager.hxx b/framework/source/layoutmanager/panelmanager.hxx
new file mode 100644
index 000000000000..fd3e892414fa
--- /dev/null
+++ b/framework/source/layoutmanager/panelmanager.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutmanager.hxx,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_LAYOUTMANAGER_PANELMANAGER_HXX_
+#define __FRAMEWORK_LAYOUTMANAGER_PANELMANAGER_HXX_
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <threadhelp/threadhelpbase.hxx>
+#include <macros/generic.hxx>
+#include <macros/debug.hxx>
+#include <macros/xinterface.hxx>
+#include <macros/xtypeprovider.hxx>
+#include <macros/xserviceinfo.hxx>
+#include <general.h>
+#include <stdtypes.h>
+#include "panel.hxx"
+#include <uielement/uielement.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/awt/XDockableWindowListener.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <cppuhelper/weak.hxx>
+#include <vcl/window.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+
+class PanelManager : private ThreadHelpBase // Struct for right initalization of mutex member! Must be first of baseclasses.
+{
+ public:
+ PanelManager(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSMGR,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame );
+ virtual ~PanelManager();
+
+ bool createPanels();
+ ::com::sun::star::awt::Rectangle getPreferredSize() const;
+ void layoutPanels( const ::com::sun::star::awt::Rectangle newSize );
+
+ UIElement* findDockingWindow( const ::rtl::OUString& rResourceName );
+ bool addDockingWindow( const ::rtl::OUString& rResourceName, const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& xUIElement );
+ bool destroyDockingWindow( const ::rtl::OUString& rResourceName );
+
+ //---------------------------------------------------------------------------------------------------------
+ // XDockableWindowListener
+ //---------------------------------------------------------------------------------------------------------
+ virtual void SAL_CALL startDocking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::DockingData SAL_CALL docking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endDocking( const ::com::sun::star::awt::EndDockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL prepareToggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL toggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endPopupMode( const ::com::sun::star::awt::EndPopupModeEvent& e ) throw (::com::sun::star::uno::RuntimeException);
+
+ private:
+ Panel* m_aPanels[PANEL_COUNT];
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_LAYOUTMANAGER_PANELMANAGER_HXX_
diff --git a/framework/source/layoutmanager/toolbarlayoutmanager.cxx b/framework/source/layoutmanager/toolbarlayoutmanager.cxx
new file mode 100644
index 000000000000..cde360d18436
--- /dev/null
+++ b/framework/source/layoutmanager/toolbarlayoutmanager.cxx
@@ -0,0 +1,4303 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutmanager.cxx,v $
+ * $Revision: 1.72 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+// my own includes
+#include <toolbarlayoutmanager.hxx>
+#include <helpers.hxx>
+#include <services.h>
+#include <classes/resource.hrc>
+#include <classes/fwkresid.hxx>
+#include <uiconfiguration/windowstateconfiguration.hxx>
+
+// interface includes
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/ui/XUIElementSettings.hpp>
+#include <com/sun/star/ui/XUIFunctionListener.hpp>
+
+// other includes
+#include <unotools/cmdoptions.hxx>
+#include <toolkit/unohlp.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <vcl/dockingarea.hxx>
+#include <boost/bind.hpp>
+
+using namespace ::com::sun::star;
+
+namespace framework
+{
+
+ToolbarLayoutManager::ToolbarLayoutManager(
+ const uno::Reference< lang::XMultiServiceFactory >& xSMGR,
+ const uno::Reference< ui::XUIElementFactory >& xUIElementFactory,
+ ILayoutNotifications* pParentLayouter )
+ : ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_xSMGR( xSMGR ),
+ m_xUIElementFactoryManager( xUIElementFactory ),
+ m_pParentLayouter( pParentLayouter ),
+ m_eDockOperation( DOCKOP_ON_COLROW ),
+ m_pAddonOptions( 0 ),
+ m_pGlobalSettings( 0 ),
+ m_bComponentAttached( false ),
+ m_bMustLayout( false ),
+ m_bLayoutDirty( false ),
+ m_bStoreWindowState( false ),
+ m_bGlobalSettings( false ),
+ m_bDockingInProgress( false ),
+ m_bVisible( true ),
+ m_bLayoutInProgress( false ),
+ m_bToolbarCreation( false ),
+ m_aFullAddonTbxPrefix( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" )),
+ m_aCustomTbxPrefix( RTL_CONSTASCII_USTRINGPARAM( "custom_" )),
+ m_aCustomizeCmd( RTL_CONSTASCII_USTRINGPARAM( "ConfigureDialog" )),
+ m_aToolbarTypeString( RTL_CONSTASCII_USTRINGPARAM( UIRESOURCETYPE_TOOLBAR ))
+{
+ // initialize rectangles to zero values
+ setZeroRectangle( m_aDockingAreaOffsets );
+ setZeroRectangle( m_aDockingArea );
+
+ // create toolkit object
+ m_xToolkit = uno::Reference< awt::XToolkit >( m_xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), uno::UNO_QUERY );
+}
+
+ToolbarLayoutManager::~ToolbarLayoutManager()
+{
+ delete m_pGlobalSettings;
+ delete m_pAddonOptions;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XInterface
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL ToolbarLayoutManager::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL ToolbarLayoutManager::release() throw()
+{
+ OWeakObject::release();
+}
+
+uno::Any SAL_CALL ToolbarLayoutManager::queryInterface( const uno::Type & rType ) throw( uno::RuntimeException )
+{
+ uno::Any a = ::cppu::queryInterface( rType,
+ SAL_STATIC_CAST( awt::XDockableWindowListener*, this ),
+ SAL_STATIC_CAST( ui::XUIConfigurationListener*, this ),
+ SAL_STATIC_CAST( awt::XWindowListener*, this ));
+
+ if ( a.hasValue() )
+ return a;
+
+ return OWeakObject::queryInterface( rType );
+}
+
+void SAL_CALL ToolbarLayoutManager::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
+{
+ if ( aEvent.Source == m_xFrame )
+ {
+ // Reset all internal references
+ reset();
+ implts_destroyDockingAreaWindows();
+ }
+}
+
+awt::Rectangle ToolbarLayoutManager::getDockingArea()
+{
+ WriteGuard aWriteLock( m_aLock );
+ Rectangle aNewDockingArea( m_aDockingArea );
+ aWriteLock.unlock();
+
+ if ( isLayoutDirty() )
+ aNewDockingArea = implts_calcDockingArea();
+
+ aWriteLock.lock();
+ m_aDockingArea = aNewDockingArea;
+ aWriteLock.unlock();
+
+ return putRectangleValueToAWT(aNewDockingArea);
+}
+
+void ToolbarLayoutManager::setDockingArea( const awt::Rectangle& rDockingArea )
+{
+ WriteGuard aWriteLock( m_aLock );
+ m_aDockingArea = putAWTToRectangle( rDockingArea );
+ m_bLayoutDirty = true;
+ aWriteLock.unlock();
+}
+
+void ToolbarLayoutManager::implts_setDockingAreaWindowSizes( const awt::Rectangle& rBorderSpace )
+{
+ ReadGuard aReadLock( m_aLock );
+ Rectangle aDockOffsets = m_aDockingAreaOffsets;
+ uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
+ uno::Reference< awt::XWindow > xTopDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
+ uno::Reference< awt::XWindow > xBottomDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
+ uno::Reference< awt::XWindow > xLeftDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
+ uno::Reference< awt::XWindow > xRightDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
+ aReadLock.unlock();
+
+ uno::Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY );
+
+ // Convert relativ size to output size.
+ awt::Rectangle aRectangle = xContainerWindow->getPosSize();
+ awt::DeviceInfo aInfo = xDevice->getInfo();
+ awt::Size aContainerClientSize = awt::Size( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
+ aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
+ long aStatusBarHeight = aDockOffsets.GetHeight();
+
+ sal_Int32 nLeftRightDockingAreaHeight( aContainerClientSize.Height );
+ if ( rBorderSpace.Y >= 0 )
+ {
+ // Top docking area window
+ xTopDockAreaWindow->setPosSize( 0, 0, aContainerClientSize.Width, rBorderSpace.Y, awt::PosSize::POSSIZE );
+ xTopDockAreaWindow->setVisible( sal_True );
+ nLeftRightDockingAreaHeight -= rBorderSpace.Y;
+ }
+
+ if ( rBorderSpace.Height >= 0 )
+ {
+ // Bottom docking area window
+ sal_Int32 nBottomPos = std::max( sal_Int32( aContainerClientSize.Height - rBorderSpace.Height - aStatusBarHeight ), sal_Int32( 0 ));
+ sal_Int32 nHeight = ( nBottomPos == 0 ) ? 0 : rBorderSpace.Height;
+
+ xBottomDockAreaWindow->setPosSize( 0, nBottomPos, aContainerClientSize.Width, nHeight, awt::PosSize::POSSIZE );
+ xBottomDockAreaWindow->setVisible( sal_True );
+ nLeftRightDockingAreaHeight -= nHeight;
+ }
+
+ nLeftRightDockingAreaHeight -= aStatusBarHeight;
+ if ( rBorderSpace.X >= 0 || nLeftRightDockingAreaHeight > 0 )
+ {
+ // Left docking area window
+ // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority!
+ sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight ));
+
+ xLeftDockAreaWindow->setPosSize( 0, rBorderSpace.Y, rBorderSpace.X, nHeight, awt::PosSize::POSSIZE );
+ xLeftDockAreaWindow->setVisible( sal_True );
+ }
+ if ( rBorderSpace.Width >= 0 || nLeftRightDockingAreaHeight > 0 )
+ {
+ // Right docking area window
+ // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority!
+ sal_Int32 nLeftPos = std::max( sal_Int32( 0 ), sal_Int32( aContainerClientSize.Width - rBorderSpace.Width ));
+ sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight ));
+ sal_Int32 nWidth = ( nLeftPos == 0 ) ? 0 : rBorderSpace.Width;
+
+ xRightDockAreaWindow->setPosSize( nLeftPos, rBorderSpace.Y, nWidth, nHeight, awt::PosSize::POSSIZE );
+ xRightDockAreaWindow->setVisible( sal_True );
+ }
+}
+
+bool ToolbarLayoutManager::isLayoutDirty()
+{
+ return m_bLayoutDirty;
+}
+
+void ToolbarLayoutManager::doLayout(const ::Size& aContainerSize)
+{
+ WriteGuard aWriteLock( m_aLock );
+ bool bLayoutInProgress( m_bLayoutInProgress );
+ m_bLayoutInProgress = true;
+ awt::Rectangle aDockingArea = putRectangleValueToAWT( m_aDockingArea );
+ aWriteLock.unlock();
+
+ if ( bLayoutInProgress )
+ return;
+
+ // Retrieve row/column dependent data from all docked user-interface elements
+ for ( sal_Int32 i = 0; i < DOCKINGAREAS_COUNT; i++ )
+ {
+ bool bReverse( isReverseOrderDockingArea( i ));
+ std::vector< SingleRowColumnWindowData > aRowColumnsWindowData;
+
+ implts_getDockingAreaElementInfos( (ui::DockingArea)i, aRowColumnsWindowData );
+
+ sal_Int32 nOffset( 0 );
+ const sal_uInt32 nCount = aRowColumnsWindowData.size();
+ for ( sal_uInt32 j = 0; j < nCount; ++j )
+ {
+ sal_uInt32 nIndex = bReverse ? nCount-j-1 : j;
+ implts_calcWindowPosSizeOnSingleRowColumn( i, nOffset, aRowColumnsWindowData[nIndex], aContainerSize );
+ nOffset += aRowColumnsWindowData[j].nStaticSize;
+ }
+ }
+
+ implts_setDockingAreaWindowSizes( aDockingArea );
+
+ aWriteLock.lock();
+ m_bLayoutDirty = false;
+ m_bLayoutInProgress = false;
+ aWriteLock.unlock();
+}
+
+bool ToolbarLayoutManager::implts_isParentWindowVisible() const
+{
+ ReadGuard aReadLock( m_aLock );
+ bool bVisible( false );
+ if ( m_xContainerWindow.is() )
+ bVisible = m_xContainerWindow->isVisible();
+
+ return bVisible;
+}
+
+Rectangle ToolbarLayoutManager::implts_calcDockingArea()
+{
+ ReadGuard aReadLock( m_aLock );
+ UIElementVector aWindowVector( m_aUIElements );
+ aReadLock.unlock();
+
+ Rectangle aBorderSpace;
+ sal_Int32 nCurrRowColumn( 0 );
+ sal_Int32 nCurrPos( 0 );
+ sal_Int32 nCurrDockingArea( ui::DockingArea_DOCKINGAREA_TOP );
+ std::vector< sal_Int32 > aRowColumnSizes[DOCKINGAREAS_COUNT];
+ UIElementVector::const_iterator pConstIter;
+
+ // initialize rectangle with zero values!
+ aBorderSpace.setWidth(0);
+ aBorderSpace.setHeight(0);
+
+ aRowColumnSizes[nCurrDockingArea].clear();
+ aRowColumnSizes[nCurrDockingArea].push_back( 0 );
+
+ for ( pConstIter = aWindowVector.begin(); pConstIter != aWindowVector.end(); pConstIter++ )
+ {
+ uno::Reference< ui::XUIElement > xUIElement( pConstIter->m_xUIElement, uno::UNO_QUERY );
+ if ( xUIElement.is() )
+ {
+ uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+ if ( xWindow.is() && xDockWindow.is() )
+ {
+ SolarMutexGuard aGuard;
+
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && !xDockWindow->isFloating() && pConstIter->m_bVisible )
+ {
+ awt::Rectangle aPosSize = xWindow->getPosSize();
+ if ( pConstIter->m_aDockedData.m_nDockedArea != nCurrDockingArea )
+ {
+ nCurrDockingArea = pConstIter->m_aDockedData.m_nDockedArea;
+ nCurrRowColumn = 0;
+ nCurrPos = 0;
+ aRowColumnSizes[nCurrDockingArea].clear();
+ aRowColumnSizes[nCurrDockingArea].push_back( 0 );
+ }
+
+ if ( pConstIter->m_aDockedData.m_nDockedArea == nCurrDockingArea )
+ {
+ if ( isHorizontalDockingArea( pConstIter->m_aDockedData.m_nDockedArea ))
+ {
+ if ( pConstIter->m_aDockedData.m_aPos.Y() > nCurrPos )
+ {
+ ++nCurrRowColumn;
+ nCurrPos = pConstIter->m_aDockedData.m_aPos.Y();
+ aRowColumnSizes[nCurrDockingArea].push_back( 0 );
+ }
+
+ if ( aPosSize.Height > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] )
+ aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Height;
+ }
+ else
+ {
+ if ( pConstIter->m_aDockedData.m_aPos.X() > nCurrPos )
+ {
+ ++nCurrRowColumn;
+ nCurrPos = pConstIter->m_aDockedData.m_aPos.X();
+ aRowColumnSizes[nCurrDockingArea].push_back( 0 );
+ }
+
+ if ( aPosSize.Width > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] )
+ aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Width;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Sum up max heights from every row/column
+ if ( !aWindowVector.empty() )
+ {
+ for ( sal_Int32 i = 0; i <= ui::DockingArea_DOCKINGAREA_RIGHT; i++ )
+ {
+ sal_Int32 nSize( 0 );
+ const sal_uInt32 nCount = aRowColumnSizes[i].size();
+ for ( sal_uInt32 j = 0; j < nCount; j++ )
+ nSize += aRowColumnSizes[i][j];
+
+ if ( i == ui::DockingArea_DOCKINGAREA_TOP )
+ aBorderSpace.Top() = nSize;
+ else if ( i == ui::DockingArea_DOCKINGAREA_BOTTOM )
+ aBorderSpace.Bottom() = nSize;
+ else if ( i == ui::DockingArea_DOCKINGAREA_LEFT )
+ aBorderSpace.Left() = nSize;
+ else
+ aBorderSpace.Right() = nSize;
+ }
+ }
+
+ return aBorderSpace;
+}
+
+void ToolbarLayoutManager::reset()
+{
+ WriteGuard aWriteLock( m_aLock );
+ uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr );
+ uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr );
+ m_xModuleCfgMgr.clear();
+ m_xDocCfgMgr.clear();
+ m_bComponentAttached = false;
+ aWriteLock.unlock();
+
+ destroyToolbars();
+ resetDockingArea();
+}
+
+void ToolbarLayoutManager::attach(
+ const uno::Reference< frame::XFrame >& xFrame,
+ const uno::Reference< ui::XUIConfigurationManager >& xModuleCfgMgr,
+ const uno::Reference< ui::XUIConfigurationManager >& xDocCfgMgr,
+ const uno::Reference< container::XNameAccess >& xPersistentWindowState )
+{
+ // reset toolbar manager if we lose our current frame
+ if ( m_xFrame.is() && m_xFrame != xFrame )
+ reset();
+
+ WriteGuard aWriteLock( m_aLock );
+ m_xFrame = xFrame;
+ m_xModuleCfgMgr = xModuleCfgMgr;
+ m_xDocCfgMgr = xDocCfgMgr;
+ m_xPersistentWindowState = xPersistentWindowState;
+ m_bComponentAttached = true;
+}
+
+void ToolbarLayoutManager::createStaticToolbars()
+{
+ resetDockingArea();
+ implts_createCustomToolBars();
+ implts_createAddonsToolBars();
+ implts_createNonContextSensitiveToolBars();
+ implts_sortUIElements();
+}
+
+bool ToolbarLayoutManager::requestToolbar( const ::rtl::OUString& rResourceURL )
+{
+ bool bNotify( false );
+ bool bMustCallCreate( false );
+ uno::Reference< ui::XUIElement > xUIElement;
+
+ UIElement aRequestedToolbar = impl_findToolbar( rResourceURL );
+ if ( aRequestedToolbar.m_aName != rResourceURL )
+ {
+ bMustCallCreate = true;
+ aRequestedToolbar.m_aName = rResourceURL;
+ aRequestedToolbar.m_aType = m_aToolbarTypeString;
+ aRequestedToolbar.m_xUIElement = xUIElement;
+ implts_readWindowStateData( rResourceURL, aRequestedToolbar );
+ }
+
+ xUIElement = aRequestedToolbar.m_xUIElement;
+ if ( !xUIElement.is() )
+ bMustCallCreate = true;
+
+ bool bCreateOrShowToolbar( aRequestedToolbar.m_bVisible & !aRequestedToolbar.m_bMasterHide );
+ uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow, uno::UNO_QUERY );
+ if ( xContainerWindow.is() && aRequestedToolbar.m_bFloating )
+ bCreateOrShowToolbar &= bool( xContainerWindow->isActive());
+
+ if ( bCreateOrShowToolbar )
+ bNotify = ( bMustCallCreate ) ? createToolbar( rResourceURL ) : showToolbar( rResourceURL );
+
+ return bNotify;
+}
+
+bool ToolbarLayoutManager::createToolbar( const ::rtl::OUString& rResourceURL )
+{
+ bool bNotify( false );
+ uno::Reference< ui::XUIElement > xUITempElement;
+
+ implts_createToolBar( rResourceURL, bNotify, xUITempElement );
+ return bNotify;
+}
+
+bool ToolbarLayoutManager::destroyToolbar( const ::rtl::OUString& rResourceURL )
+{
+ const rtl::OUString aAddonTbResourceName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" ));
+
+ UIElementVector::iterator pIter;
+ uno::Reference< lang::XComponent > xComponent;
+
+ bool bNotify( false );
+ bool bMustBeSorted( false );
+ bool bMustLayouted( false );
+ bool bMustBeDestroyed( rResourceURL.indexOf( aAddonTbResourceName ) != 0 );
+
+ WriteGuard aWriteLock( m_aLock );
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ if ( pIter->m_aName == rResourceURL )
+ {
+ xComponent.set( pIter->m_xUIElement, uno::UNO_QUERY );
+ if ( bMustBeDestroyed )
+ pIter->m_xUIElement.clear();
+ else
+ pIter->m_bVisible = false;
+ break;
+ }
+ }
+ aWriteLock.unlock();
+
+ uno::Reference< ui::XUIElement > xUIElement( xComponent, uno::UNO_QUERY );
+ if ( xUIElement.is() )
+ {
+ uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+
+ if ( bMustBeDestroyed )
+ {
+ try
+ {
+ if ( xWindow.is() )
+ xWindow->removeWindowListener( uno::Reference< awt::XWindowListener >(
+ static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
+ }
+ catch( uno::Exception& ) {}
+
+ try
+ {
+ if ( xDockWindow.is() )
+ xDockWindow->removeDockableWindowListener( uno::Reference< awt::XDockableWindowListener >(
+ static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
+ }
+ catch ( uno::Exception& ) {}
+ }
+ else
+ {
+ if ( xWindow.is() )
+ xWindow->setVisible( sal_False );
+ bNotify = true;
+ }
+
+ if ( !xDockWindow->isFloating() )
+ bMustLayouted = true;
+ bMustBeSorted = true;
+ }
+
+ if ( bMustBeDestroyed )
+ {
+ if ( xComponent.is() )
+ xComponent->dispose();
+ bNotify = true;
+ }
+
+ if ( bMustLayouted )
+ implts_setLayoutDirty();
+
+ if ( bMustBeSorted )
+ implts_sortUIElements();
+
+ return bNotify;
+}
+
+void ToolbarLayoutManager::destroyToolbars()
+{
+ UIElementVector aUIElementVector;
+ implts_getUIElementVectorCopy( aUIElementVector );
+
+ WriteGuard aWriteLock( m_aLock );
+ m_aUIElements.clear();
+ m_bLayoutDirty = true;
+ aWriteLock.unlock();
+
+ UIElementVector::iterator pIter;
+ for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ )
+ {
+ uno::Reference< lang::XComponent > xComponent( pIter->m_xUIElement, uno::UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+ }
+}
+
+bool ToolbarLayoutManager::showToolbar( const ::rtl::OUString& rResourceURL )
+{
+ UIElement aUIElement = implts_findToolbar( rResourceURL );
+
+ SolarMutexGuard aGuard;
+ Window* pWindow = getWindowFromXUIElement( aUIElement.m_xUIElement );
+ if ( pWindow )
+ {
+ if ( !aUIElement.m_bFloating )
+ implts_setLayoutDirty();
+ else
+ pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+
+ aUIElement.m_bVisible = true;
+ implts_writeWindowStateData( aUIElement );
+ implts_setToolbar( aUIElement );
+ return true;
+ }
+
+ return false;
+}
+
+bool ToolbarLayoutManager::hideToolbar( const ::rtl::OUString& rResourceURL )
+{
+ UIElement aUIElement = implts_findToolbar( rResourceURL );
+
+ SolarMutexGuard aGuard;
+ Window* pWindow = getWindowFromXUIElement( aUIElement.m_xUIElement );
+ if ( pWindow )
+ {
+ pWindow->Show( sal_False );
+ if ( !aUIElement.m_bFloating )
+ implts_setLayoutDirty();
+
+ aUIElement.m_bVisible = false;
+ implts_writeWindowStateData( aUIElement );
+ implts_setToolbar( aUIElement );
+ return true;
+ }
+
+ return false;
+}
+
+void ToolbarLayoutManager::refreshToolbarsVisibility( bool bAutomaticToolbars )
+{
+ UIElementVector aUIElementVector;
+
+ ReadGuard aReadLock( m_aLock );
+ bool bVisible( m_bVisible );
+ aReadLock.unlock();
+
+ if ( !bVisible || !bAutomaticToolbars )
+ return;
+
+ implts_getUIElementVectorCopy( aUIElementVector );
+
+ UIElement aUIElement;
+ SolarMutexGuard aGuard;
+ UIElementVector::iterator pIter;
+ for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ )
+ {
+ if ( implts_readWindowStateData( pIter->m_aName, aUIElement ) &&
+ ( pIter->m_bVisible != aUIElement.m_bVisible ) && !pIter->m_bMasterHide )
+ {
+ WriteGuard aWriteLock( m_aLock );
+ UIElement& rUIElement = impl_findToolbar( pIter->m_aName );
+ if ( rUIElement.m_aName == pIter->m_aName )
+ {
+ rUIElement.m_bVisible = aUIElement.m_bVisible;
+ implts_setLayoutDirty();
+ }
+ }
+ }
+}
+
+void ToolbarLayoutManager::setFloatingToolbarsVisibility( bool bVisible )
+{
+ UIElementVector aUIElementVector;
+ implts_getUIElementVectorCopy( aUIElementVector );
+
+ SolarMutexGuard aGuard;
+ UIElementVector::iterator pIter;
+ for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ )
+ {
+ Window* pWindow = getWindowFromXUIElement( pIter->m_xUIElement );
+ if ( pWindow && pIter->m_bFloating )
+ {
+ if ( bVisible )
+ {
+ if ( pIter->m_bVisible && !pIter->m_bMasterHide )
+ pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ }
+ else
+ pWindow->Show( sal_False );
+ }
+ }
+}
+
+void ToolbarLayoutManager::setVisible( bool bVisible )
+{
+ UIElementVector aUIElementVector;
+ implts_getUIElementVectorCopy( aUIElementVector );
+
+ SolarMutexGuard aGuard;
+ UIElementVector::iterator pIter;
+ for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ )
+ {
+ pIter->m_bMasterHide = !bVisible;
+ Window* pWindow = getWindowFromXUIElement( pIter->m_xUIElement );
+ if ( pWindow )
+ {
+ bool bSetVisible( pIter->m_bVisible & bVisible );
+ if ( !bSetVisible )
+ pWindow->Hide();
+ else
+ {
+ if ( pIter->m_bFloating )
+ pWindow->Show(true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ else
+ implts_setLayoutDirty();
+ }
+ }
+ }
+
+ if ( !bVisible )
+ resetDockingArea();
+}
+
+bool ToolbarLayoutManager::dockToolbar( const ::rtl::OUString& rResourceURL, ui::DockingArea eDockingArea, const awt::Point& aPos )
+{
+ UIElement aUIElement = implts_findToolbar( rResourceURL );
+
+ if ( aUIElement.m_xUIElement.is() )
+ {
+ try
+ {
+ uno::Reference< awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+ if ( xDockWindow.is() )
+ {
+ if ( eDockingArea != ui::DockingArea_DOCKINGAREA_DEFAULT )
+ aUIElement.m_aDockedData.m_nDockedArea = sal_Int16( eDockingArea );
+
+ if ( !isDefaultPos( aPos ))
+ aUIElement.m_aDockedData.m_aPos = ::Point( aPos.X, aPos.Y );
+
+ if ( !xDockWindow->isFloating() )
+ {
+ Window* pWindow( 0 );
+ ToolBox* pToolBox( 0 );
+
+ {
+ SolarMutexGuard aGuard;
+ pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
+ {
+ pToolBox = (ToolBox *)pWindow;
+
+ // We have to set the alignment of the toolbox. It's possible that the toolbox is moved from a
+ // horizontal to a vertical docking area!
+ pToolBox->SetAlign( ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ));
+ }
+ }
+
+ if ( hasDefaultPosValue( aUIElement.m_aDockedData.m_aPos ))
+ {
+ // Docking on its default position without a preset position -
+ // we have to find a good place for it.
+ ::Size aSize;
+
+ SolarMutexGuard aGuard;
+ {
+ if ( pToolBox )
+ aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ) );
+ else
+ aSize = pWindow->GetSizePixel();
+ }
+
+ ::Point aPixelPos;
+ ::Point aDockPos;
+ implts_findNextDockingPos((ui::DockingArea)aUIElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos );
+ aUIElement.m_aDockedData.m_aPos = aDockPos;
+ }
+ }
+
+ implts_setToolbar( aUIElement );
+
+ if ( xDockWindow->isFloating() )
+ {
+ // ATTENTION: This will call toggleFloatingMode() via notifications which
+ // sets the floating member of the UIElement correctly!
+ xDockWindow->setFloatingMode( sal_False );
+ }
+ else
+ {
+ implts_writeWindowStateData( aUIElement );
+ implts_sortUIElements();
+
+ if ( aUIElement.m_bVisible )
+ implts_setLayoutDirty();
+ }
+ return true;
+ }
+ }
+ catch ( lang::DisposedException& ) {}
+ }
+
+ return false;
+}
+
+bool ToolbarLayoutManager::dockAllToolbars()
+{
+ std::vector< ::rtl::OUString > aToolBarNameVector;
+
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+
+ ReadGuard aReadLock( m_aLock );
+ UIElementVector::iterator pIter;
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ if ( pIter->m_aType.equalsAscii( "toolbar" ) && pIter->m_xUIElement.is() &&
+ pIter->m_bFloating && pIter->m_bVisible )
+ aToolBarNameVector.push_back( pIter->m_aName );
+ }
+ aReadLock.unlock();
+
+ bool bResult(true);
+ const sal_uInt32 nCount = aToolBarNameVector.size();
+ for ( sal_uInt32 i = 0; i < nCount; ++i )
+ {
+ awt::Point aPoint;
+ aPoint.X = aPoint.Y = SAL_MAX_INT32;
+ bResult &= dockToolbar( aToolBarNameVector[i], ui::DockingArea_DOCKINGAREA_DEFAULT, aPoint );
+ }
+
+ return bResult;
+}
+
+long ToolbarLayoutManager::childWindowEvent( VclSimpleEvent* pEvent )
+{
+ // To enable toolbar controllers to change their image when a sub-toolbar function
+ // is activated, we need this mechanism. We have NO connection between these toolbars
+ // anymore!
+ if ( pEvent && pEvent->ISA( VclWindowEvent ))
+ {
+ if ( pEvent->GetId() == VCLEVENT_TOOLBOX_SELECT )
+ {
+ ::rtl::OUString aToolbarName;
+ ::rtl::OUString aCommand;
+ ToolBox* pToolBox = getToolboxPtr( ((VclWindowEvent*)pEvent)->GetWindow() );
+
+ if ( pToolBox )
+ {
+ aToolbarName = retrieveToolbarNameFromHelpURL( pToolBox );
+ sal_uInt16 nId = pToolBox->GetCurItemId();
+ if ( nId > 0 )
+ aCommand = pToolBox->GetItemCommand( nId );
+ }
+
+ if (( aToolbarName.getLength() > 0 ) && ( aCommand.getLength() > 0 ))
+ {
+ ReadGuard aReadLock( m_aLock );
+ ::std::vector< uno::Reference< ui::XUIFunctionListener > > aListenerArray;
+ UIElementVector::iterator pIter;
+
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ if ( pIter->m_xUIElement.is() )
+ {
+ uno::Reference< ui::XUIFunctionListener > xListener( pIter->m_xUIElement, uno::UNO_QUERY );
+ if ( xListener.is() )
+ aListenerArray.push_back( xListener );
+ }
+ }
+ aReadLock.unlock();
+
+ const sal_uInt32 nCount = aListenerArray.size();
+ for ( sal_uInt32 i = 0; i < nCount; ++i )
+ {
+ try { aListenerArray[i]->functionExecute( aToolbarName, aCommand ); }
+ catch ( uno::RuntimeException& ) { throw; }
+ catch ( uno::Exception& ) {}
+ }
+ }
+ }
+ else if ( pEvent->GetId() == VCLEVENT_TOOLBOX_FORMATCHANGED )
+ {
+ if ( !implts_isToolbarCreationActive() )
+ {
+ ToolBox* pToolBox = getToolboxPtr( ((VclWindowEvent*)pEvent)->GetWindow() );
+ if ( pToolBox )
+ {
+ ::rtl::OUString aToolbarName = retrieveToolbarNameFromHelpURL( pToolBox );
+ if ( aToolbarName.getLength() > 0 )
+ {
+ ::rtl::OUStringBuffer aBuf(100);
+ aBuf.appendAscii( "private:resource/toolbar/" );
+ aBuf.append( aToolbarName );
+
+ UIElement aToolbar = implts_findToolbar( aBuf.makeStringAndClear() );
+ if ( aToolbar.m_xUIElement.is() && !aToolbar.m_bFloating )
+ {
+ implts_setLayoutDirty();
+ m_pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+void ToolbarLayoutManager::resetDockingArea()
+{
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
+ uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
+ uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
+ uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
+ aReadLock.unlock();
+
+ if ( xTopDockingWindow.is() )
+ xTopDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
+ if ( xLeftDockingWindow.is() )
+ xLeftDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
+ if ( xRightDockingWindow.is() )
+ xRightDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
+ if ( xBottomDockingWindow.is() )
+ xBottomDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
+}
+
+void ToolbarLayoutManager::setParentWindow(
+ const uno::Reference< awt::XWindowPeer >& xParentWindow )
+{
+ static const char DOCKINGAREASTRING[] = "dockingarea";
+
+ uno::Reference< awt::XWindow > xTopDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xSMGR, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
+ uno::Reference< awt::XWindow > xLeftDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xSMGR, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
+ uno::Reference< awt::XWindow > xRightDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xSMGR, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
+ uno::Reference< awt::XWindow > xBottomDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xSMGR, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
+
+ WriteGuard aWriteLock( m_aLock );
+ m_xContainerWindow = uno::Reference< awt::XWindow2 >( xParentWindow, uno::UNO_QUERY );
+ m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] = xTopDockWindow;
+ m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] = xLeftDockWindow;
+ m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] = xRightDockWindow;
+ m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] = xBottomDockWindow;
+ aWriteLock.unlock();
+
+ if ( xParentWindow.is() )
+ {
+ SolarMutexGuard aGuard;
+ ::DockingAreaWindow* pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xTopDockWindow ) );
+ if( pWindow ) pWindow->SetAlign( WINDOWALIGN_TOP );
+ pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xBottomDockWindow ) );
+ if( pWindow ) pWindow->SetAlign( WINDOWALIGN_BOTTOM );
+ pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xLeftDockWindow ) );
+ if( pWindow ) pWindow->SetAlign( WINDOWALIGN_LEFT );
+ pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xRightDockWindow ) );
+ if( pWindow ) pWindow->SetAlign( WINDOWALIGN_RIGHT );
+ implts_reparentToolbars();
+ }
+ else
+ {
+ destroyToolbars();
+ resetDockingArea();
+ }
+}
+
+void ToolbarLayoutManager::setDockingAreaOffsets( const ::Rectangle aOffsets )
+{
+ WriteGuard aWriteLock( m_aLock );
+ m_aDockingAreaOffsets = aOffsets;
+ m_bLayoutDirty = true;
+}
+
+rtl::OUString ToolbarLayoutManager::implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber ) const
+{
+ String aAddonGenericTitle;
+
+ aAddonGenericTitle = String( FwkResId( STR_TOOLBAR_TITLE_ADDON ));
+ const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
+
+ String aNumStr = rI18nHelper.GetNum( nNumber, 0, sal_False, sal_False );
+ aAddonGenericTitle.SearchAndReplaceAscii( "%num%", aNumStr );
+
+ return rtl::OUString( aAddonGenericTitle );
+}
+
+void ToolbarLayoutManager::implts_createAddonsToolBars()
+{
+ WriteGuard aWriteLock( m_aLock );
+ if ( !m_pAddonOptions )
+ m_pAddonOptions = new AddonsOptions;
+
+ uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
+ uno::Reference< frame::XFrame > xFrame( m_xFrame );
+ aWriteLock.unlock();
+
+ uno::Reference< frame::XModel > xModel( impl_getModelFromFrame( xFrame ));
+ if ( implts_isPreviewModel( xModel ))
+ return; // no addon toolbars for preview frame!
+
+ UIElementVector aUIElementVector;
+ uno::Sequence< uno::Sequence< beans::PropertyValue > > aAddonToolBarData;
+ uno::Reference< ui::XUIElement > xUIElement;
+
+ sal_uInt32 nCount = m_pAddonOptions->GetAddonsToolBarCount();
+ ::rtl::OUString aAddonsToolBarStaticName( m_aFullAddonTbxPrefix );
+ ::rtl::OUString aElementType( RTL_CONSTASCII_USTRINGPARAM( "toolbar" ));
+
+ uno::Sequence< beans::PropertyValue > aPropSeq( 2 );
+ aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropSeq[0].Value <<= xFrame;
+ aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationData" ));
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ ::rtl::OUString aAddonToolBarName( aAddonsToolBarStaticName + m_pAddonOptions->GetAddonsToolbarResourceName(i) );
+ aAddonToolBarData = m_pAddonOptions->GetAddonsToolBarPart( i );
+ aPropSeq[1].Value <<= aAddonToolBarData;
+
+ UIElement aElement = implts_findToolbar( aAddonToolBarName );
+
+ // #i79828
+ // It's now possible that we are called more than once. Be sure to not create
+ // add-on toolbars more than once!
+ if ( aElement.m_xUIElement.is() )
+ continue;
+
+ try
+ {
+ xUIElement = xUIElementFactory->createUIElement( aAddonToolBarName, aPropSeq );
+ if ( xUIElement.is() )
+ {
+ uno::Reference< awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
+ if ( xDockWindow.is() )
+ {
+ try
+ {
+ xDockWindow->addDockableWindowListener( uno::Reference< awt::XDockableWindowListener >( static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
+ xDockWindow->enableDocking( sal_True );
+ uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY );
+ if ( xWindow.is() )
+ xWindow->addWindowListener( uno::Reference< awt::XWindowListener >( static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
+ }
+ catch ( uno::Exception& ) {}
+ }
+
+ ::rtl::OUString aGenericAddonTitle = implts_generateGenericAddonToolbarTitle( i+1 );
+
+ if ( aElement.m_aName.getLength() > 0 )
+ {
+ // Reuse a local entry so we are able to use the latest
+ // UI changes for this document.
+ implts_setElementData( aElement, xDockWindow );
+ aElement.m_xUIElement = xUIElement;
+ if ( aElement.m_aUIName.getLength() == 0 )
+ {
+ aElement.m_aUIName = aGenericAddonTitle;
+ implts_writeWindowStateData( aElement );
+ }
+ }
+ else
+ {
+ // Create new UI element and try to read its state data
+ UIElement aNewToolbar( aAddonToolBarName, aElementType, xUIElement );
+ aNewToolbar.m_bFloating = true;
+ implts_readWindowStateData( aAddonToolBarName, aNewToolbar );
+ implts_setElementData( aNewToolbar, xDockWindow );
+ if ( aNewToolbar.m_aUIName.getLength() == 0 )
+ {
+ aNewToolbar.m_aUIName = aGenericAddonTitle;
+ implts_writeWindowStateData( aNewToolbar );
+ }
+ implts_insertToolbar( aNewToolbar );
+ }
+
+ uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY );
+ if ( xWindow.is() )
+ {
+ // Set generic title for add-on toolbar
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow->GetText().Len() == 0 )
+ pWindow->SetText( aGenericAddonTitle );
+ if ( pWindow->GetType() == WINDOW_TOOLBOX )
+ {
+ ToolBox* pToolbar = (ToolBox *)pWindow;
+ pToolbar->SetMenuType();
+ }
+ }
+ }
+ }
+ catch ( container::NoSuchElementException& ) {}
+ catch ( lang::IllegalArgumentException& ) {}
+ }
+}
+
+void ToolbarLayoutManager::implts_createCustomToolBars()
+{
+ ReadGuard aReadLock( m_aLock );
+ if ( !m_bComponentAttached )
+ return;
+
+ uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
+ uno::Reference< frame::XFrame > xFrame( m_xFrame );
+ uno::Reference< frame::XModel > xModel;
+ uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr, uno::UNO_QUERY );
+ uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr, uno::UNO_QUERY );
+ aReadLock.unlock();
+
+ if ( xFrame.is() )
+ {
+ xModel = impl_getModelFromFrame( xFrame );
+ if ( implts_isPreviewModel( xModel ))
+ return; // no custom toolbars for preview frame!
+
+ uno::Sequence< uno::Sequence< beans::PropertyValue > > aTbxSeq;
+ if ( xDocCfgMgr.is() )
+ {
+ aTbxSeq = xDocCfgMgr->getUIElementsInfo( ui::UIElementType::TOOLBAR );
+ implts_createCustomToolBars( aTbxSeq ); // first create all document based toolbars
+ }
+ if ( xModuleCfgMgr.is() )
+ {
+ aTbxSeq = xModuleCfgMgr->getUIElementsInfo( ui::UIElementType::TOOLBAR );
+ implts_createCustomToolBars( aTbxSeq ); // second create module based toolbars
+ }
+ }
+}
+
+void ToolbarLayoutManager::implts_createNonContextSensitiveToolBars()
+{
+ ReadGuard aReadLock( m_aLock );
+
+ if ( !m_xPersistentWindowState.is() || !m_xFrame.is() || !m_bComponentAttached )
+ return;
+
+ uno::Reference< frame::XFrame > xFrame( m_xFrame );
+ uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
+ uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
+ aReadLock.unlock();
+
+ if ( implts_isPreviewModel( impl_getModelFromFrame( xFrame )))
+ return;
+
+ std::vector< rtl::OUString > aMakeVisibleToolbars;
+
+ try
+ {
+ uno::Sequence< ::rtl::OUString > aToolbarNames = xPersistentWindowState->getElementNames();
+
+ if ( aToolbarNames.getLength() > 0 )
+ {
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+ ::rtl::OUString aName;
+
+ uno::Reference< ui::XUIElement > xUIElement;
+ aMakeVisibleToolbars.reserve(aToolbarNames.getLength());
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ const rtl::OUString* pTbNames = aToolbarNames.getConstArray();
+ for ( sal_Int32 i = 0; i < aToolbarNames.getLength(); i++ )
+ {
+ aName = pTbNames[i];
+ parseResourceURL( aName, aElementType, aElementName );
+
+ // Check that we only create:
+ // - Toolbars (the statusbar is also member of the persistent window state)
+ // - Not custom toolbars, there are created with their own method (implts_createCustomToolbars)
+ if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" ) && aElementName.indexOf( m_aCustomTbxPrefix ) == -1 )
+ {
+ UIElement aNewToolbar = implts_findToolbar( aName );
+ bool bFound = ( aNewToolbar.m_aName == aName );
+ if ( !bFound )
+ implts_readWindowStateData( aName, aNewToolbar );
+
+ if ( aNewToolbar.m_bVisible && !aNewToolbar.m_bContextSensitive )
+ {
+ if ( !bFound )
+ implts_insertToolbar( aNewToolbar );
+ aMakeVisibleToolbars.push_back( aName );
+ }
+ }
+ }
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ }
+ }
+ catch ( uno::RuntimeException& ) { throw; }
+ catch ( uno::Exception& ) {}
+
+ if ( !aMakeVisibleToolbars.empty() )
+ ::std::for_each( aMakeVisibleToolbars.begin(), aMakeVisibleToolbars.end(),::boost::bind( &ToolbarLayoutManager::requestToolbar, this,_1 ));
+}
+
+void ToolbarLayoutManager::implts_createCustomToolBars( const uno::Sequence< uno::Sequence< beans::PropertyValue > >& aTbxSeqSeq )
+{
+ const uno::Sequence< beans::PropertyValue >* pTbxSeq = aTbxSeqSeq.getConstArray();
+ for ( sal_Int32 i = 0; i < aTbxSeqSeq.getLength(); i++ )
+ {
+ const uno::Sequence< beans::PropertyValue >& rTbxSeq = pTbxSeq[i];
+ ::rtl::OUString aTbxResName;
+ ::rtl::OUString aTbxTitle;
+ for ( sal_Int32 j = 0; j < rTbxSeq.getLength(); j++ )
+ {
+ if ( rTbxSeq[j].Name.equalsAscii( "ResourceURL" ))
+ rTbxSeq[j].Value >>= aTbxResName;
+ else if ( rTbxSeq[j].Name.equalsAscii( "UIName" ))
+ rTbxSeq[j].Value >>= aTbxTitle;
+ }
+
+ // Only create custom toolbars. Their name have to start with "custom_"!
+ if ( aTbxResName.getLength() > 0 && aTbxResName.indexOf( m_aCustomTbxPrefix ) != -1 )
+ implts_createCustomToolBar( aTbxResName, aTbxTitle );
+ }
+}
+
+void ToolbarLayoutManager::implts_createCustomToolBar( const rtl::OUString& aTbxResName, const rtl::OUString& aTitle )
+{
+ if ( aTbxResName.getLength() > 0 )
+ {
+ bool bNotify( false );
+ uno::Reference< ui::XUIElement > xUIElement;
+ implts_createToolBar( aTbxResName, bNotify, xUIElement );
+
+ if ( aTitle && xUIElement.is() )
+ {
+ SolarMutexGuard aGuard;
+
+ Window* pWindow = getWindowFromXUIElement( xUIElement );
+ if ( pWindow )
+ pWindow->SetText( aTitle );
+ }
+ }
+}
+
+void ToolbarLayoutManager::implts_reparentToolbars()
+{
+ WriteGuard aWriteLock( m_aLock );
+ UIElementVector aUIElementVector = m_aUIElements;
+ Window* pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
+ Window* pTopDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
+ Window* pBottomDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
+ Window* pLeftDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
+ Window* pRightDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
+ aWriteLock.unlock();
+
+ SolarMutexGuard aGuard;
+ if ( pContainerWindow )
+ {
+ UIElementVector::iterator pIter;
+ for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ )
+ {
+ uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
+ if ( xUIElement.is() )
+ {
+ uno::Reference< awt::XWindow > xWindow;
+ try
+ {
+ // We have to retreive the window reference with try/catch as it is
+ // possible that all elements have been disposed!
+ xWindow = uno::Reference< awt::XWindow >( xUIElement->getRealInterface(), uno::UNO_QUERY );
+ }
+ catch ( uno::RuntimeException& ) { throw; }
+ catch ( uno::Exception& ) {}
+
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow )
+ {
+ // Reparent our child windows acording to their current state.
+ if ( pIter->m_bFloating )
+ pWindow->SetParent( pContainerWindow );
+ else
+ {
+ if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_TOP )
+ pWindow->SetParent( pTopDockWindow );
+ else if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
+ pWindow->SetParent( pBottomDockWindow );
+ else if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )
+ pWindow->SetParent( pLeftDockWindow );
+ else
+ pWindow->SetParent( pRightDockWindow );
+ }
+ }
+ }
+ }
+ }
+}
+
+void ToolbarLayoutManager::implts_setToolbarCreation( bool bStart )
+{
+ WriteGuard aWriteLock( m_aLock );
+ m_bToolbarCreation = bStart;
+}
+
+bool ToolbarLayoutManager::implts_isToolbarCreationActive()
+{
+ ReadGuard aReadLock( m_aLock );
+ return m_bToolbarCreation;
+}
+
+void ToolbarLayoutManager::implts_createToolBar( const ::rtl::OUString& aName, bool& bNotify, uno::Reference< ui::XUIElement >& rUIElement )
+{
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< frame::XFrame > xFrame( m_xFrame );
+ uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
+ aReadLock.unlock();
+
+ bNotify = false;
+
+ if ( !xFrame.is() || !xContainerWindow.is() )
+ return;
+
+ UIElement aToolbarElement = implts_findToolbar( aName );
+ if ( !aToolbarElement.m_xUIElement.is() )
+ {
+ uno::Reference< ui::XUIElement > xUIElement = implts_createElement( aName );
+
+ bool bVisible( false );
+ bool bFloating( false );
+ if ( xUIElement.is() )
+ {
+ rUIElement = xUIElement;
+
+ uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+ if ( xDockWindow.is() && xWindow.is() )
+ {
+ try
+ {
+ xDockWindow->addDockableWindowListener( uno::Reference< awt::XDockableWindowListener >(
+ static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
+ xWindow->addWindowListener( uno::Reference< awt::XWindowListener >(
+ static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
+ xDockWindow->enableDocking( sal_True );
+ }
+ catch ( uno::Exception& ) {}
+ }
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ UIElement& rElement = impl_findToolbar( aName );
+ if ( rElement.m_aName.getLength() > 0 )
+ {
+ // Reuse a local entry so we are able to use the latest
+ // UI changes for this document.
+ implts_setElementData( rElement, xDockWindow );
+ rElement.m_xUIElement = xUIElement;
+ bVisible = rElement.m_bVisible;
+ bFloating = rElement.m_bFloating;
+ }
+ else
+ {
+ // Create new UI element and try to read its state data
+ UIElement aNewToolbar( aName, m_aToolbarTypeString, xUIElement );
+ implts_readWindowStateData( aName, aNewToolbar );
+ implts_setElementData( aNewToolbar, xDockWindow );
+ implts_insertToolbar( aNewToolbar );
+ bVisible = aNewToolbar.m_bVisible;
+ bFloating = rElement.m_bFloating;
+ }
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ // set toolbar menu style according to customize command state
+ SvtCommandOptions aCmdOptions;
+
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
+ {
+ ToolBox* pToolbar = (ToolBox *)pWindow;
+ sal_uInt16 nMenuType = pToolbar->GetMenuType();
+ if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, m_aCustomizeCmd ))
+ pToolbar->SetMenuType( nMenuType & ~TOOLBOX_MENUTYPE_CUSTOMIZE );
+ else
+ pToolbar->SetMenuType( nMenuType | TOOLBOX_MENUTYPE_CUSTOMIZE );
+ }
+ bNotify = true;
+
+ implts_sortUIElements();
+
+ if ( bVisible && !bFloating )
+ implts_setLayoutDirty();
+ }
+ }
+}
+
+uno::Reference< ui::XUIElement > ToolbarLayoutManager::implts_createElement( const ::rtl::OUString& aName )
+{
+ uno::Reference< ui::XUIElement > xUIElement;
+
+ ReadGuard aReadLock( m_aLock );
+ uno::Sequence< beans::PropertyValue > aPropSeq( 2 );
+ aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropSeq[0].Value <<= m_xFrame;
+ aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" ));
+ aPropSeq[1].Value <<= true;
+ uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
+ aReadLock.unlock();
+
+ implts_setToolbarCreation( true );
+ try
+ {
+ if ( xUIElementFactory.is() )
+ xUIElement = xUIElementFactory->createUIElement( aName, aPropSeq );
+ }
+ catch ( container::NoSuchElementException& ) {}
+ catch ( lang::IllegalArgumentException& ) {}
+ implts_setToolbarCreation( false );
+
+ return xUIElement;
+}
+
+void ToolbarLayoutManager::implts_setElementData( UIElement& rElement, const uno::Reference< awt::XDockableWindow >& rDockWindow )
+{
+ ReadGuard aReadLock( m_aLock );
+ bool bShowElement( rElement.m_bVisible && !rElement.m_bMasterHide && implts_isParentWindowVisible() );
+ aReadLock.unlock();
+
+ uno::Reference< awt::XDockableWindow > xDockWindow( rDockWindow );
+ uno::Reference< awt::XWindow2 > xWindow( xDockWindow, uno::UNO_QUERY );
+
+ Window* pWindow( 0 );
+ ToolBox* pToolBox( 0 );
+
+ if ( xDockWindow.is() && xWindow.is() )
+ {
+ {
+ SolarMutexGuard aGuard;
+ pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow )
+ {
+ String aText = pWindow->GetText();
+ if ( aText.Len() == 0 )
+ pWindow->SetText( rElement.m_aUIName );
+ if ( rElement.m_bNoClose )
+ pWindow->SetStyle( pWindow->GetStyle() & ~WB_CLOSEABLE );
+ if ( pWindow->GetType() == WINDOW_TOOLBOX )
+ pToolBox = (ToolBox *)pWindow;
+ }
+ if ( pToolBox )
+ {
+ if (( rElement.m_nStyle < 0 ) || ( rElement.m_nStyle > BUTTON_SYMBOLTEXT ))
+ rElement.m_nStyle = BUTTON_SYMBOL;
+ pToolBox->SetButtonType( (ButtonType)rElement.m_nStyle );
+ if ( rElement.m_bNoClose )
+ pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE );
+ }
+ }
+
+ if ( rElement.m_bFloating )
+ {
+ if ( pWindow )
+ {
+ SolarMutexGuard aGuard;
+ String aText = pWindow->GetText();
+ if ( aText.Len() == 0 )
+ pWindow->SetText( rElement.m_aUIName );
+ }
+
+ ::Point aPos( rElement.m_aFloatingData.m_aPos.X(),
+ rElement.m_aFloatingData.m_aPos.Y() );
+ bool bWriteData( false );
+ bool bUndefPos = hasDefaultPosValue( rElement.m_aFloatingData.m_aPos );
+ bool bSetSize = ( rElement.m_aFloatingData.m_aSize.Width() != 0 &&
+ rElement.m_aFloatingData.m_aSize.Height() != 0 );
+ xDockWindow->setFloatingMode( sal_True );
+ if ( bUndefPos )
+ {
+ aPos = implts_findNextCascadeFloatingPos();
+ rElement.m_aFloatingData.m_aPos = aPos; // set new cascaded position
+ bWriteData = true;
+ }
+
+ if( bSetSize )
+ xWindow->setOutputSize( AWTSize( rElement.m_aFloatingData.m_aSize ) );
+ else
+ {
+ if( pToolBox )
+ {
+ // set an optimal initial floating size
+ SolarMutexGuard aGuard;
+ ::Size aSize( pToolBox->CalcFloatingWindowSizePixel() );
+ pToolBox->SetOutputSizePixel( aSize );
+ }
+ }
+
+ // #i60882# IMPORTANT: Set position after size as it is
+ // possible that we position some part of the toolbar
+ // outside of the desktop. A default constructed toolbar
+ // always has one line. Now VCL automatically
+ // position the toolbar back into the desktop. Therefore
+ // we resize the toolbar with the new (wrong) position.
+ // To fix this problem we have to set the size BEFORE the
+ // position.
+ xWindow->setPosSize( aPos.X(), aPos.Y(), 0, 0, awt::PosSize::POS );
+
+ if ( bWriteData )
+ implts_writeWindowStateData( rElement );
+ if ( bShowElement && pWindow )
+ {
+ SolarMutexGuard aGuard;
+ pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ }
+ }
+ else
+ {
+ bool bSetSize( false );
+ ::Point aDockPos;
+ ::Point aPixelPos;
+ ::Size aSize;
+
+ if ( pToolBox )
+ {
+ SolarMutexGuard aGuard;
+ pToolBox->SetAlign( ImplConvertAlignment(rElement.m_aDockedData.m_nDockedArea ) );
+ pToolBox->SetLineCount( 1 );
+ xDockWindow->setFloatingMode( sal_False );
+ if ( rElement.m_aDockedData.m_bLocked )
+ xDockWindow->lock();
+ aSize = pToolBox->CalcWindowSizePixel();
+ bSetSize = true;
+
+ if ( isDefaultPos( rElement.m_aDockedData.m_aPos ))
+ {
+ implts_findNextDockingPos( (ui::DockingArea)rElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos );
+ rElement.m_aDockedData.m_aPos = aDockPos;
+ }
+ }
+
+ xWindow->setPosSize( aPixelPos.X(), aPixelPos.Y(), 0, 0, awt::PosSize::POS );
+ if( bSetSize )
+ xWindow->setOutputSize( AWTSize( aSize) );
+
+ if ( pWindow )
+ {
+ SolarMutexGuard aGuard;
+ if ( !bShowElement )
+ pWindow->Hide();
+ }
+ }
+ }
+}
+
+void ToolbarLayoutManager::implts_destroyDockingAreaWindows()
+{
+ WriteGuard aWriteLock( m_aLock );
+ uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
+ uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
+ uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
+ uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
+ m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP].clear();
+ m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT].clear();
+ m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT].clear();
+ m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM].clear();
+ aWriteLock.unlock();
+
+ // destroy windows
+ xTopDockingWindow->dispose();
+ xLeftDockingWindow->dispose();
+ xRightDockingWindow->dispose();
+ xBottomDockingWindow->dispose();
+}
+
+//---------------------------------------------------------------------------------------------------------
+// persistence methods
+//---------------------------------------------------------------------------------------------------------
+
+sal_Bool ToolbarLayoutManager::implts_readWindowStateData( const rtl::OUString& aName, UIElement& rElementData )
+{
+ WriteGuard aWriteLock( m_aLock );
+ uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
+ bool bGetSettingsState( false );
+ aWriteLock.unlock();
+
+ if ( xPersistentWindowState.is() )
+ {
+ aWriteLock.lock();
+ bool bGlobalSettings( m_bGlobalSettings );
+ GlobalSettings* pGlobalSettings( 0 );
+ if ( m_pGlobalSettings == 0 )
+ {
+ m_pGlobalSettings = new GlobalSettings( m_xSMGR );
+ bGetSettingsState = true;
+ }
+ pGlobalSettings = m_pGlobalSettings;
+ aWriteLock.unlock();
+
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aWindowState;
+ if ( xPersistentWindowState->getByName( aName ) >>= aWindowState )
+ {
+ sal_Bool bValue( sal_False );
+ for ( sal_Int32 n = 0; n < aWindowState.getLength(); n++ )
+ {
+ if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKED ))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bFloating = !bValue;
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE ))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bVisible = bValue;
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKINGAREA ))
+ {
+ ui::DockingArea eDockingArea;
+ if ( aWindowState[n].Value >>= eDockingArea )
+ rElementData.m_aDockedData.m_nDockedArea = sal_Int16( eDockingArea );
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKPOS ))
+ {
+ awt::Point aPoint;
+ if ( aWindowState[n].Value >>= aPoint )
+ {
+ rElementData.m_aDockedData.m_aPos.X() = aPoint.X;
+ rElementData.m_aDockedData.m_aPos.Y() = aPoint.Y;
+ }
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_POS ))
+ {
+ awt::Point aPoint;
+ if ( aWindowState[n].Value >>= aPoint )
+ {
+ rElementData.m_aFloatingData.m_aPos.X() = aPoint.X;
+ rElementData.m_aFloatingData.m_aPos.Y() = aPoint.Y;
+ }
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_SIZE ))
+ {
+ awt::Size aSize;
+ if ( aWindowState[n].Value >>= aSize )
+ {
+ rElementData.m_aFloatingData.m_aSize.Width() = aSize.Width;
+ rElementData.m_aFloatingData.m_aSize.Height() = aSize.Height;
+ }
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_UINAME ))
+ aWindowState[n].Value >>= rElementData.m_aUIName;
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_STYLE ))
+ {
+ sal_Int32 nStyle = 0;
+ if ( aWindowState[n].Value >>= nStyle )
+ rElementData.m_nStyle = sal_Int16( nStyle );
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_LOCKED ))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_aDockedData.m_bLocked = bValue;
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT ))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bContextSensitive = bValue;
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_NOCLOSE ))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bNoClose = bValue;
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXTACTIVE ))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bContextActive = bValue;
+ }
+ else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_SOFTCLOSE ))
+ {
+ if ( aWindowState[n].Value >>= bValue )
+ rElementData.m_bSoftClose = bValue;
+ }
+ }
+ }
+
+ // oversteer values with global settings
+ if ( pGlobalSettings && ( bGetSettingsState || bGlobalSettings ))
+ {
+ if ( pGlobalSettings->HasStatesInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR ))
+ {
+ WriteGuard aWriteLock2( m_aLock );
+ m_bGlobalSettings = true;
+ aWriteLock2.unlock();
+
+ uno::Any aValue;
+ sal_Bool bValue = sal_Bool();
+ if ( pGlobalSettings->GetStateInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR,
+ GlobalSettings::STATEINFO_LOCKED,
+ aValue ))
+ aValue >>= rElementData.m_aDockedData.m_bLocked;
+ if ( pGlobalSettings->GetStateInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR,
+ GlobalSettings::STATEINFO_DOCKED,
+ aValue ))
+ {
+ if ( aValue >>= bValue )
+ rElementData.m_bFloating = !bValue;
+ }
+ }
+ }
+
+ return sal_True;
+ }
+ catch ( container::NoSuchElementException& ) {}
+ }
+
+ return sal_False;
+}
+
+void ToolbarLayoutManager::implts_writeWindowStateData( const UIElement& rElementData )
+{
+ WriteGuard aWriteLock( m_aLock );
+ uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
+ m_bStoreWindowState = true; // set flag to determine that we triggered the notification
+ aWriteLock.unlock();
+
+ bool bPersistent( sal_False );
+ uno::Reference< beans::XPropertySet > xPropSet( rElementData.m_xUIElement, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ // Check persistent flag of the user interface element
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" ))) >>= bPersistent;
+ }
+ catch ( beans::UnknownPropertyException )
+ {
+ bPersistent = true; // Non-configurable elements should at least store their dimension/position
+ }
+ catch ( lang::WrappedTargetException ) {}
+ }
+
+ if ( bPersistent && xPersistentWindowState.is() )
+ {
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aWindowState( 8 );
+
+ aWindowState[0].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_DOCKED );
+ aWindowState[0].Value = ::uno::makeAny( sal_Bool( !rElementData.m_bFloating ));
+ aWindowState[1].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_VISIBLE );
+ aWindowState[1].Value = uno::makeAny( sal_Bool( rElementData.m_bVisible ));
+ aWindowState[2].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_DOCKINGAREA );
+ aWindowState[2].Value = uno::makeAny( static_cast< ui::DockingArea >( rElementData.m_aDockedData.m_nDockedArea ) );
+
+ awt::Point aPos;
+ aPos.X = rElementData.m_aDockedData.m_aPos.X();
+ aPos.Y = rElementData.m_aDockedData.m_aPos.Y();
+ aWindowState[3].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_DOCKPOS );
+ aWindowState[3].Value <<= aPos;
+
+ aPos.X = rElementData.m_aFloatingData.m_aPos.X();
+ aPos.Y = rElementData.m_aFloatingData.m_aPos.Y();
+ aWindowState[4].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_POS );
+ aWindowState[4].Value <<= aPos;
+
+ awt::Size aSize;
+ aSize.Width = rElementData.m_aFloatingData.m_aSize.Width();
+ aSize.Height = rElementData.m_aFloatingData.m_aSize.Height();
+ aWindowState[5].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_SIZE );
+ aWindowState[5].Value <<= aSize;
+ aWindowState[6].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_UINAME );
+ aWindowState[6].Value = uno::makeAny( rElementData.m_aUIName );
+ aWindowState[7].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_LOCKED );
+ aWindowState[7].Value = uno::makeAny( rElementData.m_aDockedData.m_bLocked );
+
+ ::rtl::OUString aName = rElementData.m_aName;
+ if ( xPersistentWindowState->hasByName( aName ))
+ {
+ uno::Reference< container::XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY );
+ xReplace->replaceByName( aName, uno::makeAny( aWindowState ));
+ }
+ else
+ {
+ uno::Reference< container::XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY );
+ xInsert->insertByName( aName, uno::makeAny( aWindowState ));
+ }
+ }
+ catch ( uno::Exception& ) {}
+ }
+
+ // Reset flag
+ aWriteLock.lock();
+ m_bStoreWindowState = false;
+ aWriteLock.unlock();
+}
+
+void ToolbarLayoutManager::implts_writeNewWindowStateData( const rtl::OUString aName, const uno::Reference< awt::XWindow >& xWindow )
+{
+ bool bVisible( false );
+ bool bFloating( true );
+ awt::Rectangle aPos;
+ awt::Size aSize;
+
+ if ( xWindow.is() )
+ {
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+ if ( xDockWindow.is() )
+ bFloating = xDockWindow->isFloating();
+
+ uno::Reference< awt::XWindow2 > xWindow2( xWindow, uno::UNO_QUERY );
+ if( xWindow2.is() )
+ {
+ aPos = xWindow2->getPosSize();
+ aSize = xWindow2->getOutputSize(); // always use output size for consistency
+ bVisible = xWindow2->isVisible();
+ }
+
+ WriteGuard aWriteLock( m_aLock );
+ UIElement& rUIElement = impl_findToolbar( aName );
+ if ( rUIElement.m_xUIElement.is() )
+ {
+ rUIElement.m_bVisible = bVisible;
+ rUIElement.m_bFloating = bFloating;
+ if ( bFloating )
+ {
+ rUIElement.m_aFloatingData.m_aPos = ::Point( aPos.X, aPos.Y );
+ rUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height );
+ }
+ }
+ implts_writeWindowStateData( rUIElement );
+ aWriteLock.unlock();
+ }
+}
+
+/******************************************************************************
+ LOOKUP PART FOR TOOLBARS
+******************************************************************************/
+
+UIElement& ToolbarLayoutManager::impl_findToolbar( const rtl::OUString& aName )
+{
+ static UIElement aEmptyElement;
+ UIElementVector::iterator pIter;
+
+ ReadGuard aReadLock( m_aLock );
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ if ( pIter->m_aName == aName )
+ return *pIter;
+ }
+
+ return aEmptyElement;
+}
+
+UIElement ToolbarLayoutManager::implts_findToolbar( const rtl::OUString& aName )
+{
+ ReadGuard aReadLock( m_aLock );
+ UIElement aElement = impl_findToolbar( aName );
+ aReadLock.unlock();
+
+ return aElement;
+}
+
+UIElement ToolbarLayoutManager::implts_findToolbar( const uno::Reference< uno::XInterface >& xToolbar )
+{
+ UIElement aToolbar;
+ UIElementVector::const_iterator pIter;
+
+ ReadGuard aReadLock( m_aLock );
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ if ( pIter->m_xUIElement.is() )
+ {
+ uno::Reference< uno::XInterface > xIfac( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY );
+ if ( xIfac == xToolbar )
+ {
+ aToolbar = *pIter;
+ break;
+ }
+ }
+ }
+
+ return aToolbar;
+}
+
+uno::Reference< awt::XWindow > ToolbarLayoutManager::implts_getXWindow( const ::rtl::OUString& aName )
+{
+ UIElementVector::iterator pIter;
+ uno::Reference< awt::XWindow > xWindow;
+
+ ReadGuard aReadLock( m_aLock );
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ if ( pIter->m_aName == aName && pIter->m_xUIElement.is() )
+ {
+ xWindow = uno::Reference< awt::XWindow >( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY );
+ break;
+ }
+ }
+
+ return xWindow;
+}
+
+Window* ToolbarLayoutManager::implts_getWindow( const ::rtl::OUString& aName )
+{
+ uno::Reference< awt::XWindow > xWindow = implts_getXWindow( aName );
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+
+ return pWindow;
+}
+
+bool ToolbarLayoutManager::implts_insertToolbar( const UIElement& rUIElement )
+{
+ UIElement aTempData;
+ bool bFound( false );
+ bool bResult( false );
+
+ aTempData = implts_findToolbar( rUIElement.m_aName );
+ if ( aTempData.m_aName == rUIElement.m_aName )
+ bFound = true;
+
+ if ( !bFound )
+ {
+ WriteGuard aWriteLock( m_aLock );
+ m_aUIElements.push_back( rUIElement );
+ bResult = true;
+ }
+
+ return bResult;
+}
+
+void ToolbarLayoutManager::implts_setToolbar( const UIElement& rUIElement )
+{
+ WriteGuard aWriteLock( m_aLock );
+ UIElement& rData = impl_findToolbar( rUIElement.m_aName );
+ if ( rData.m_aName == rUIElement.m_aName )
+ rData = rUIElement;
+ else
+ m_aUIElements.push_back( rUIElement );
+}
+
+/******************************************************************************
+ LAYOUT CODE PART FOR TOOLBARS
+******************************************************************************/
+
+::Point ToolbarLayoutManager::implts_findNextCascadeFloatingPos()
+{
+ const sal_Int32 nHotZoneX = 50;
+ const sal_Int32 nHotZoneY = 50;
+ const sal_Int32 nCascadeIndentX = 15;
+ const sal_Int32 nCascadeIndentY = 15;
+
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
+ uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
+ uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
+ aReadLock.unlock();
+
+ ::Point aStartPos( nCascadeIndentX, nCascadeIndentY );
+ ::Point aCurrPos( aStartPos );
+ awt::Rectangle aRect;
+
+ Window* pContainerWindow( 0 );
+ if ( xContainerWindow.is() )
+ {
+ SolarMutexGuard aGuard;
+ pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ if ( pContainerWindow )
+ aStartPos = pContainerWindow->OutputToScreenPixel( aStartPos );
+ }
+
+ // Determine size of top and left docking area
+ awt::Rectangle aTopRect( xTopDockingWindow->getPosSize() );
+ awt::Rectangle aLeftRect( xLeftDockingWindow->getPosSize() );
+
+ aStartPos.X() += aLeftRect.Width + nCascadeIndentX;
+ aStartPos.Y() += aTopRect.Height + nCascadeIndentY;
+ aCurrPos = aStartPos;
+
+ // Try to find a cascaded position for the new floating window
+ UIElementVector::const_iterator pIter;
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ if ( pIter->m_xUIElement.is() )
+ {
+ uno::Reference< awt::XDockableWindow > xDockWindow( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY );
+ uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY );
+ if ( xDockWindow.is() && xDockWindow->isFloating() )
+ {
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->IsVisible() )
+ {
+ awt::Rectangle aFloatRect = xWindow->getPosSize();
+ if ((( aFloatRect.X - nHotZoneX ) <= aCurrPos.X() ) &&
+ ( aFloatRect.X >= aCurrPos.X() ) &&
+ (( aFloatRect.Y - nHotZoneY ) <= aCurrPos.Y() ) &&
+ ( aFloatRect.Y >= aCurrPos.Y() ))
+ {
+ aCurrPos.X() = aFloatRect.X + nCascadeIndentX;
+ aCurrPos.Y() = aFloatRect.Y + nCascadeIndentY;
+ }
+ }
+ }
+ }
+ }
+
+ return aCurrPos;
+}
+
+void ToolbarLayoutManager::implts_sortUIElements()
+{
+ WriteGuard aWriteLock( m_aLock );
+ UIElementVector::iterator pIterStart = m_aUIElements.begin();
+ UIElementVector::iterator pIterEnd = m_aUIElements.end();
+
+ std::stable_sort( pIterStart, pIterEnd ); // first created element should first
+
+ // We have to reset our temporary flags.
+ UIElementVector::iterator pIter;
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ pIter->m_bUserActive = sal_False;
+ aWriteLock.unlock();
+}
+
+void ToolbarLayoutManager::implts_getUIElementVectorCopy( UIElementVector& rCopy )
+{
+ ReadGuard aReadLock( m_aLock );
+ rCopy = m_aUIElements;
+}
+
+::Size ToolbarLayoutManager::implts_getTopBottomDockingAreaSizes()
+{
+ ::Size aSize;
+ uno::Reference< awt::XWindow > xTopDockingAreaWindow;
+ uno::Reference< awt::XWindow > xBottomDockingAreaWindow;
+
+ ReadGuard aReadLock( m_aLock );
+ xTopDockingAreaWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP];
+ xBottomDockingAreaWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM];
+ aReadLock.unlock();
+
+ if ( xTopDockingAreaWindow.is() )
+ aSize.Width() = xTopDockingAreaWindow->getPosSize().Height;
+ if ( xBottomDockingAreaWindow.is() )
+ aSize.Height() = xBottomDockingAreaWindow->getPosSize().Height;
+
+ return aSize;
+}
+
+void ToolbarLayoutManager::implts_getDockingAreaElementInfos( ui::DockingArea eDockingArea, std::vector< SingleRowColumnWindowData >& rRowColumnsWindowData )
+{
+ std::vector< UIElement > aWindowVector;
+
+ if (( eDockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
+ eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;
+
+ uno::Reference< awt::XWindow > xDockAreaWindow;
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+ aWindowVector.reserve(m_aUIElements.size());
+ xDockAreaWindow = m_xDockAreaWindows[eDockingArea];
+ UIElementVector::iterator pIter;
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea && pIter->m_bVisible && !pIter->m_bFloating )
+ {
+ uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
+ if ( xUIElement.is() )
+ {
+ uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+ if ( xDockWindow.is() )
+ {
+ // docked windows
+ aWindowVector.push_back( *pIter );
+ }
+ }
+ }
+ }
+ aReadLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ rRowColumnsWindowData.clear();
+
+ // Collect data from windows that are on the same row/column
+ sal_Int32 j;
+ sal_Int32 nIndex( 0 );
+ sal_Int32 nLastPos( 0 );
+ sal_Int32 nCurrPos( -1 );
+ sal_Int32 nLastRowColPixelPos( 0 );
+ awt::Rectangle aDockAreaRect;
+
+ if ( xDockAreaWindow.is() )
+ aDockAreaRect = xDockAreaWindow->getPosSize();
+
+ if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
+ nLastRowColPixelPos = 0;
+ else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
+ nLastRowColPixelPos = aDockAreaRect.Height;
+ else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
+ nLastRowColPixelPos = 0;
+ else
+ nLastRowColPixelPos = aDockAreaRect.Width;
+
+ const sal_uInt32 nCount = aWindowVector.size();
+ for ( j = 0; j < sal_Int32( nCount); j++ )
+ {
+ const UIElement& rElement = aWindowVector[j];
+ uno::Reference< awt::XWindow > xWindow;
+ uno::Reference< ui::XUIElement > xUIElement( rElement.m_xUIElement );
+ awt::Rectangle aPosSize;
+
+ if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) )
+ continue;
+ if ( isHorizontalDockingArea( eDockingArea ))
+ {
+ if ( nCurrPos == -1 )
+ {
+ nCurrPos = rElement.m_aDockedData.m_aPos.Y();
+ nLastPos = 0;
+
+ SingleRowColumnWindowData aRowColumnWindowData;
+ aRowColumnWindowData.nRowColumn = nCurrPos;
+ rRowColumnsWindowData.push_back( aRowColumnWindowData );
+ }
+
+ sal_Int32 nSpace( 0 );
+ if ( rElement.m_aDockedData.m_aPos.Y() != nCurrPos )
+ {
+ if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
+ nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize;
+ else
+ nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize;
+ ++nIndex;
+ nLastPos = 0;
+ nCurrPos = rElement.m_aDockedData.m_aPos.Y();
+ SingleRowColumnWindowData aRowColumnWindowData;
+ aRowColumnWindowData.nRowColumn = nCurrPos;
+ rRowColumnsWindowData.push_back( aRowColumnWindowData );
+ }
+
+ // Calc space before an element and store it
+ nSpace = ( rElement.m_aDockedData.m_aPos.X() - nLastPos );
+ if ( rElement.m_aDockedData.m_aPos.X() >= nLastPos )
+ {
+ rRowColumnsWindowData[nIndex].nSpace += nSpace;
+ nLastPos = rElement.m_aDockedData.m_aPos.X() + aPosSize.Width;
+ }
+ else
+ {
+ nSpace = 0;
+ nLastPos += aPosSize.Width;
+ }
+ rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace );
+
+ rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow );
+ rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName );
+ rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.push_back(
+ awt::Rectangle( rElement.m_aDockedData.m_aPos.X(),
+ rElement.m_aDockedData.m_aPos.Y(),
+ aPosSize.Width,
+ aPosSize.Height ));
+ if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Height )
+ rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Height;
+ if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
+ rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( 0, nLastRowColPixelPos,
+ aDockAreaRect.Width, aPosSize.Height );
+ else
+ rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( 0, ( nLastRowColPixelPos - aPosSize.Height ),
+ aDockAreaRect.Width, aPosSize.Height );
+ rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Width + nSpace;
+ }
+ else
+ {
+ if ( nCurrPos == -1 )
+ {
+ nCurrPos = rElement.m_aDockedData.m_aPos.X();
+ nLastPos = 0;
+
+ SingleRowColumnWindowData aRowColumnWindowData;
+ aRowColumnWindowData.nRowColumn = nCurrPos;
+ rRowColumnsWindowData.push_back( aRowColumnWindowData );
+ }
+
+ sal_Int32 nSpace( 0 );
+ if ( rElement.m_aDockedData.m_aPos.X() != nCurrPos )
+ {
+ if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
+ nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize;
+ else
+ nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize;
+ ++nIndex;
+ nLastPos = 0;
+ nCurrPos = rElement.m_aDockedData.m_aPos.X();
+ SingleRowColumnWindowData aRowColumnWindowData;
+ aRowColumnWindowData.nRowColumn = nCurrPos;
+ rRowColumnsWindowData.push_back( aRowColumnWindowData );
+ }
+
+ // Calc space before an element and store it
+ nSpace = ( rElement.m_aDockedData.m_aPos.Y() - nLastPos );
+ if ( rElement.m_aDockedData.m_aPos.Y() > nLastPos )
+ {
+ rRowColumnsWindowData[nIndex].nSpace += nSpace;
+ nLastPos = rElement.m_aDockedData.m_aPos.Y() + aPosSize.Height;
+ }
+ else
+ {
+ nSpace = 0;
+ nLastPos += aPosSize.Height;
+ }
+ rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace );
+
+ rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow );
+ rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName );
+ rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.push_back(
+ awt::Rectangle( rElement.m_aDockedData.m_aPos.X(),
+ rElement.m_aDockedData.m_aPos.Y(),
+ aPosSize.Width,
+ aPosSize.Height ));
+ if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Width )
+ rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Width;
+ if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
+ rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( nLastRowColPixelPos, 0,
+ aPosSize.Width, aDockAreaRect.Height );
+ else
+ rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( ( nLastRowColPixelPos - aPosSize.Width ), 0,
+ aPosSize.Width, aDockAreaRect.Height );
+ rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Height + nSpace;
+ }
+ }
+}
+
+void ToolbarLayoutManager::implts_getDockingAreaElementInfoOnSingleRowCol( ui::DockingArea eDockingArea, sal_Int32 nRowCol, SingleRowColumnWindowData& rRowColumnWindowData )
+{
+ std::vector< UIElement > aWindowVector;
+
+ if (( eDockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
+ eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;
+
+ bool bHorzDockArea = isHorizontalDockingArea( eDockingArea );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+ UIElementVector::iterator pIter;
+ UIElementVector::iterator pEnd = m_aUIElements.end();
+ for ( pIter = m_aUIElements.begin(); pIter != pEnd; pIter++ )
+ {
+ if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea )
+ {
+ bool bSameRowCol = bHorzDockArea ? ( pIter->m_aDockedData.m_aPos.Y() == nRowCol ) : ( pIter->m_aDockedData.m_aPos.X() == nRowCol );
+ uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
+
+ if ( bSameRowCol && xUIElement.is() )
+ {
+ uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
+ if ( xWindow.is() )
+ {
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+ if ( pWindow && pIter->m_bVisible && xDockWindow.is() && !pIter->m_bFloating )
+ aWindowVector.push_back( *pIter ); // docked windows
+ }
+ }
+ }
+ }
+ aReadLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ // Initialize structure
+ rRowColumnWindowData.aUIElementNames.clear();
+ rRowColumnWindowData.aRowColumnWindows.clear();
+ rRowColumnWindowData.aRowColumnWindowSizes.clear();
+ rRowColumnWindowData.aRowColumnSpace.clear();
+ rRowColumnWindowData.nVarSize = 0;
+ rRowColumnWindowData.nStaticSize = 0;
+ rRowColumnWindowData.nSpace = 0;
+ rRowColumnWindowData.nRowColumn = nRowCol;
+
+ // Collect data from windows that are on the same row/column
+ sal_Int32 j;
+ sal_Int32 nLastPos( 0 );
+
+ const sal_uInt32 nCount = aWindowVector.size();
+ for ( j = 0; j < sal_Int32( nCount); j++ )
+ {
+ const UIElement& rElement = aWindowVector[j];
+ uno::Reference< awt::XWindow > xWindow;
+ uno::Reference< ui::XUIElement > xUIElement( rElement.m_xUIElement );
+ awt::Rectangle aPosSize;
+ if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) )
+ continue;
+
+ sal_Int32 nSpace;
+ if ( isHorizontalDockingArea( eDockingArea ))
+ {
+ nSpace = ( rElement.m_aDockedData.m_aPos.X() - nLastPos );
+
+ // Calc space before an element and store it
+ if ( rElement.m_aDockedData.m_aPos.X() > nLastPos )
+ rRowColumnWindowData.nSpace += nSpace;
+ else
+ nSpace = 0;
+
+ nLastPos = rElement.m_aDockedData.m_aPos.X() + aPosSize.Width;
+
+
+ rRowColumnWindowData.aRowColumnWindowSizes.push_back(
+ awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), rElement.m_aDockedData.m_aPos.Y(),
+ aPosSize.Width, aPosSize.Height ));
+ if ( rRowColumnWindowData.nStaticSize < aPosSize.Height )
+ rRowColumnWindowData.nStaticSize = aPosSize.Height;
+ rRowColumnWindowData.nVarSize += aPosSize.Width;
+ }
+ else
+ {
+ // Calc space before an element and store it
+ nSpace = ( rElement.m_aDockedData.m_aPos.Y() - nLastPos );
+ if ( rElement.m_aDockedData.m_aPos.Y() > nLastPos )
+ rRowColumnWindowData.nSpace += nSpace;
+ else
+ nSpace = 0;
+
+ nLastPos = rElement.m_aDockedData.m_aPos.Y() + aPosSize.Height;
+
+ rRowColumnWindowData.aRowColumnWindowSizes.push_back(
+ awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), rElement.m_aDockedData.m_aPos.Y(),
+ aPosSize.Width, aPosSize.Height ));
+ if ( rRowColumnWindowData.nStaticSize < aPosSize.Width )
+ rRowColumnWindowData.nStaticSize = aPosSize.Width;
+ rRowColumnWindowData.nVarSize += aPosSize.Height;
+ }
+
+ rRowColumnWindowData.aUIElementNames.push_back( rElement.m_aName );
+ rRowColumnWindowData.aRowColumnWindows.push_back( xWindow );
+ rRowColumnWindowData.aRowColumnSpace.push_back( nSpace );
+ rRowColumnWindowData.nVarSize += nSpace;
+ }
+}
+
+::Rectangle ToolbarLayoutManager::implts_getWindowRectFromRowColumn(
+ ui::DockingArea DockingArea,
+ const SingleRowColumnWindowData& rRowColumnWindowData,
+ const ::Point& rMousePos,
+ const rtl::OUString& rExcludeElementName )
+{
+ ::Rectangle aWinRect;
+
+ if (( DockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
+ DockingArea = ui::DockingArea_DOCKINGAREA_TOP;
+
+ if ( rRowColumnWindowData.aRowColumnWindows.empty() )
+ return aWinRect;
+ else
+ {
+ ReadGuard aReadLock( m_aLock );
+ Window* pContainerWindow( VCLUnoHelper::GetWindow( m_xContainerWindow ));
+ Window* pDockingAreaWindow( VCLUnoHelper::GetWindow( m_xDockAreaWindows[DockingArea] ));
+ aReadLock.unlock();
+
+ // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect
+ SolarMutexGuard aGuard;
+
+ // Retrieve output size from container Window
+ if ( pDockingAreaWindow && pContainerWindow )
+ {
+ const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindows.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ awt::Rectangle aWindowRect = rRowColumnWindowData.aRowColumnWindows[i]->getPosSize();
+ ::Rectangle aRect( aWindowRect.X, aWindowRect.Y, aWindowRect.X+aWindowRect.Width, aWindowRect.Y+aWindowRect.Height );
+ aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() )));
+ if ( aRect.IsInside( rMousePos ))
+ {
+ // Check if we have found the excluded element. If yes, we have to provide an empty rectangle.
+ // We prevent that a toolbar cannot be moved when the mouse pointer is inside its own rectangle!
+ if ( rExcludeElementName != rRowColumnWindowData.aUIElementNames[i] )
+ return aRect;
+ else
+ break;
+ }
+ }
+ }
+ }
+
+ return aWinRect;
+}
+
+::Rectangle ToolbarLayoutManager::implts_determineFrontDockingRect(
+ ui::DockingArea eDockingArea,
+ sal_Int32 nRowCol,
+ const ::Rectangle& rDockedElementRect,
+ const ::rtl::OUString& rMovedElementName,
+ const ::Rectangle& rMovedElementRect )
+{
+ SingleRowColumnWindowData aRowColumnWindowData;
+
+ sal_Bool bHorzDockArea( isHorizontalDockingArea( eDockingArea ));
+ implts_getDockingAreaElementInfoOnSingleRowCol( eDockingArea, nRowCol, aRowColumnWindowData );
+ if ( aRowColumnWindowData.aRowColumnWindows.empty() )
+ return rMovedElementRect;
+ else
+ {
+ sal_Int32 nSpace( 0 );
+ ::Rectangle aFrontDockingRect( rMovedElementRect );
+ const sal_uInt32 nCount = aRowColumnWindowData.aRowColumnWindows.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ if ( bHorzDockArea )
+ {
+ if ( aRowColumnWindowData.aRowColumnWindowSizes[i].X >= rDockedElementRect.Left() )
+ {
+ nSpace += aRowColumnWindowData.aRowColumnSpace[i];
+ break;
+ }
+ else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName )
+ nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Width +
+ aRowColumnWindowData.aRowColumnSpace[i];
+ else
+ nSpace = 0;
+ }
+ else
+ {
+ if ( aRowColumnWindowData.aRowColumnWindowSizes[i].Y >= rDockedElementRect.Top() )
+ {
+ nSpace += aRowColumnWindowData.aRowColumnSpace[i];
+ break;
+ }
+ else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName )
+ nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Height +
+ aRowColumnWindowData.aRowColumnSpace[i];
+ else
+ nSpace = 0;
+ }
+ }
+
+ if ( nSpace > 0 )
+ {
+ sal_Int32 nMove = std::min( nSpace, static_cast<sal_Int32>(aFrontDockingRect.getWidth()) );
+ if ( bHorzDockArea )
+ aFrontDockingRect.Move( -nMove, 0 );
+ else
+ aFrontDockingRect.Move( 0, -nMove );
+ }
+
+ return aFrontDockingRect;
+ }
+}
+
+void ToolbarLayoutManager::implts_findNextDockingPos( ui::DockingArea DockingArea, const ::Size& aUIElementSize, ::Point& rVirtualPos, ::Point& rPixelPos )
+{
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< awt::XWindow > xDockingWindow( m_xDockAreaWindows[DockingArea] );
+ ::Size aDockingWinSize;
+ Window* pDockingWindow( 0 );
+ aReadLock.unlock();
+
+ if (( DockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
+ DockingArea = ui::DockingArea_DOCKINGAREA_TOP;
+
+ {
+ // Retrieve output size from container Window
+ SolarMutexGuard aGuard;
+ pDockingWindow = VCLUnoHelper::GetWindow( xDockingWindow );
+ if ( pDockingWindow )
+ aDockingWinSize = pDockingWindow->GetOutputSizePixel();
+ }
+
+ sal_Int32 nFreeRowColPixelPos( 0 );
+ sal_Int32 nMaxSpace( 0 );
+ sal_Int32 nNeededSpace( 0 );
+ sal_Int32 nTopDockingAreaSize( 0 );
+
+ if ( isHorizontalDockingArea( DockingArea ))
+ {
+ nMaxSpace = aDockingWinSize.Width();
+ nNeededSpace = aUIElementSize.Width();
+ }
+ else
+ {
+ nMaxSpace = aDockingWinSize.Height();
+ nNeededSpace = aUIElementSize.Height();
+ nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width();
+ }
+
+ std::vector< SingleRowColumnWindowData > aRowColumnsWindowData;
+
+ implts_getDockingAreaElementInfos( DockingArea, aRowColumnsWindowData );
+ sal_Int32 nPixelPos( 0 );
+ const sal_uInt32 nCount = aRowColumnsWindowData.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ SingleRowColumnWindowData& rRowColumnWindowData = aRowColumnsWindowData[i];
+
+ if (( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) ||
+ ( DockingArea == ui::DockingArea_DOCKINGAREA_RIGHT ))
+ nPixelPos += rRowColumnWindowData.nStaticSize;
+
+ if ((( nMaxSpace - rRowColumnWindowData.nVarSize ) >= nNeededSpace ) ||
+ ( rRowColumnWindowData.nSpace >= nNeededSpace ))
+ {
+ // Check current row where we can find the needed space
+ sal_Int32 nCurrPos( 0 );
+ const sal_uInt32 nWindowSizesCount = rRowColumnWindowData.aRowColumnWindowSizes.size();
+ for ( sal_uInt32 j = 0; j < nWindowSizesCount; j++ )
+ {
+ awt::Rectangle rRect = rRowColumnWindowData.aRowColumnWindowSizes[j];
+ sal_Int32& rSpace = rRowColumnWindowData.aRowColumnSpace[j];
+ if ( isHorizontalDockingArea( DockingArea ))
+ {
+ if ( rSpace >= nNeededSpace )
+ {
+ rVirtualPos = ::Point( nCurrPos, rRowColumnWindowData.nRowColumn );
+ if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP )
+ rPixelPos = ::Point( nCurrPos, nPixelPos );
+ else
+ rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos );
+ return;
+ }
+ nCurrPos = rRect.X + rRect.Width;
+ }
+ else
+ {
+ if ( rSpace >= nNeededSpace )
+ {
+ rVirtualPos = ::Point( rRowColumnWindowData.nRowColumn, nCurrPos );
+ if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
+ rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos );
+ else
+ rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos );
+ return;
+ }
+ nCurrPos = rRect.Y + rRect.Height;
+ }
+ }
+
+ if (( nCurrPos + nNeededSpace ) <= nMaxSpace )
+ {
+ if ( isHorizontalDockingArea( DockingArea ))
+ {
+ rVirtualPos = ::Point( nCurrPos, rRowColumnWindowData.nRowColumn );
+ if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP )
+ rPixelPos = ::Point( nCurrPos, nPixelPos );
+ else
+ rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos );
+ return;
+ }
+ else
+ {
+ rVirtualPos = ::Point( rRowColumnWindowData.nRowColumn, nCurrPos );
+ if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
+ rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos );
+ else
+ rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos );
+ return;
+ }
+ }
+ }
+
+ if (( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ))
+ nPixelPos += rRowColumnWindowData.nStaticSize;
+ }
+
+ sal_Int32 nNextFreeRowCol( 0 );
+ sal_Int32 nRowColumnsCount = aRowColumnsWindowData.size();
+ if ( nRowColumnsCount > 0 )
+ nNextFreeRowCol = aRowColumnsWindowData[nRowColumnsCount-1].nRowColumn+1;
+ else
+ nNextFreeRowCol = 0;
+
+ if ( nNextFreeRowCol == 0 )
+ {
+ if ( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
+ nFreeRowColPixelPos = aDockingWinSize.Height() - aUIElementSize.Height();
+ else if ( DockingArea == ui::DockingArea_DOCKINGAREA_RIGHT )
+ nFreeRowColPixelPos = aDockingWinSize.Width() - aUIElementSize.Width();
+ }
+
+ if ( isHorizontalDockingArea( DockingArea ))
+ {
+ rVirtualPos = ::Point( 0, nNextFreeRowCol );
+ if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP )
+ rPixelPos = ::Point( 0, nFreeRowColPixelPos );
+ else
+ rPixelPos = ::Point( 0, aDockingWinSize.Height() - nFreeRowColPixelPos );
+ }
+ else
+ {
+ rVirtualPos = ::Point( nNextFreeRowCol, 0 );
+ rPixelPos = ::Point( aDockingWinSize.Width() - nFreeRowColPixelPos, 0 );
+ }
+}
+
+void ToolbarLayoutManager::implts_calcWindowPosSizeOnSingleRowColumn(
+ sal_Int32 nDockingArea,
+ sal_Int32 nOffset,
+ SingleRowColumnWindowData& rRowColumnWindowData,
+ const ::Size& rContainerSize )
+{
+ sal_Int32 nDiff(0);
+ sal_Int32 nRCSpace( rRowColumnWindowData.nSpace );
+ sal_Int32 nTopDockingAreaSize(0);
+ sal_Int32 nBottomDockingAreaSize(0);
+ sal_Int32 nContainerClientSize(0);
+
+ if ( rRowColumnWindowData.aRowColumnWindows.empty() )
+ return;
+
+ if ( isHorizontalDockingArea( nDockingArea ))
+ {
+ nContainerClientSize = rContainerSize.Width();
+ nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize;
+ }
+ else
+ {
+ nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width();
+ nBottomDockingAreaSize = implts_getTopBottomDockingAreaSizes().Height();
+ nContainerClientSize = ( rContainerSize.Height() - nTopDockingAreaSize - nBottomDockingAreaSize );
+ nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize;
+ }
+
+ const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindowSizes.size();
+ if (( nDiff < 0 ) && ( nRCSpace > 0 ))
+ {
+ // First we try to reduce the size of blank space before/behind docked windows
+ sal_Int32 i = nCount - 1;
+ while ( i >= 0 )
+ {
+ sal_Int32 nSpace = rRowColumnWindowData.aRowColumnSpace[i];
+ if ( nSpace >= -nDiff )
+ {
+ if ( isHorizontalDockingArea( nDockingArea ))
+ {
+ // Try to move this and all user elements behind with the calculated difference
+ for ( sal_uInt32 j = i; j < nCount ; j++ )
+ rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff;
+ }
+ else
+ {
+ // Try to move this and all user elements behind with the calculated difference
+ for ( sal_uInt32 j = i; j < nCount ; j++ )
+ rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff;
+ }
+ nDiff = 0;
+
+ break;
+ }
+ else if ( nSpace > 0 )
+ {
+ if ( isHorizontalDockingArea( nDockingArea ))
+ {
+ // Try to move this and all user elements behind with the calculated difference
+ for ( sal_uInt32 j = i; j < nCount; j++ )
+ rRowColumnWindowData.aRowColumnWindowSizes[j].X -= nSpace;
+ }
+ else
+ {
+ // Try to move this and all user elements behind with the calculated difference
+ for ( sal_uInt32 j = i; j < nCount; j++ )
+ rRowColumnWindowData.aRowColumnWindowSizes[j].Y -= nSpace;
+ }
+ nDiff += nSpace;
+ }
+ --i;
+ }
+ }
+
+ // Check if we have to reduce further
+ if ( nDiff < 0 )
+ {
+ // Now we have to reduce the size of certain docked windows
+ sal_Int32 i = sal_Int32( nCount - 1 );
+ while ( i >= 0 )
+ {
+ awt::Rectangle& rWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i];
+ ::Size aMinSize;
+
+ SolarMutexGuard aGuard;
+ {
+ uno::Reference< awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i];
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
+ aMinSize = ((ToolBox *)pWindow)->CalcMinimumWindowSizePixel();
+ }
+
+ if (( aMinSize.Width() > 0 ) && ( aMinSize.Height() > 0 ))
+ {
+ if ( isHorizontalDockingArea( nDockingArea ))
+ {
+ sal_Int32 nMaxReducation = ( rWinRect.Width - aMinSize.Width() );
+ if ( nMaxReducation >= -nDiff )
+ {
+ rWinRect.Width = rWinRect.Width + nDiff;
+ nDiff = 0;
+ }
+ else
+ {
+ rWinRect.Width = aMinSize.Width();
+ nDiff += nMaxReducation;
+ }
+
+ // Try to move this and all user elements behind with the calculated difference
+ for ( sal_uInt32 j = i; j < nCount; j++ )
+ rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff;
+ }
+ else
+ {
+ sal_Int32 nMaxReducation = ( rWinRect.Height - aMinSize.Height() );
+ if ( nMaxReducation >= -nDiff )
+ {
+ rWinRect.Height = rWinRect.Height + nDiff;
+ nDiff = 0;
+ }
+ else
+ {
+ rWinRect.Height = aMinSize.Height();
+ nDiff += nMaxReducation;
+ }
+
+ // Try to move this and all user elements behind with the calculated difference
+ for ( sal_uInt32 j = i; j < nCount; j++ )
+ rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff;
+ }
+ }
+
+ if ( nDiff >= 0 )
+ break;
+
+ --i;
+ }
+ }
+
+ ReadGuard aReadLock( m_aLock );
+ Window* pDockAreaWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[nDockingArea] );
+ aReadLock.unlock();
+
+ sal_Int32 nCurrPos( 0 );
+
+ SolarMutexGuard aGuard;
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ uno::Reference< awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i];
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ Window* pOldParentWindow = pWindow->GetParent();
+
+ if ( pDockAreaWindow != pOldParentWindow )
+ pWindow->SetParent( pDockAreaWindow );
+
+ awt::Rectangle aWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i];
+ if ( isHorizontalDockingArea( nDockingArea ))
+ {
+ if ( aWinRect.X < nCurrPos )
+ aWinRect.X = nCurrPos;
+ pWindow->SetPosSizePixel( ::Point( aWinRect.X, nOffset ), ::Size( aWinRect.Width, rRowColumnWindowData.nStaticSize ));
+ pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ nCurrPos += ( aWinRect.X - nCurrPos ) + aWinRect.Width;
+ }
+ else
+ {
+ if ( aWinRect.Y < nCurrPos )
+ aWinRect.Y = nCurrPos;
+ pWindow->SetPosSizePixel( ::Point( nOffset, aWinRect.Y ), ::Size( rRowColumnWindowData.nStaticSize, aWinRect.Height ));
+ pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ nCurrPos += ( aWinRect.Y - nCurrPos ) + aWinRect.Height;
+ }
+ }
+}
+
+void ToolbarLayoutManager::implts_setLayoutDirty()
+{
+ WriteGuard aWriteLock( m_aLock );
+ m_bLayoutDirty = true;
+}
+
+void ToolbarLayoutManager::implts_setLayoutInProgress( bool bInProgress )
+{
+ WriteGuard aWriteLock( m_aLock );
+ m_bLayoutInProgress = bInProgress;
+}
+
+::Rectangle ToolbarLayoutManager::implts_calcHotZoneRect( const ::Rectangle& rRect, sal_Int32 nHotZoneOffset )
+{
+ ::Rectangle aRect( rRect );
+
+ aRect.Left() -= nHotZoneOffset;
+ aRect.Top() -= nHotZoneOffset;
+ aRect.Right() += nHotZoneOffset;
+ aRect.Bottom() += nHotZoneOffset;
+
+ return aRect;
+}
+
+void ToolbarLayoutManager::implts_calcDockingPosSize(
+ UIElement& rUIElement,
+ DockingOperation& rDockingOperation,
+ ::Rectangle& rTrackingRect,
+ const Point& rMousePos )
+{
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
+ ::Size aContainerWinSize;
+ Window* pContainerWindow( 0 );
+ ::Rectangle aDockingAreaOffsets( m_aDockingAreaOffsets );
+ aReadLock.unlock();
+
+ if ( !rUIElement.m_xUIElement.is() )
+ {
+ rTrackingRect = ::Rectangle();
+ return;
+ }
+
+ {
+ // Retrieve output size from container Window
+ SolarMutexGuard aGuard;
+ pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ aContainerWinSize = pContainerWindow->GetOutputSizePixel();
+ }
+
+ Window* pDockWindow( 0 );
+ Window* pDockingAreaWindow( 0 );
+ ToolBox* pToolBox( 0 );
+ uno::Reference< awt::XWindow > xWindow( rUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
+ uno::Reference< awt::XWindow > xDockingAreaWindow;
+ ::Rectangle aTrackingRect( rTrackingRect );
+ ui::DockingArea eDockedArea( (ui::DockingArea)rUIElement.m_aDockedData.m_nDockedArea );
+ sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() );
+ sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() );
+ bool bHorizontalDockArea(( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) ||
+ ( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ));
+ sal_Int32 nMaxLeftRightDockAreaSize = aContainerWinSize.Height() -
+ nTopDockingAreaSize -
+ nBottomDockingAreaSize -
+ aDockingAreaOffsets.Top() -
+ aDockingAreaOffsets.Bottom();
+ ::Rectangle aDockingAreaRect;
+
+ aReadLock.lock();
+ xDockingAreaWindow = m_xDockAreaWindows[eDockedArea];
+ aReadLock.unlock();
+
+ {
+ SolarMutexGuard aGuard;
+ pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow );
+ pDockWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pDockWindow && pDockWindow->GetType() == WINDOW_TOOLBOX )
+ pToolBox = (ToolBox *)pDockWindow;
+
+ aDockingAreaRect = ::Rectangle( pDockingAreaWindow->GetPosPixel(), pDockingAreaWindow->GetSizePixel() );
+ if ( pToolBox )
+ {
+ // docked toolbars always have one line
+ ::Size aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( sal_Int16( eDockedArea )) );
+ aTrackingRect.SetSize( ::Size( aSize.Width(), aSize.Height() ));
+ }
+ }
+
+ // default docking operation, dock on the given row/column
+ bool bOpOutsideOfDockingArea( !aDockingAreaRect.IsInside( rMousePos ));
+ std::vector< SingleRowColumnWindowData > aRowColumnsWindowData;
+
+ rDockingOperation = DOCKOP_ON_COLROW;
+ implts_getDockingAreaElementInfos( eDockedArea, aRowColumnsWindowData );
+
+ // determine current first row/column and last row/column
+ sal_Int32 nMaxRowCol( -1 );
+ sal_Int32 nMinRowCol( SAL_MAX_INT32 );
+ const sal_uInt32 nCount = aRowColumnsWindowData.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ if ( aRowColumnsWindowData[i].nRowColumn > nMaxRowCol )
+ nMaxRowCol = aRowColumnsWindowData[i].nRowColumn;
+ if ( aRowColumnsWindowData[i].nRowColumn < nMinRowCol )
+ nMinRowCol = aRowColumnsWindowData[i].nRowColumn;
+ }
+
+ if ( !bOpOutsideOfDockingArea )
+ {
+ // docking inside our docking area
+ sal_Int32 nIndex( -1 );
+ sal_Int32 nRowCol( -1 );
+ ::Rectangle aWindowRect;
+ ::Rectangle aRowColumnRect;
+
+ const sal_uInt32 nWindowDataCount = aRowColumnsWindowData.size();
+ for ( sal_uInt32 i = 0; i < nWindowDataCount; i++ )
+ {
+ ::Rectangle aRect( aRowColumnsWindowData[i].aRowColumnRect.X,
+ aRowColumnsWindowData[i].aRowColumnRect.Y,
+ aRowColumnsWindowData[i].aRowColumnRect.X + aRowColumnsWindowData[i].aRowColumnRect.Width,
+ aRowColumnsWindowData[i].aRowColumnRect.Y + aRowColumnsWindowData[i].aRowColumnRect.Height );
+
+ {
+ // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect
+ SolarMutexGuard aGuard;
+ aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() )));
+ }
+
+ bool bIsInsideRowCol( aRect.IsInside( rMousePos ) );
+ if ( bIsInsideRowCol )
+ {
+ nIndex = i;
+ nRowCol = aRowColumnsWindowData[i].nRowColumn;
+ rDockingOperation = implts_determineDockingOperation( eDockedArea, aRect, rMousePos );
+ aWindowRect = implts_getWindowRectFromRowColumn( eDockedArea, aRowColumnsWindowData[i], rMousePos, rUIElement.m_aName );
+ aRowColumnRect = aRect;
+ break;
+ }
+ }
+
+ OSL_ENSURE( ( nIndex >= 0 ) && ( nRowCol >= 0 ), "Impossible case - no row/column found but mouse pointer is inside our docking area" );
+ if (( nIndex >= 0 ) && ( nRowCol >= 0 ))
+ {
+ if ( rDockingOperation == DOCKOP_ON_COLROW )
+ {
+ if ( !aWindowRect.IsEmpty())
+ {
+ // Tracking rect is on a row/column and mouse is over a docked toolbar.
+ // Determine if the tracking rect must be located before/after the docked toolbar.
+
+ ::Rectangle aUIElementRect( aWindowRect );
+ sal_Int32 nMiddle( bHorizontalDockArea ? ( aWindowRect.Left() + aWindowRect.getWidth() / 2 ) :
+ ( aWindowRect.Top() + aWindowRect.getHeight() / 2 ));
+ sal_Bool bInsertBefore( bHorizontalDockArea ? ( rMousePos.X() < nMiddle ) : ( rMousePos.Y() < nMiddle ));
+ if ( bInsertBefore )
+ {
+ if ( bHorizontalDockArea )
+ {
+ sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( aContainerWinSize.Width() - aWindowRect.Left() ),
+ sal_Int32( aTrackingRect.getWidth() )));
+ if ( nSize == 0 )
+ nSize = aWindowRect.getWidth();
+
+ aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() ));
+ aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect,rUIElement.m_aName, aUIElementRect );
+
+ // Set virtual position
+ rUIElement.m_aDockedData.m_aPos.X() = aWindowRect.Left();
+ rUIElement.m_aDockedData.m_aPos.Y() = nRowCol;
+ }
+ else
+ {
+ sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(
+ nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Top() ),
+ sal_Int32( aTrackingRect.getHeight() )));
+ if ( nSize == 0 )
+ nSize = aWindowRect.getHeight();
+
+ aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize ));
+ aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect, rUIElement.m_aName, aUIElementRect );
+
+ // Set virtual position
+ sal_Int32 nPosY = pDockingAreaWindow->ScreenToOutputPixel(
+ pContainerWindow->OutputToScreenPixel( aWindowRect.TopLeft() )).Y();
+ rUIElement.m_aDockedData.m_aPos.X() = nRowCol;
+ rUIElement.m_aDockedData.m_aPos.Y() = nPosY;
+ }
+
+ rTrackingRect = aWindowRect;
+ return;
+ }
+ else
+ {
+ if ( bHorizontalDockArea )
+ {
+ sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(( aContainerWinSize.Width() ) - aWindowRect.Right() ),
+ sal_Int32( aTrackingRect.getWidth() )));
+ if ( nSize == 0 )
+ {
+ aUIElementRect.SetPos( ::Point( aContainerWinSize.Width() - aTrackingRect.getWidth(), aWindowRect.Top() ));
+ aUIElementRect.SetSize( ::Size( aTrackingRect.getWidth(), aWindowRect.getHeight() ));
+ rUIElement.m_aDockedData.m_aPos.X() = aUIElementRect.Left();
+ }
+ else
+ {
+ aUIElementRect.SetPos( ::Point( aWindowRect.Right(), aWindowRect.Top() ));
+ aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() ));
+ rUIElement.m_aDockedData.m_aPos.X() = aWindowRect.Right();
+ }
+
+ // Set virtual position
+ rUIElement.m_aDockedData.m_aPos.Y() = nRowCol;
+ }
+ else
+ {
+ sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Bottom() ),
+ sal_Int32( aTrackingRect.getHeight() )));
+ aUIElementRect.SetPos( ::Point( aWindowRect.Left(), aWindowRect.Bottom() ));
+ aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize ));
+
+ // Set virtual position
+ sal_Int32 nPosY( 0 );
+ {
+ SolarMutexGuard aGuard;
+ nPosY = pDockingAreaWindow->ScreenToOutputPixel(
+ pContainerWindow->OutputToScreenPixel( aWindowRect.BottomRight() )).Y();
+ }
+ rUIElement.m_aDockedData.m_aPos.X() = nRowCol;
+ rUIElement.m_aDockedData.m_aPos.Y() = nPosY;
+ }
+
+ rTrackingRect = aUIElementRect;
+ return;
+ }
+ }
+ else
+ {
+ implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect );
+ rTrackingRect = implts_calcTrackingAndElementRect(
+ eDockedArea, nRowCol, rUIElement,
+ aTrackingRect, aRowColumnRect, aContainerWinSize );
+ return;
+ }
+ }
+ else
+ {
+ if ((( nRowCol == nMinRowCol ) && ( rDockingOperation == DOCKOP_BEFORE_COLROW )) ||
+ (( nRowCol == nMaxRowCol ) && ( rDockingOperation == DOCKOP_AFTER_COLROW )))
+ bOpOutsideOfDockingArea = true;
+ else
+ {
+ // handle docking before/after a row
+ implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect );
+ rTrackingRect = implts_calcTrackingAndElementRect(
+ eDockedArea, nRowCol, rUIElement,
+ aTrackingRect, aRowColumnRect, aContainerWinSize );
+
+ sal_Int32 nOffsetX( 0 );
+ sal_Int32 nOffsetY( 0 );
+ if ( bHorizontalDockArea )
+ nOffsetY = sal_Int32( floor( aRowColumnRect.getHeight() / 2 + 0.5 ));
+ else
+ nOffsetX = sal_Int32( floor( aRowColumnRect.getWidth() / 2 + 0.5 ));
+
+ if ( rDockingOperation == DOCKOP_BEFORE_COLROW )
+ {
+ if (( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT ))
+ {
+ // Docking before/after means move track rectangle half column/row.
+ // As left and top are ordered 0...n instead of right and bottom
+ // which uses n...0, we have to use negative values for top/left.
+ nOffsetX *= -1;
+ nOffsetY *= -1;
+ }
+ }
+ else
+ {
+ if (( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) || ( eDockedArea == ui::DockingArea_DOCKINGAREA_RIGHT ))
+ {
+ // Docking before/after means move track rectangle half column/row.
+ // As left and top are ordered 0...n instead of right and bottom
+ // which uses n...0, we have to use negative values for top/left.
+ nOffsetX *= -1;
+ nOffsetY *= -1;
+ }
+ nRowCol++;
+ }
+
+ if ( bHorizontalDockArea )
+ rUIElement.m_aDockedData.m_aPos.Y() = nRowCol;
+ else
+ rUIElement.m_aDockedData.m_aPos.X() = nRowCol;
+
+ rTrackingRect.Move( nOffsetX, nOffsetY );
+ rTrackingRect.SetSize( aTrackingRect.GetSize() );
+ }
+ }
+ }
+ }
+
+ // Docking outside of our docking window area =>
+ // Users want to dock before/after first/last docked element or to an empty docking area
+ if ( bOpOutsideOfDockingArea )
+ {
+ // set correct size for docking
+ implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect );
+ rTrackingRect = aTrackingRect;
+
+ if ( bHorizontalDockArea )
+ {
+ sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 )));
+ if (( nPosX + rTrackingRect.getWidth()) > aContainerWinSize.Width() )
+ nPosX = std::min( nPosX,
+ std::max( sal_Int32( aContainerWinSize.Width() - rTrackingRect.getWidth() ),
+ sal_Int32( 0 )));
+
+ sal_Int32 nSize = std::min( aContainerWinSize.Width(), rTrackingRect.getWidth() );
+ sal_Int32 nDockHeight = std::max( static_cast<sal_Int32>(aDockingAreaRect.getHeight()), sal_Int32( 0 ));
+ if ( nDockHeight == 0 )
+ {
+ sal_Int32 nPosY( std::max( aDockingAreaRect.Top(), aDockingAreaRect.Bottom() ));
+ if ( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
+ nPosY -= rTrackingRect.getHeight();
+ rTrackingRect.SetPos( Point( nPosX, nPosY ));
+ rUIElement.m_aDockedData.m_aPos.Y() = 0;
+ }
+ else if ( rMousePos.Y() < ( aDockingAreaRect.Top() + ( nDockHeight / 2 )))
+ {
+ rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Top() - rTrackingRect.getHeight() ));
+ if ( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP )
+ rUIElement.m_aDockedData.m_aPos.Y() = 0;
+ else
+ rUIElement.m_aDockedData.m_aPos.Y() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
+ rDockingOperation = DOCKOP_BEFORE_COLROW;
+ }
+ else
+ {
+ rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Bottom() ));
+ if ( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP )
+ rUIElement.m_aDockedData.m_aPos.Y() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
+ else
+ rUIElement.m_aDockedData.m_aPos.Y() = 0;
+ rDockingOperation = DOCKOP_AFTER_COLROW;
+ }
+ rTrackingRect.setWidth( nSize );
+
+ {
+ SolarMutexGuard aGuard;
+ nPosX = pDockingAreaWindow->ScreenToOutputPixel(
+ pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).X();
+ }
+ rUIElement.m_aDockedData.m_aPos.X() = nPosX;
+ }
+ else
+ {
+ sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ), sal_Int32( nMaxLeftRightDockAreaSize ));
+ sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize )));
+ if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight ))
+ nPosY = std::min( nPosY,
+ std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )),
+ sal_Int32( nTopDockingAreaSize )));
+
+ sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) );
+ sal_Int32 nDockWidth = std::max( static_cast<sal_Int32>(aDockingAreaRect.getWidth()), sal_Int32( 0 ));
+ if ( nDockWidth == 0 )
+ {
+ sal_Int32 nPosX( std::max( aDockingAreaRect.Left(), aDockingAreaRect.Right() ));
+ if ( eDockedArea == ui::DockingArea_DOCKINGAREA_RIGHT )
+ nPosX -= rTrackingRect.getWidth();
+ rTrackingRect.SetPos( Point( nPosX, nPosY ));
+ rUIElement.m_aDockedData.m_aPos.X() = 0;
+ }
+ else if ( rMousePos.X() < ( aDockingAreaRect.Left() + ( nDockWidth / 2 )))
+ {
+ rTrackingRect.SetPos( Point( aDockingAreaRect.Left() - rTrackingRect.getWidth(), nPosY ));
+ if ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )
+ rUIElement.m_aDockedData.m_aPos.X() = 0;
+ else
+ rUIElement.m_aDockedData.m_aPos.X() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
+ rDockingOperation = DOCKOP_BEFORE_COLROW;
+ }
+ else
+ {
+ rTrackingRect.SetPos( Point( aDockingAreaRect.Right(), nPosY ));
+ if ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )
+ rUIElement.m_aDockedData.m_aPos.X() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
+ else
+ rUIElement.m_aDockedData.m_aPos.X() = 0;
+ rDockingOperation = DOCKOP_AFTER_COLROW;
+ }
+ rTrackingRect.setHeight( nSize );
+
+ {
+ SolarMutexGuard aGuard;
+ nPosY = pDockingAreaWindow->ScreenToOutputPixel(
+ pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).Y();
+ }
+ rUIElement.m_aDockedData.m_aPos.Y() = nPosY;
+ }
+ }
+}
+
+framework::ToolbarLayoutManager::DockingOperation ToolbarLayoutManager::implts_determineDockingOperation(
+ ui::DockingArea DockingArea,
+ const ::Rectangle& rRowColRect,
+ const Point& rMousePos )
+{
+ const sal_Int32 nHorzVerticalRegionSize = 6;
+ const sal_Int32 nHorzVerticalMoveRegion = 4;
+
+ if ( rRowColRect.IsInside( rMousePos ))
+ {
+ if ( isHorizontalDockingArea( DockingArea ))
+ {
+ sal_Int32 nRegion = rRowColRect.getHeight() / nHorzVerticalRegionSize;
+ sal_Int32 nPosY = rRowColRect.Top() + nRegion;
+
+ if ( rMousePos.Y() < nPosY )
+ return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW;
+ else if ( rMousePos.Y() < ( nPosY + nRegion*nHorzVerticalMoveRegion ))
+ return DOCKOP_ON_COLROW;
+ else
+ return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW;
+ }
+ else
+ {
+ sal_Int32 nRegion = rRowColRect.getWidth() / nHorzVerticalRegionSize;
+ sal_Int32 nPosX = rRowColRect.Left() + nRegion;
+
+ if ( rMousePos.X() < nPosX )
+ return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW;
+ else if ( rMousePos.X() < ( nPosX + nRegion*nHorzVerticalMoveRegion ))
+ return DOCKOP_ON_COLROW;
+ else
+ return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW;
+ }
+ }
+ else
+ return DOCKOP_ON_COLROW;
+}
+
+::Rectangle ToolbarLayoutManager::implts_calcTrackingAndElementRect(
+ ui::DockingArea eDockingArea,
+ sal_Int32 nRowCol,
+ UIElement& rUIElement,
+ const ::Rectangle& rTrackingRect,
+ const ::Rectangle& rRowColumnRect,
+ const ::Size& rContainerWinSize )
+{
+ ReadGuard aReadGuard( m_aLock );
+ ::Rectangle aDockingAreaOffsets( m_aDockingAreaOffsets );
+ aReadGuard.unlock();
+
+ bool bHorizontalDockArea( isHorizontalDockingArea( eDockingArea ));
+ sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() );
+ sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() );
+
+ sal_Int32 nMaxLeftRightDockAreaSize = rContainerWinSize.Height() -
+ nTopDockingAreaSize -
+ nBottomDockingAreaSize -
+ aDockingAreaOffsets.Top() -
+ aDockingAreaOffsets.Bottom();
+
+ ::Rectangle aTrackingRect( rTrackingRect );
+ if ( bHorizontalDockArea )
+ {
+ sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 )));
+ if (( nPosX + rTrackingRect.getWidth()) > rContainerWinSize.Width() )
+ nPosX = std::min( nPosX,
+ std::max( sal_Int32( rContainerWinSize.Width() - rTrackingRect.getWidth() ),
+ sal_Int32( 0 )));
+
+ sal_Int32 nSize = std::min( rContainerWinSize.Width(), rTrackingRect.getWidth() );
+
+ aTrackingRect.SetPos( ::Point( nPosX, rRowColumnRect.Top() ));
+ aTrackingRect.setWidth( nSize );
+ aTrackingRect.setHeight( rRowColumnRect.getHeight() );
+
+ // Set virtual position
+ rUIElement.m_aDockedData.m_aPos.X() = nPosX;
+ rUIElement.m_aDockedData.m_aPos.Y() = nRowCol;
+ }
+ else
+ {
+ sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ),
+ sal_Int32( nMaxLeftRightDockAreaSize ));
+
+ sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize )));
+ if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight ))
+ nPosY = std::min( nPosY,
+ std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )),
+ sal_Int32( nTopDockingAreaSize )));
+
+ sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) );
+
+ aTrackingRect.SetPos( ::Point( rRowColumnRect.Left(), nPosY ));
+ aTrackingRect.setWidth( rRowColumnRect.getWidth() );
+ aTrackingRect.setHeight( nSize );
+
+ aReadGuard.lock();
+ uno::Reference< awt::XWindow > xDockingAreaWindow( m_xDockAreaWindows[eDockingArea] );
+ uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
+ aReadGuard.unlock();
+
+ sal_Int32 nDockPosY( 0 );
+ Window* pDockingAreaWindow( 0 );
+ Window* pContainerWindow( 0 );
+ {
+ SolarMutexGuard aGuard;
+ pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow );
+ pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ nDockPosY = pDockingAreaWindow->ScreenToOutputPixel( pContainerWindow->OutputToScreenPixel( ::Point( 0, nPosY ))).Y();
+ }
+
+ // Set virtual position
+ rUIElement.m_aDockedData.m_aPos.X() = nRowCol;
+ rUIElement.m_aDockedData.m_aPos.Y() = nDockPosY;
+ }
+
+ return aTrackingRect;
+}
+
+void ToolbarLayoutManager::implts_setTrackingRect( ui::DockingArea eDockingArea, const ::Point& rMousePos, ::Rectangle& rTrackingRect )
+{
+ ::Point aPoint( rTrackingRect.TopLeft());
+ if ( isHorizontalDockingArea( eDockingArea ))
+ aPoint.X() = rMousePos.X();
+ else
+ aPoint.Y() = rMousePos.Y();
+ rTrackingRect.SetPos( aPoint );
+}
+
+void ToolbarLayoutManager::implts_renumberRowColumnData(
+ ui::DockingArea eDockingArea,
+ DockingOperation /*eDockingOperation*/,
+ const UIElement& rUIElement )
+{
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
+ aReadLock.unlock();
+
+ bool bHorzDockingArea( isHorizontalDockingArea( eDockingArea ));
+ sal_Int32 nRowCol( bHorzDockingArea ? rUIElement.m_aDockedData.m_aPos.Y() : rUIElement.m_aDockedData.m_aPos.X() );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ UIElementVector::iterator pIter;
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ if (( pIter->m_aDockedData.m_nDockedArea == sal_Int16( eDockingArea )) && ( pIter->m_aName != rUIElement.m_aName ))
+ {
+ // Don't change toolbars without a valid docking position!
+ if ( isDefaultPos( pIter->m_aDockedData.m_aPos ))
+ continue;
+
+ sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? pIter->m_aDockedData.m_aPos.Y() : pIter->m_aDockedData.m_aPos.X();
+ if ( nWindowRowCol >= nRowCol )
+ {
+ if ( bHorzDockingArea )
+ pIter->m_aDockedData.m_aPos.Y() += 1;
+ else
+ pIter->m_aDockedData.m_aPos.X() += 1;
+ }
+ }
+ }
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ // We have to change the persistent window state part
+ if ( xPersistentWindowState.is() )
+ {
+ try
+ {
+ uno::Sequence< ::rtl::OUString > aWindowElements = xPersistentWindowState->getElementNames();
+ for ( sal_Int32 i = 0; i < aWindowElements.getLength(); i++ )
+ {
+ if ( rUIElement.m_aName != aWindowElements[i] )
+ {
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq;
+ awt::Point aDockedPos;
+ ui::DockingArea nDockedArea( ui::DockingArea_DOCKINGAREA_DEFAULT );
+
+ xPersistentWindowState->getByName( aWindowElements[i] ) >>= aPropValueSeq;
+ for ( sal_Int32 j = 0; j < aPropValueSeq.getLength(); j++ )
+ {
+ if ( aPropValueSeq[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKINGAREA ))
+ aPropValueSeq[j].Value >>= nDockedArea;
+ else if ( aPropValueSeq[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKPOS ))
+ aPropValueSeq[j].Value >>= aDockedPos;
+ }
+
+ // Don't change toolbars without a valid docking position!
+ if ( isDefaultPos( aDockedPos ))
+ continue;
+
+ sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? aDockedPos.Y : aDockedPos.X;
+ if (( nDockedArea == eDockingArea ) && ( nWindowRowCol >= nRowCol ))
+ {
+ if ( bHorzDockingArea )
+ aDockedPos.Y += 1;
+ else
+ aDockedPos.X += 1;
+
+ uno::Reference< container::XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY );
+ xReplace->replaceByName( aWindowElements[i], makeAny( aPropValueSeq ));
+ }
+ }
+ catch ( uno::Exception& ) {}
+ }
+ }
+ }
+ catch ( uno::Exception& ) {}
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XWindowListener
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL ToolbarLayoutManager::windowResized( const awt::WindowEvent& aEvent )
+throw( uno::RuntimeException )
+{
+ WriteGuard aWriteLock( m_aLock );
+ bool bLocked( m_bDockingInProgress );
+ bool bLayoutInProgress( m_bLayoutInProgress );
+ aWriteLock.unlock();
+
+ // Do not do anything if we are in the middle of a docking process. This would interfere all other
+ // operations. We will store the new position and size in the docking handlers.
+ // Do not do anything if we are in the middle of our layouting process. We will adapt the position
+ // and size of the user interface elements.
+ if ( !bLocked && !bLayoutInProgress )
+ {
+ bool bNotify( false );
+ uno::Reference< awt::XWindow > xWindow( aEvent.Source, uno::UNO_QUERY );
+
+ UIElement aUIElement = implts_findToolbar( aEvent.Source );
+ if ( aUIElement.m_xUIElement.is() )
+ {
+ if ( aUIElement.m_bFloating )
+ {
+ uno::Reference< awt::XWindow2 > xWindow2( xWindow, uno::UNO_QUERY );
+
+ if( xWindow2.is() )
+ {
+ awt::Rectangle aPos = xWindow2->getPosSize();
+ awt::Size aSize = xWindow2->getOutputSize(); // always use output size for consistency
+ bool bVisible = xWindow2->isVisible();
+
+ // update element data
+ aUIElement.m_aFloatingData.m_aPos = ::Point( aPos.X, aPos.Y );
+ aUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height );
+ aUIElement.m_bVisible = bVisible;
+ }
+
+ implts_writeWindowStateData( aUIElement );
+ }
+ else
+ {
+ implts_setLayoutDirty();
+ bNotify = true;
+ }
+ }
+
+ if ( bNotify )
+ m_pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
+ }
+}
+
+void SAL_CALL ToolbarLayoutManager::windowMoved( const awt::WindowEvent& /*aEvent*/ )
+throw( uno::RuntimeException )
+{
+}
+
+void SAL_CALL ToolbarLayoutManager::windowShown( const lang::EventObject& /*aEvent*/ )
+throw( uno::RuntimeException )
+{
+}
+
+void SAL_CALL ToolbarLayoutManager::windowHidden( const lang::EventObject& /*aEvent*/ )
+throw( uno::RuntimeException )
+{
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XDockableWindowListener
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL ToolbarLayoutManager::startDocking( const awt::DockingEvent& e )
+throw (uno::RuntimeException)
+{
+ bool bWinFound( false );
+
+ ReadGuard aReadGuard( m_aLock );
+ uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
+ uno::Reference< awt::XWindow2 > xWindow( e.Source, uno::UNO_QUERY );
+ aReadGuard.unlock();
+
+ Window* pContainerWindow( 0 );
+ Window* pWindow( 0 );
+ ::Point aMousePos;
+ {
+ SolarMutexGuard aGuard;
+ pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ aMousePos = pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y ));
+ }
+
+ UIElement aUIElement = implts_findToolbar( e.Source );
+
+ if ( aUIElement.m_xUIElement.is() && xWindow.is() )
+ {
+ awt::Rectangle aRect;
+
+ bWinFound = true;
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+ if ( xDockWindow->isFloating() )
+ {
+ awt::Rectangle aPos = xWindow->getPosSize();
+ awt::Size aSize = xWindow->getOutputSize();
+
+ aUIElement.m_aFloatingData.m_aPos = ::Point( aPos.X, aPos.Y );
+ aUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height );
+
+ SolarMutexGuard aGuard;
+
+ pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
+ {
+ ToolBox* pToolBox = (ToolBox *)pWindow;
+ aUIElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines();
+ aUIElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
+ }
+ }
+ }
+
+ WriteGuard aWriteLock( m_aLock );
+ m_bDockingInProgress = bWinFound;
+ m_aDockUIElement = aUIElement;
+ m_aDockUIElement.m_bUserActive = true;
+ m_aStartDockMousePos = aMousePos;
+ aWriteLock.unlock();
+}
+
+awt::DockingData SAL_CALL ToolbarLayoutManager::docking( const awt::DockingEvent& e )
+throw (uno::RuntimeException)
+{
+ const sal_Int32 MAGNETIC_DISTANCE_UNDOCK = 25;
+ const sal_Int32 MAGNETIC_DISTANCE_DOCK = 20;
+
+ ReadGuard aReadLock( m_aLock );
+ awt::DockingData aDockingData;
+ uno::Reference< awt::XDockableWindow > xDockWindow( e.Source, uno::UNO_QUERY );
+ uno::Reference< awt::XWindow > xWindow( e.Source, uno::UNO_QUERY );
+ uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
+ uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
+ uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
+ uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
+ uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
+ UIElement aUIDockingElement( m_aDockUIElement );
+ DockingOperation eDockingOperation( DOCKOP_ON_COLROW );
+ bool bDockingInProgress( m_bDockingInProgress );
+ aReadLock.unlock();
+
+ if ( bDockingInProgress )
+ aDockingData.TrackingRectangle = e.TrackingRectangle;
+
+ if ( bDockingInProgress && xDockWindow.is() && xWindow.is() )
+ {
+ try
+ {
+ SolarMutexGuard aGuard;
+
+ sal_Int16 eDockingArea( -1 ); // none
+ sal_Int32 nMagneticZone( aUIDockingElement.m_bFloating ? MAGNETIC_DISTANCE_DOCK : MAGNETIC_DISTANCE_UNDOCK );
+ awt::Rectangle aNewTrackingRect;
+ ::Rectangle aTrackingRect( e.TrackingRectangle.X, e.TrackingRectangle.Y,
+ ( e.TrackingRectangle.X + e.TrackingRectangle.Width ),
+ ( e.TrackingRectangle.Y + e.TrackingRectangle.Height ));
+
+ awt::Rectangle aTmpRect = xTopDockingWindow->getPosSize();
+ ::Rectangle aTopDockRect( aTmpRect.X, aTmpRect.Y, aTmpRect.Width, aTmpRect.Height );
+ ::Rectangle aHotZoneTopDockRect( implts_calcHotZoneRect( aTopDockRect, nMagneticZone ));
+
+ aTmpRect = xBottomDockingWindow->getPosSize();
+ ::Rectangle aBottomDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width), ( aTmpRect.Y + aTmpRect.Height ));
+ ::Rectangle aHotZoneBottomDockRect( implts_calcHotZoneRect( aBottomDockRect, nMagneticZone ));
+
+ aTmpRect = xLeftDockingWindow->getPosSize();
+ ::Rectangle aLeftDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height ));
+ ::Rectangle aHotZoneLeftDockRect( implts_calcHotZoneRect( aLeftDockRect, nMagneticZone ));
+
+ aTmpRect = xRightDockingWindow->getPosSize();
+ ::Rectangle aRightDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height ));
+ ::Rectangle aHotZoneRightDockRect( implts_calcHotZoneRect( aRightDockRect, nMagneticZone ));
+
+ Window* pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow ) );
+ ::Point aMousePos( pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y )));
+
+ if ( aHotZoneTopDockRect.IsInside( aMousePos ))
+ eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;
+ else if ( aHotZoneBottomDockRect.IsInside( aMousePos ))
+ eDockingArea = ui::DockingArea_DOCKINGAREA_BOTTOM;
+ else if ( aHotZoneLeftDockRect.IsInside( aMousePos ))
+ eDockingArea = ui::DockingArea_DOCKINGAREA_LEFT;
+ else if ( aHotZoneRightDockRect.IsInside( aMousePos ))
+ eDockingArea = ui::DockingArea_DOCKINGAREA_RIGHT;
+
+ // Higher priority for movements inside the real docking area
+ if ( aTopDockRect.IsInside( aMousePos ))
+ eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;
+ else if ( aBottomDockRect.IsInside( aMousePos ))
+ eDockingArea = ui::DockingArea_DOCKINGAREA_BOTTOM;
+ else if ( aLeftDockRect.IsInside( aMousePos ))
+ eDockingArea = ui::DockingArea_DOCKINGAREA_LEFT;
+ else if ( aRightDockRect.IsInside( aMousePos ))
+ eDockingArea = ui::DockingArea_DOCKINGAREA_RIGHT;
+
+ // Determine if we have a toolbar and set alignment according to the docking area!
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ ToolBox* pToolBox = 0;
+ if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
+ pToolBox = (ToolBox *)pWindow;
+
+ if ( eDockingArea != -1 )
+ {
+ if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
+ {
+ aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_TOP;
+ aUIDockingElement.m_bFloating = false;
+ }
+ else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
+ {
+ aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_BOTTOM;
+ aUIDockingElement.m_bFloating = false;
+ }
+ else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
+ {
+ aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_LEFT;
+ aUIDockingElement.m_bFloating = false;
+ }
+ else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_RIGHT )
+ {
+ aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_RIGHT;
+ aUIDockingElement.m_bFloating = false;
+ }
+
+ ::Point aOutputPos = pContainerWindow->ScreenToOutputPixel( aTrackingRect.TopLeft() );
+ aTrackingRect.SetPos( aOutputPos );
+
+ ::Rectangle aNewDockingRect( aTrackingRect );
+ implts_calcDockingPosSize( aUIDockingElement, eDockingOperation, aNewDockingRect, aMousePos );
+
+ ::Point aScreenPos = pContainerWindow->OutputToScreenPixel( aNewDockingRect.TopLeft() );
+ aNewTrackingRect = awt::Rectangle( aScreenPos.X(), aScreenPos.Y(),
+ aNewDockingRect.getWidth(), aNewDockingRect.getHeight() );
+ aDockingData.TrackingRectangle = aNewTrackingRect;
+ }
+ else if ( pToolBox && bDockingInProgress )
+ {
+ bool bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
+ ::Size aFloatSize = aUIDockingElement.m_aFloatingData.m_aSize;
+ if ( aFloatSize.Width() > 0 && aFloatSize.Height() > 0 )
+ {
+ aUIDockingElement.m_aFloatingData.m_aPos = pContainerWindow->ScreenToOutputPixel(
+ ::Point( e.MousePos.X, e.MousePos.Y ));
+ aDockingData.TrackingRectangle.Height = aFloatSize.Height();
+ aDockingData.TrackingRectangle.Width = aFloatSize.Width();
+ }
+ else
+ {
+ aFloatSize = pToolBox->CalcWindowSizePixel();
+ if ( !bIsHorizontal )
+ {
+ // Floating toolbars are always horizontal aligned! We have to swap
+ // width/height if we have a vertical aligned toolbar.
+ sal_Int32 nTemp = aFloatSize.Height();
+ aFloatSize.Height() = aFloatSize.Width();
+ aFloatSize.Width() = nTemp;
+ }
+
+ aDockingData.TrackingRectangle.Height = aFloatSize.Height();
+ aDockingData.TrackingRectangle.Width = aFloatSize.Width();
+
+ // For the first time we don't have any data about the floating size of a toolbar.
+ // We calculate it and store it for later use.
+ aUIDockingElement.m_aFloatingData.m_aPos = pContainerWindow->ScreenToOutputPixel(::Point( e.MousePos.X, e.MousePos.Y ));
+ aUIDockingElement.m_aFloatingData.m_aSize = aFloatSize;
+ aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines();
+ aUIDockingElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
+ }
+ aDockingData.TrackingRectangle.X = e.MousePos.X;
+ aDockingData.TrackingRectangle.Y = e.MousePos.Y;
+ }
+
+ aDockingData.bFloating = ( eDockingArea == -1 );
+
+ // Write current data to the member docking progress data
+ WriteGuard aWriteLock( m_aLock );
+ m_aDockUIElement.m_bFloating = aDockingData.bFloating;
+ if ( !aDockingData.bFloating )
+ {
+ m_aDockUIElement.m_aDockedData = aUIDockingElement.m_aDockedData;
+ m_eDockOperation = eDockingOperation;
+ }
+ else
+ m_aDockUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData;
+ aWriteLock.unlock();
+ }
+ catch ( uno::Exception& ) {}
+ }
+
+ return aDockingData;
+}
+
+void SAL_CALL ToolbarLayoutManager::endDocking( const awt::EndDockingEvent& e )
+throw (uno::RuntimeException)
+{
+ bool bDockingInProgress( false );
+ bool bStartDockFloated( false );
+ bool bFloating( false );
+ UIElement aUIDockingElement;
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ bDockingInProgress = m_bDockingInProgress;
+ aUIDockingElement = m_aDockUIElement;
+ bFloating = aUIDockingElement.m_bFloating;
+
+ UIElement& rUIElement = impl_findToolbar( aUIDockingElement.m_aName );
+ if ( rUIElement.m_aName == aUIDockingElement.m_aName )
+ {
+ if ( aUIDockingElement.m_bFloating )
+ {
+ // Write last position into position data
+ uno::Reference< awt::XWindow > xWindow( aUIDockingElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
+ rUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData;
+ awt::Rectangle aTmpRect = xWindow->getPosSize();
+ rUIElement.m_aFloatingData.m_aPos = ::Point( aTmpRect.X, aTmpRect.Y );
+ // make changes also for our local data as we use it to make data persistent
+ aUIDockingElement.m_aFloatingData = rUIElement.m_aFloatingData;
+ }
+ else
+ {
+ rUIElement.m_aDockedData = aUIDockingElement.m_aDockedData;
+ rUIElement.m_aFloatingData.m_aSize = aUIDockingElement.m_aFloatingData.m_aSize;
+
+ if ( m_eDockOperation != DOCKOP_ON_COLROW )
+ {
+ // we have to renumber our row/column data to insert a new row/column
+ implts_renumberRowColumnData((ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, m_eDockOperation, aUIDockingElement );
+ }
+ }
+
+ bStartDockFloated = rUIElement.m_bFloating;
+ rUIElement.m_bFloating = m_aDockUIElement.m_bFloating;
+ rUIElement.m_bUserActive = true;
+ }
+
+ // reset member for next docking operation
+ m_aDockUIElement.m_xUIElement.clear();
+ m_eDockOperation = DOCKOP_ON_COLROW;
+ aWriteLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ implts_writeWindowStateData( aUIDockingElement );
+
+ if ( bDockingInProgress )
+ {
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( uno::Reference< awt::XWindow >( e.Source, uno::UNO_QUERY ));
+ ToolBox* pToolBox = 0;
+ if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
+ pToolBox = (ToolBox *)pWindow;
+
+ if ( pToolBox )
+ {
+ if( e.bFloating )
+ {
+ if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
+ pToolBox->SetAlign( WINDOWALIGN_TOP );
+ else
+ pToolBox->SetAlign( WINDOWALIGN_LEFT );
+ }
+ else
+ {
+ ::Size aSize;
+
+ pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) );
+
+ // Docked toolbars have always one line
+ aSize = pToolBox->CalcWindowSizePixel( 1 );
+
+ // Lock layouting updates as our listener would be called due to SetSizePixel
+ pToolBox->SetOutputSizePixel( aSize );
+ }
+ }
+ }
+
+ implts_sortUIElements();
+
+ aWriteLock.lock();
+ m_bDockingInProgress = sal_False;
+ m_bLayoutDirty = !bStartDockFloated || !bFloating;
+ bool bNotify = m_bLayoutDirty;
+ aWriteLock.unlock();
+
+ if ( bNotify )
+ m_pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
+}
+
+sal_Bool SAL_CALL ToolbarLayoutManager::prepareToggleFloatingMode( const lang::EventObject& e )
+throw (uno::RuntimeException)
+{
+ ReadGuard aReadLock( m_aLock );
+ bool bDockingInProgress = m_bDockingInProgress;
+ aReadLock.unlock();
+
+ UIElement aUIDockingElement = implts_findToolbar( e.Source );
+ bool bWinFound( aUIDockingElement.m_aName.getLength() > 0 );
+ uno::Reference< awt::XWindow > xWindow( e.Source, uno::UNO_QUERY );
+
+ if ( bWinFound && xWindow.is() )
+ {
+ if ( !bDockingInProgress )
+ {
+ awt::Rectangle aRect;
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+ if ( xDockWindow->isFloating() )
+ {
+ {
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
+ {
+ ToolBox* pToolBox = static_cast< ToolBox *>( pWindow );
+ aUIDockingElement.m_aFloatingData.m_aPos = pToolBox->GetPosPixel();
+ aUIDockingElement.m_aFloatingData.m_aSize = pToolBox->GetOutputSizePixel();
+ aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines();
+ aUIDockingElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
+ }
+ }
+
+ UIElement aUIElement = implts_findToolbar( aUIDockingElement.m_aName );
+ if ( aUIElement.m_aName == aUIDockingElement.m_aName )
+ implts_setToolbar( aUIDockingElement );
+ }
+ }
+ }
+
+ return sal_True;
+}
+
+void SAL_CALL ToolbarLayoutManager::toggleFloatingMode( const lang::EventObject& e )
+throw (uno::RuntimeException)
+{
+ UIElement aUIDockingElement;
+
+ ReadGuard aReadLock( m_aLock );
+ bool bDockingInProgress( m_bDockingInProgress );
+ if ( bDockingInProgress )
+ aUIDockingElement = m_aDockUIElement;
+ aReadLock.unlock();
+
+ Window* pWindow( 0 );
+ ToolBox* pToolBox( 0 );
+ uno::Reference< awt::XWindow2 > xWindow;
+
+ {
+ SolarMutexGuard aGuard;
+ xWindow = uno::Reference< awt::XWindow2 >( e.Source, uno::UNO_QUERY );
+ pWindow = VCLUnoHelper::GetWindow( xWindow );
+
+ if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
+ pToolBox = (ToolBox *)pWindow;
+ }
+
+ if ( !bDockingInProgress )
+ {
+ aUIDockingElement = implts_findToolbar( e.Source );
+ bool bWinFound = ( aUIDockingElement.m_aName.getLength() > 0 );
+
+ if ( bWinFound && xWindow.is() )
+ {
+ aUIDockingElement.m_bFloating = !aUIDockingElement.m_bFloating;
+ aUIDockingElement.m_bUserActive = true;
+
+ implts_setLayoutInProgress( true );
+ if ( aUIDockingElement.m_bFloating )
+ {
+ SolarMutexGuard aGuard;
+ if ( pToolBox )
+ {
+ pToolBox->SetLineCount( aUIDockingElement.m_aFloatingData.m_nLines );
+ if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
+ pToolBox->SetAlign( WINDOWALIGN_TOP );
+ else
+ pToolBox->SetAlign( WINDOWALIGN_LEFT );
+ }
+
+ bool bUndefPos = hasDefaultPosValue( aUIDockingElement.m_aFloatingData.m_aPos );
+ bool bSetSize = !hasEmptySize( aUIDockingElement.m_aFloatingData.m_aSize );
+
+ if ( bUndefPos )
+ aUIDockingElement.m_aFloatingData.m_aPos = implts_findNextCascadeFloatingPos();
+
+ if ( !bSetSize )
+ {
+ if ( pToolBox )
+ aUIDockingElement.m_aFloatingData.m_aSize = pToolBox->CalcFloatingWindowSizePixel();
+ else
+ aUIDockingElement.m_aFloatingData.m_aSize = pWindow->GetOutputSizePixel();
+ }
+
+ xWindow->setPosSize( aUIDockingElement.m_aFloatingData.m_aPos.X(),
+ aUIDockingElement.m_aFloatingData.m_aPos.Y(),
+ 0, 0, awt::PosSize::POS );
+ xWindow->setOutputSize( AWTSize( aUIDockingElement.m_aFloatingData.m_aSize ) );
+ }
+ else
+ {
+ if ( isDefaultPos( aUIDockingElement.m_aDockedData.m_aPos ))
+ {
+ // Docking on its default position without a preset position -
+ // we have to find a good place for it.
+ ::Point aPixelPos;
+ ::Point aDockPos;
+ ::Size aSize;
+
+ {
+ SolarMutexGuard aGuard;
+ if ( pToolBox )
+ aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea ) );
+ else
+ aSize = pWindow->GetSizePixel();
+ }
+
+ implts_findNextDockingPos((ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos );
+ aUIDockingElement.m_aDockedData.m_aPos = aDockPos;
+ }
+
+ SolarMutexGuard aGuard;
+ if ( pToolBox )
+ {
+ pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) );
+ ::Size aSize = pToolBox->CalcWindowSizePixel( 1 );
+ awt::Rectangle aRect = xWindow->getPosSize();
+ xWindow->setPosSize( aRect.X, aRect.Y, 0, 0, awt::PosSize::POS );
+ xWindow->setOutputSize( AWTSize( aSize ) );
+ }
+ }
+
+ implts_setLayoutInProgress( false );
+ implts_setToolbar( aUIDockingElement );
+ implts_writeWindowStateData( aUIDockingElement );
+ implts_sortUIElements();
+ implts_setLayoutDirty();
+
+ aReadLock.lock();
+ ILayoutNotifications* pParentLayouter( m_pParentLayouter );
+ aReadLock.unlock();
+
+ if ( pParentLayouter )
+ pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
+ }
+ }
+ else
+ {
+ SolarMutexGuard aGuard;
+ if ( pToolBox )
+ {
+ if ( aUIDockingElement.m_bFloating )
+ {
+ if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
+ pToolBox->SetAlign( WINDOWALIGN_TOP );
+ else
+ pToolBox->SetAlign( WINDOWALIGN_LEFT );
+ }
+ else
+ pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) );
+ }
+ }
+}
+
+void SAL_CALL ToolbarLayoutManager::closed( const lang::EventObject& e )
+throw (uno::RuntimeException)
+{
+ rtl::OUString aName;
+ UIElement aUIElement;
+ UIElementVector::iterator pIter;
+
+ WriteGuard aWriteLock( m_aLock );
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
+ if ( xUIElement.is() )
+ {
+ uno::Reference< uno::XInterface > xIfac( xUIElement->getRealInterface(), uno::UNO_QUERY );
+ if ( xIfac == e.Source )
+ {
+ aName = pIter->m_aName;
+
+ // user closes a toolbar =>
+ // context sensitive toolbar: only destroy toolbar and store state.
+ // context sensitive toolbar: make it invisible, store state and destroy it.
+ if ( !pIter->m_bContextSensitive )
+ pIter->m_bVisible = sal_False;
+
+ aUIElement = *pIter;
+ break;
+ }
+ }
+ }
+ aWriteLock.unlock();
+
+ // destroy element
+ if ( aName.getLength() > 0 )
+ {
+ implts_writeWindowStateData( aUIElement );
+ destroyToolbar( aName );
+ }
+}
+
+void SAL_CALL ToolbarLayoutManager::endPopupMode( const awt::EndPopupModeEvent& /*e*/ )
+throw (uno::RuntimeException)
+{
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XUIConfigurationListener
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL ToolbarLayoutManager::elementInserted( const ui::ConfigurationEvent& rEvent )
+throw (uno::RuntimeException)
+{
+ UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL );
+
+ uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY );
+ if ( xElementSettings.is() )
+ {
+ ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
+ uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ if ( rEvent.Source == uno::Reference< uno::XInterface >( m_xDocCfgMgr, uno::UNO_QUERY ))
+ xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( m_xDocCfgMgr ));
+ }
+ xElementSettings->updateSettings();
+ }
+ else
+ {
+ ::rtl::OUString aElementType;
+ ::rtl::OUString aElementName;
+ parseResourceURL( rEvent.ResourceURL, aElementType, aElementName );
+ if ( aElementName.indexOf( m_aCustomTbxPrefix ) != -1 )
+ {
+ // custom toolbar must be directly created, shown and layouted!
+ createToolbar( rEvent.ResourceURL );
+ uno::Reference< ui::XUIElement > xUIElement = getToolbar( rEvent.ResourceURL );
+ if ( xUIElement.is() )
+ {
+ ::rtl::OUString aUIName;
+ uno::Reference< ui::XUIConfigurationManager > xCfgMgr;
+ uno::Reference< beans::XPropertySet > xPropSet;
+
+ try
+ {
+ xCfgMgr = uno::Reference< ui::XUIConfigurationManager >( rEvent.Source, uno::UNO_QUERY );
+ xPropSet = uno::Reference< beans::XPropertySet >( xCfgMgr->getSettings( rEvent.ResourceURL, sal_False ), uno::UNO_QUERY );
+
+ if ( xPropSet.is() )
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= aUIName;
+ }
+ catch ( container::NoSuchElementException& ) {}
+ catch ( beans::UnknownPropertyException& ) {}
+ catch ( lang::WrappedTargetException& ) {}
+
+ {
+ SolarMutexGuard aGuard;
+ Window* pWindow = getWindowFromXUIElement( xUIElement );
+ if ( pWindow )
+ pWindow->SetText( aUIName );
+ }
+
+ showToolbar( rEvent.ResourceURL );
+ }
+ }
+ }
+}
+
+void SAL_CALL ToolbarLayoutManager::elementRemoved( const ui::ConfigurationEvent& rEvent )
+throw (uno::RuntimeException)
+{
+ ReadGuard aReadLock( m_aLock );
+ uno::Reference< awt::XWindow > xContainerWindow( m_xContainerWindow, uno::UNO_QUERY );
+ uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr );
+ uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr );
+ aReadLock.unlock();
+
+ UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL );
+ uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY );
+ if ( xElementSettings.is() )
+ {
+ bool bNoSettings( false );
+ ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
+ uno::Reference< uno::XInterface > xElementCfgMgr;
+ uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );
+
+ if ( xPropSet.is() )
+ xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr;
+
+ if ( !xElementCfgMgr.is() )
+ return;
+
+ // Check if the same UI configuration manager has changed => check further
+ if ( rEvent.Source == xElementCfgMgr )
+ {
+ // Same UI configuration manager where our element has its settings
+ if ( rEvent.Source == uno::Reference< uno::XInterface >( xDocCfgMgr, uno::UNO_QUERY ))
+ {
+ // document settings removed
+ if ( xModuleCfgMgr->hasSettings( rEvent.ResourceURL ))
+ {
+ xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( xModuleCfgMgr ));
+ xElementSettings->updateSettings();
+ return;
+ }
+ }
+
+ bNoSettings = true;
+ }
+
+ // No settings anymore, element must be destroyed
+ if ( xContainerWindow.is() && bNoSettings )
+ destroyToolbar( rEvent.ResourceURL );
+ }
+}
+
+void SAL_CALL ToolbarLayoutManager::elementReplaced( const ui::ConfigurationEvent& rEvent )
+throw (uno::RuntimeException)
+{
+ UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL );
+
+ uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY );
+ if ( xElementSettings.is() )
+ {
+ ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
+ uno::Reference< uno::XInterface > xElementCfgMgr;
+ uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );
+
+ if ( xPropSet.is() )
+ xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr;
+
+ if ( !xElementCfgMgr.is() )
+ return;
+
+ // Check if the same UI configuration manager has changed => update settings
+ if ( rEvent.Source == xElementCfgMgr )
+ {
+ xElementSettings->updateSettings();
+
+ WriteGuard aWriteLock( m_aLock );
+ bool bNotify = !aUIElement.m_bFloating;
+ m_bLayoutDirty = bNotify;
+ ILayoutNotifications* pParentLayouter( m_pParentLayouter );
+ aWriteLock.unlock();
+
+ if ( bNotify && pParentLayouter )
+ pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
+ }
+ }
+}
+
+uno::Reference< ui::XUIElement > ToolbarLayoutManager::getToolbar( const ::rtl::OUString& aName )
+{
+ return implts_findToolbar( aName ).m_xUIElement;
+}
+
+uno::Sequence< uno::Reference< ui::XUIElement > > ToolbarLayoutManager::getToolbars()
+{
+ uno::Sequence< uno::Reference< ui::XUIElement > > aSeq;
+
+ ReadGuard aReadLock( m_aLock );
+ if ( m_aUIElements.size() > 0 )
+ {
+ sal_uInt32 nCount(0);
+ UIElementVector::iterator pIter;
+ for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ )
+ {
+ if ( pIter->m_xUIElement.is() )
+ {
+ ++nCount;
+ aSeq.realloc( nCount );
+ aSeq[nCount-1] = pIter->m_xUIElement;
+ }
+ }
+ }
+
+ return aSeq;
+}
+
+bool ToolbarLayoutManager::floatToolbar( const ::rtl::OUString& rResourceURL )
+{
+ UIElement aUIElement = implts_findToolbar( rResourceURL );
+ if ( aUIElement.m_xUIElement.is() )
+ {
+ try
+ {
+ uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
+ if ( xDockWindow.is() && !xDockWindow->isFloating() )
+ {
+ aUIElement.m_bFloating = true;
+ implts_writeWindowStateData( aUIElement );
+ xDockWindow->setFloatingMode( true );
+
+ implts_setLayoutDirty();
+ implts_setToolbar( aUIElement );
+ return true;
+ }
+ }
+ catch ( lang::DisposedException& ) {}
+ }
+
+ return false;
+}
+
+bool ToolbarLayoutManager::lockToolbar( const ::rtl::OUString& rResourceURL )
+{
+ UIElement aUIElement = implts_findToolbar( rResourceURL );
+ if ( aUIElement.m_xUIElement.is() )
+ {
+ try
+ {
+ uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
+ if ( xDockWindow.is() && !xDockWindow->isFloating() && !xDockWindow->isLocked() )
+ {
+ aUIElement.m_aDockedData.m_bLocked = true;
+ implts_writeWindowStateData( aUIElement );
+ xDockWindow->lock();
+
+ implts_setLayoutDirty();
+ implts_setToolbar( aUIElement );
+ return true;
+ }
+ }
+ catch ( lang::DisposedException& ) {}
+ }
+
+ return false;
+}
+
+bool ToolbarLayoutManager::unlockToolbar( const ::rtl::OUString& rResourceURL )
+{
+ UIElement aUIElement = implts_findToolbar( rResourceURL );
+ if ( aUIElement.m_xUIElement.is() )
+ {
+ try
+ {
+ uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
+ if ( xDockWindow.is() && !xDockWindow->isFloating() && xDockWindow->isLocked() )
+ {
+ aUIElement.m_aDockedData.m_bLocked = false;
+ implts_writeWindowStateData( aUIElement );
+ xDockWindow->unlock();
+
+ implts_setLayoutDirty();
+ implts_setToolbar( aUIElement );
+ return true;
+ }
+ }
+ catch ( lang::DisposedException& ) {}
+ }
+
+ return false;
+}
+
+bool ToolbarLayoutManager::isToolbarVisible( const ::rtl::OUString& rResourceURL )
+{
+ uno::Reference< awt::XWindow2 > xWindow2( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
+ return ( xWindow2.is() && xWindow2->isVisible() );
+}
+
+bool ToolbarLayoutManager::isToolbarFloating( const ::rtl::OUString& rResourceURL )
+{
+ uno::Reference< awt::XDockableWindow > xDockWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
+ return ( xDockWindow.is() && xDockWindow->isFloating() );
+}
+
+bool ToolbarLayoutManager::isToolbarDocked( const ::rtl::OUString& rResourceURL )
+{
+ return !isToolbarFloating( rResourceURL );
+}
+
+bool ToolbarLayoutManager::isToolbarLocked( const ::rtl::OUString& rResourceURL )
+{
+ uno::Reference< awt::XDockableWindow > xDockWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
+ return ( xDockWindow.is() && xDockWindow->isLocked() );
+}
+
+awt::Size ToolbarLayoutManager::getToolbarSize( const ::rtl::OUString& rResourceURL )
+{
+ Window* pWindow = implts_getWindow( rResourceURL );
+
+ SolarMutexGuard aGuard;
+ if ( pWindow )
+ {
+ ::Size aSize = pWindow->GetSizePixel();
+ awt::Size aWinSize;
+ aWinSize.Width = aSize.Width();
+ aWinSize.Height = aSize.Height();
+ return aWinSize;
+ }
+
+ return awt::Size();
+}
+
+awt::Point ToolbarLayoutManager::getToolbarPos( const ::rtl::OUString& rResourceURL )
+{
+ awt::Point aPos;
+ UIElement aUIElement = implts_findToolbar( rResourceURL );
+
+ uno::Reference< awt::XWindow > xWindow( implts_getXWindow( rResourceURL ));
+ if ( xWindow.is() )
+ {
+ if ( aUIElement.m_bFloating )
+ {
+ awt::Rectangle aRect = xWindow->getPosSize();
+ aPos.X = aRect.X;
+ aPos.Y = aRect.Y;
+ }
+ else
+ {
+ ::Point aVirtualPos = aUIElement.m_aDockedData.m_aPos;
+ aPos.X = aVirtualPos.X();
+ aPos.Y = aVirtualPos.Y();
+ }
+ }
+
+ return aPos;
+}
+
+void ToolbarLayoutManager::setToolbarSize( const ::rtl::OUString& rResourceURL, const awt::Size& aSize )
+{
+ uno::Reference< awt::XWindow2 > xWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+ UIElement aUIElement = implts_findToolbar( rResourceURL );
+
+ if ( xWindow.is() && xDockWindow.is() && xDockWindow->isFloating() )
+ {
+ xWindow->setOutputSize( aSize );
+ aUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height );
+ implts_setToolbar( aUIElement );
+ implts_writeWindowStateData( aUIElement );
+ implts_sortUIElements();
+ }
+}
+
+void ToolbarLayoutManager::setToolbarPos( const ::rtl::OUString& rResourceURL, const awt::Point& aPos )
+{
+ uno::Reference< awt::XWindow > xWindow( implts_getXWindow( rResourceURL ));
+ uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
+ UIElement aUIElement = implts_findToolbar( rResourceURL );
+
+ if ( xWindow.is() && xDockWindow.is() && xDockWindow->isFloating() )
+ {
+ xWindow->setPosSize( aPos.X, aPos.Y, 0, 0, awt::PosSize::POS );
+ aUIElement.m_aFloatingData.m_aPos = ::Point( aPos.X, aPos.Y );
+ implts_setToolbar( aUIElement );
+ implts_writeWindowStateData( aUIElement );
+ implts_sortUIElements();
+ }
+}
+
+void ToolbarLayoutManager::setToolbarPosSize( const ::rtl::OUString& rResourceURL, const awt::Point& aPos, const awt::Size& aSize )
+{
+ setToolbarPos( rResourceURL, aPos );
+ setToolbarSize( rResourceURL, aSize );
+}
+
+} // namespace framework
diff --git a/framework/source/layoutmanager/toolbarlayoutmanager.hxx b/framework/source/layoutmanager/toolbarlayoutmanager.hxx
new file mode 100644
index 000000000000..df6b36020f93
--- /dev/null
+++ b/framework/source/layoutmanager/toolbarlayoutmanager.hxx
@@ -0,0 +1,344 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutmanager.hxx,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_LAYOUTMANAGER_TOOLBARLAYOUTMANAGER_HXX_
+#define __FRAMEWORK_LAYOUTMANAGER_TOOLBARLAYOUTMANAGER_HXX_
+
+/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
+ with solaris headers ...
+*/
+#include <vector>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/threadhelpbase.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <macros/generic.hxx>
+#include <macros/xinterface.hxx>
+#include <macros/xtypeprovider.hxx>
+#include <macros/xserviceinfo.hxx>
+#include <stdtypes.h>
+#include <properties.h>
+#include <stdtypes.h>
+#include <uiconfiguration/globalsettings.hxx>
+#include <uiconfiguration/windowstateconfiguration.hxx>
+#include <framework/addonsoptions.hxx>
+#include <uielement/uielement.hxx>
+#include <helper/ilayoutnotifications.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/XUIConfiguration.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/ui/XUIElementFactory.hpp>
+#include <com/sun/star/ui/DockingArea.hpp>
+#include <com/sun/star/awt/XTopWindow2.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/awt/XDockableWindow.hpp>
+#include <com/sun/star/awt/XDockableWindowListener.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <cppuhelper/implbase3.hxx>
+
+
+namespace framework
+{
+
+class ToolbarLayoutManager : public ::cppu::WeakImplHelper3< ::com::sun::star::awt::XDockableWindowListener,
+ ::com::sun::star::ui::XUIConfigurationListener,
+ ::com::sun::star::awt::XWindowListener >,
+ private ThreadHelpBase // Struct for right initalization of mutex member! Must be first of baseclasses.
+{
+ public:
+ enum { DOCKINGAREAS_COUNT = 4 };
+
+ ToolbarLayoutManager( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMGR,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElementFactory >& xUIElementFactory,
+ ILayoutNotifications* pParentLayouter );
+ virtual ~ToolbarLayoutManager();
+
+ void reset();
+ void attach( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager >& xModuleCfgMgr,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager >& xDocCfgMgr,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& xPersistentWindowState );
+
+ void setParentWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& xParentWindow );
+ void setDockingAreaOffsets( const ::Rectangle aOffsets );
+
+ void resetDockingArea();
+
+ ::com::sun::star::awt::Rectangle getDockingArea();
+ void setDockingArea( const ::com::sun::star::awt::Rectangle& rDockingArea );
+
+ // layouting
+ bool isLayoutDirty();
+ void doLayout(const ::Size& aContainerSize);
+
+ // creation/destruction
+ void createStaticToolbars();
+ void destroyToolbars();
+
+ bool requestToolbar( const ::rtl::OUString& rResourceURL );
+ bool createToolbar( const ::rtl::OUString& rResourceURL );
+ bool destroyToolbar( const ::rtl::OUString& rResourceURL );
+
+ // visibility
+ bool showToolbar( const ::rtl::OUString& rResourceURL );
+ bool hideToolbar( const ::rtl::OUString& rResourceURL );
+
+ void refreshToolbarsVisibility( bool bAutomaticToolbars );
+ void setFloatingToolbarsVisibility( bool bVisible );
+ void setVisible(bool bVisible);
+ bool isVisible() { return m_bVisible; }
+
+ // docking and further functions
+ bool dockToolbar( const ::rtl::OUString& rResourceURL, ::com::sun::star::ui::DockingArea eDockingArea, const ::com::sun::star::awt::Point& aPos );
+ bool dockAllToolbars();
+ bool floatToolbar( const ::rtl::OUString& rResoureURL );
+ bool lockToolbar( const ::rtl::OUString& rResourceURL );
+ bool unlockToolbar( const ::rtl::OUString& rResourceURL );
+ void setToolbarPos( const ::rtl::OUString& rResourceURL, const ::com::sun::star::awt::Point& aPos );
+ void setToolbarSize( const ::rtl::OUString& rResourceURL, const ::com::sun::star::awt::Size& aSize );
+ void setToolbarPosSize( const ::rtl::OUString& rResourceURL, const ::com::sun::star::awt::Point& aPos, const ::com::sun::star::awt::Size& aSize );
+ bool isToolbarVisible( const ::rtl::OUString& rResourceURL );
+ bool isToolbarFloating( const ::rtl::OUString& rResourceURL );
+ bool isToolbarDocked( const ::rtl::OUString& rResourceURL );
+ bool isToolbarLocked( const ::rtl::OUString& rResourceURL );
+ ::com::sun::star::awt::Point getToolbarPos( const ::rtl::OUString& rResourceURL );
+ ::com::sun::star::awt::Size getToolbarSize( const ::rtl::OUString& rResourceURL );
+ ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement > getToolbar( const ::rtl::OUString& aName );
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement > > getToolbars();
+
+ // child window notifications
+ long childWindowEvent( VclSimpleEvent* pEvent );
+
+ //---------------------------------------------------------------------------------------------------------
+ // XInterface
+ //---------------------------------------------------------------------------------------------------------
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw( ::com::sun::star::uno::RuntimeException );
+
+ //---------------------------------------------------------------------------------------------------------
+ // XEventListener
+ //---------------------------------------------------------------------------------------------------------
+ virtual void SAL_CALL disposing( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException );
+
+ //---------------------------------------------------------------------------------------------------------
+ // XWindowListener
+ //---------------------------------------------------------------------------------------------------------
+ virtual void SAL_CALL windowResized( const css::awt::WindowEvent& aEvent ) throw( css::uno::RuntimeException );
+ virtual void SAL_CALL windowMoved( const css::awt::WindowEvent& aEvent ) throw( css::uno::RuntimeException );
+ virtual void SAL_CALL windowShown( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException );
+ virtual void SAL_CALL windowHidden( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException );
+
+ //---------------------------------------------------------------------------------------------------------
+ // XDockableWindowListener
+ //---------------------------------------------------------------------------------------------------------
+ virtual void SAL_CALL startDocking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::awt::DockingData SAL_CALL docking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endDocking( const ::com::sun::star::awt::EndDockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL prepareToggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL toggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL endPopupMode( const ::com::sun::star::awt::EndPopupModeEvent& e ) throw (::com::sun::star::uno::RuntimeException);
+
+ //---------------------------------------------------------------------------------------------------------
+ // XUIConfigurationListener
+ //---------------------------------------------------------------------------------------------------------
+ virtual void SAL_CALL elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+
+ private:
+ enum DockingOperation
+ {
+ DOCKOP_BEFORE_COLROW,
+ DOCKOP_ON_COLROW,
+ DOCKOP_AFTER_COLROW
+ };
+
+ typedef std::vector< UIElement > UIElementVector;
+ struct SingleRowColumnWindowData
+ {
+ SingleRowColumnWindowData() : nVarSize( 0 ), nStaticSize( 0 ), nSpace( 0 ) {}
+
+ std::vector< rtl::OUString > aUIElementNames;
+ std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > > aRowColumnWindows;
+ std::vector< ::com::sun::star::awt::Rectangle > aRowColumnWindowSizes;
+ std::vector< sal_Int32 > aRowColumnSpace;
+ ::com::sun::star::awt::Rectangle aRowColumnRect;
+ sal_Int32 nVarSize;
+ sal_Int32 nStaticSize;
+ sal_Int32 nSpace;
+ sal_Int32 nRowColumn;
+ };
+
+ //---------------------------------------------------------------------------------------------------------
+ // internal helper methods
+ //---------------------------------------------------------------------------------------------------------
+ bool implts_isParentWindowVisible() const;
+ ::Rectangle implts_calcDockingArea();
+ void implts_sortUIElements();
+ void implts_reparentToolbars();
+ rtl::OUString implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber ) const;
+ void implts_setElementData( UIElement& rUIElement, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDockableWindow >& rDockWindow );
+ void implts_destroyDockingAreaWindows();
+
+ //---------------------------------------------------------------------------------------------------------
+ // layout methods
+ //---------------------------------------------------------------------------------------------------------
+ void implts_setDockingAreaWindowSizes( const ::com::sun::star::awt::Rectangle& rBorderSpace );
+ ::Point implts_findNextCascadeFloatingPos();
+ void implts_renumberRowColumnData( ::com::sun::star::ui::DockingArea eDockingArea, DockingOperation eDockingOperation, const UIElement& rUIElement );
+ void implts_calcWindowPosSizeOnSingleRowColumn( sal_Int32 nDockingArea,
+ sal_Int32 nOffset,
+ SingleRowColumnWindowData& rRowColumnWindowData,
+ const ::Size& rContainerSize );
+ void implts_setLayoutDirty();
+ void implts_setLayoutInProgress( bool bInProgress = true );
+ bool implts_isLayoutInProgress() const { return m_bLayoutInProgress; }
+
+ //---------------------------------------------------------------------------------------------------------
+ // lookup/container methods
+ //---------------------------------------------------------------------------------------------------------
+ UIElement implts_findToolbar( const rtl::OUString& aName );
+ UIElement implts_findToolbar( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xToolbar );
+ UIElement& impl_findToolbar( const rtl::OUString& aName );
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > implts_getXWindow( const ::rtl::OUString& aName );
+ Window* implts_getWindow( const ::rtl::OUString& aName );
+ bool implts_insertToolbar( const UIElement& rUIElement );
+ void implts_setToolbar( const UIElement& rUIElement );
+ ::Size implts_getTopBottomDockingAreaSizes();
+ void implts_getUIElementVectorCopy( UIElementVector& rCopy );
+
+ //---------------------------------------------------------------------------------------------------------
+ // internal docking methods
+ //---------------------------------------------------------------------------------------------------------
+ ::Rectangle implts_calcHotZoneRect( const ::Rectangle& rRect, sal_Int32 nHotZoneOffset );
+ void implts_calcDockingPosSize( UIElement& aUIElement, DockingOperation& eDockOperation, ::Rectangle& rTrackingRect, const Point& rMousePos );
+ DockingOperation implts_determineDockingOperation( ::com::sun::star::ui::DockingArea DockingArea, const ::Rectangle& rRowColRect, const Point& rMousePos );
+ ::Rectangle implts_getWindowRectFromRowColumn( ::com::sun::star::ui::DockingArea DockingArea, const SingleRowColumnWindowData& rRowColumnWindowData, const ::Point& rMousePos, const rtl::OUString& rExcludeElementName );
+ ::Rectangle implts_determineFrontDockingRect( ::com::sun::star::ui::DockingArea eDockingArea,
+ sal_Int32 nRowCol,
+ const ::Rectangle& rDockedElementRect,
+ const ::rtl::OUString& rMovedElementName,
+ const ::Rectangle& rMovedElementRect );
+ ::Rectangle implts_calcTrackingAndElementRect( ::com::sun::star::ui::DockingArea eDockingArea,
+ sal_Int32 nRowCol,
+ UIElement& rUIElement,
+ const ::Rectangle& rTrackingRect,
+ const ::Rectangle& rRowColumnRect,
+ const ::Size& rContainerWinSize );
+
+ void implts_getDockingAreaElementInfos( ::com::sun::star::ui::DockingArea DockingArea, std::vector< SingleRowColumnWindowData >& rRowColumnsWindowData );
+ void implts_getDockingAreaElementInfoOnSingleRowCol( ::com::sun::star::ui::DockingArea, sal_Int32 nRowCol, SingleRowColumnWindowData& rRowColumnWindowData );
+ void implts_findNextDockingPos( ::com::sun::star::ui::DockingArea DockingArea, const ::Size& aUIElementSize, ::Point& rVirtualPos, ::Point& rPixelPos );
+ void implts_setTrackingRect( ::com::sun::star::ui::DockingArea eDockingArea, const ::Point& rMousePos, ::Rectangle& rTrackingRect );
+
+ //---------------------------------------------------------------------------------------------------------
+ // creation methods
+ //---------------------------------------------------------------------------------------------------------
+ void implts_createAddonsToolBars();
+ void implts_createCustomToolBars();
+ void implts_createNonContextSensitiveToolBars();
+ void implts_createCustomToolBars( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& aCustomTbxSeq );
+ void implts_createCustomToolBar( const rtl::OUString& aTbxResName, const rtl::OUString& aTitle );
+ void implts_createToolBar( const ::rtl::OUString& aName, bool& bNotify, ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& rUIElement );
+ css::uno::Reference< css::ui::XUIElement > implts_createElement( const ::rtl::OUString& aName );
+ void implts_setToolbarCreation( bool bStart = true );
+ bool implts_isToolbarCreationActive();
+
+ //---------------------------------------------------------------------------------------------------------
+ // persistence methods
+ //---------------------------------------------------------------------------------------------------------
+ sal_Bool implts_readWindowStateData( const rtl::OUString& aName, UIElement& rElementData );
+ void implts_writeWindowStateData( const UIElement& rElementData );
+ void implts_writeNewWindowStateData( const rtl::OUString aName, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& xWindow );
+
+ //---------------------------------------------------------------------------------------------------------
+ // members
+ //---------------------------------------------------------------------------------------------------------
+ css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+ css::uno::Reference< css::awt::XWindow2 > m_xContainerWindow;
+ css::uno::Reference< css::awt::XWindow > m_xDockAreaWindows[DOCKINGAREAS_COUNT];
+ css::uno::Reference< ::com::sun::star::ui::XUIElementFactory > m_xUIElementFactoryManager;
+ css::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > m_xModuleCfgMgr;
+ css::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > m_xDocCfgMgr;
+ css::uno::Reference< ::com::sun::star::awt::XToolkit > m_xToolkit;
+ css::uno::Reference< ::com::sun::star::container::XNameAccess > m_xPersistentWindowState;
+ ILayoutNotifications* m_pParentLayouter;
+
+ UIElementVector m_aUIElements;
+ UIElement m_aDockUIElement;
+ Point m_aStartDockMousePos;
+ Rectangle m_aDockingArea;
+ Rectangle m_aDockingAreaOffsets;
+ DockingOperation m_eDockOperation;
+
+ AddonsOptions* m_pAddonOptions;
+ GlobalSettings* m_pGlobalSettings;
+
+ bool m_bComponentAttached;
+ bool m_bMustLayout;
+ bool m_bLayoutDirty;
+ bool m_bStoreWindowState;
+ bool m_bGlobalSettings;
+ bool m_bDockingInProgress;
+ bool m_bVisible;
+ bool m_bLayoutInProgress;
+ bool m_bToolbarCreation;
+
+ ::rtl::OUString m_aFullAddonTbxPrefix;
+ ::rtl::OUString m_aCustomTbxPrefix;
+ ::rtl::OUString m_aCustomizeCmd;
+ ::rtl::OUString m_aToolbarTypeString;
+ ::rtl::OUString m_aModuleIdentifier;
+};
+
+} // namespace framework
+
+#endif // __FRAMEWORK_LAYOUTMANAGER_TOOLBARLAYOUTMANAGER_HXX_
diff --git a/framework/source/layoutmanager/uielement.cxx b/framework/source/layoutmanager/uielement.cxx
new file mode 100644
index 000000000000..722ca164f2b5
--- /dev/null
+++ b/framework/source/layoutmanager/uielement.cxx
@@ -0,0 +1,159 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layoutmanager.hxx,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <uielement/uielement.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/ui/DockingArea.hpp>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star;
+
+namespace framework
+{
+
+ bool UIElement::operator< ( const ::framework::UIElement& aUIElement ) const
+{
+ if ( !m_xUIElement.is() && aUIElement.m_xUIElement.is() )
+ return false;
+ else if ( m_xUIElement.is() && !aUIElement.m_xUIElement.is() )
+ return true;
+ else if ( !m_bVisible && aUIElement.m_bVisible )
+ return false;
+ else if ( m_bVisible && !aUIElement.m_bVisible )
+ return true;
+ else if ( !m_bFloating && aUIElement.m_bFloating )
+ return true;
+ else if ( m_bFloating && !aUIElement.m_bFloating )
+ return false;
+ else
+ {
+ if ( m_bFloating )
+ {
+ bool bEqual = ( m_aFloatingData.m_aPos.Y() == aUIElement.m_aFloatingData.m_aPos.Y() );
+ if ( bEqual )
+ return ( m_aFloatingData.m_aPos.X() < aUIElement.m_aFloatingData.m_aPos.X() );
+ else
+ return ( m_aFloatingData.m_aPos.Y() < aUIElement.m_aFloatingData.m_aPos.Y() );
+ }
+ else
+ {
+ if ( m_aDockedData.m_nDockedArea < aUIElement.m_aDockedData.m_nDockedArea )
+ return true;
+ else if ( m_aDockedData.m_nDockedArea > aUIElement.m_aDockedData.m_nDockedArea )
+ return false;
+ else
+ {
+ if ( m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_TOP ||
+ m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
+ {
+ if ( !( m_aDockedData.m_aPos.Y() == aUIElement.m_aDockedData.m_aPos.Y() ) )
+ return ( m_aDockedData.m_aPos.Y() < aUIElement.m_aDockedData.m_aPos.Y() );
+ else
+ {
+ bool bEqual = ( m_aDockedData.m_aPos.X() == aUIElement.m_aDockedData.m_aPos.X() );
+ if ( bEqual )
+ {
+ if ( m_bUserActive && !aUIElement.m_bUserActive )
+ return sal_True;
+ else if ( !m_bUserActive && aUIElement.m_bUserActive )
+ return sal_False;
+ else
+ return sal_False;
+ }
+ else
+ return ( m_aDockedData.m_aPos.X() <= aUIElement.m_aDockedData.m_aPos.X() );
+ }
+ }
+ else
+ {
+ if ( !( m_aDockedData.m_aPos.X() == aUIElement.m_aDockedData.m_aPos.X() ) )
+ return ( m_aDockedData.m_aPos.X() < aUIElement.m_aDockedData.m_aPos.X() );
+ else
+ {
+ bool bEqual = ( m_aDockedData.m_aPos.Y() == aUIElement.m_aDockedData.m_aPos.Y() );
+ if ( bEqual )
+ {
+ if ( m_bUserActive && !aUIElement.m_bUserActive )
+ return sal_True;
+ else if ( !m_bUserActive && aUIElement.m_bUserActive )
+ return sal_False;
+ else
+ return sal_False;
+ }
+ else
+ return ( m_aDockedData.m_aPos.Y() <= aUIElement.m_aDockedData.m_aPos.Y() );
+ }
+ }
+ }
+ }
+ }
+}
+
+UIElement& UIElement::operator= ( const UIElement& rUIElement )
+{
+ if (&rUIElement != this)
+ {
+ m_aType = rUIElement.m_aType;
+ m_aName = rUIElement.m_aName;
+ m_aUIName = rUIElement.m_aUIName;
+ m_xUIElement = rUIElement.m_xUIElement;
+ m_bFloating = rUIElement.m_bFloating;
+ m_bVisible = rUIElement.m_bVisible;
+ m_bUserActive = rUIElement.m_bUserActive;
+ m_bCreateNewRowCol0 = rUIElement.m_bCreateNewRowCol0;
+ m_bDeactiveHide = rUIElement.m_bDeactiveHide;
+ m_bMasterHide = rUIElement.m_bMasterHide;
+ m_bContextSensitive = rUIElement.m_bContextSensitive;
+ m_bContextActive = rUIElement.m_bContextActive;
+ m_bNoClose = rUIElement.m_bNoClose;
+ m_bSoftClose = rUIElement.m_bSoftClose;
+ m_bStateRead = rUIElement.m_bStateRead;
+ m_nStyle = rUIElement.m_nStyle;
+ m_aDockedData = rUIElement.m_aDockedData;
+ m_aFloatingData = rUIElement.m_aFloatingData;
+ }
+ return *this;
+}
+
+} // namespace framework
diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx
new file mode 100644
index 000000000000..e4f73e58c16f
--- /dev/null
+++ b/framework/source/loadenv/loadenv.cxx
@@ -0,0 +1,1809 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+//_______________________________________________
+// includes of own project
+#include <loadenv/loadenv.hxx>
+
+#include <loadenv/targethelper.hxx>
+#include <framework/framelistanalyzer.hxx>
+
+#include <constant/frameloader.hxx>
+
+#include <constant/contenthandler.hxx>
+
+#include <constant/containerquery.hxx>
+#include <interaction/quietinteraction.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <properties.h>
+#include <protocols.h>
+#include <services.h>
+#include <comphelper/interaction.hxx>
+#include <framework/interaction.hxx>
+
+//_______________________________________________
+// includes of uno interface
+#include <com/sun/star/task/ErrorCodeRequest.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/ucb/XContentProviderManager.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XFrameLoader.hpp>
+#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
+#include <com/sun/star/frame/XNotifyingDispatch.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XContainerQuery.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+
+//_______________________________________________
+// includes of an other project
+#include <vcl/window.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/syswin.hxx>
+
+#include <toolkit/unohlp.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <svtools/sfxecode.hxx>
+#include <unotools/processfactory.hxx>
+#include <unotools/ucbhelper.hxx>
+#include <comphelper/configurationhelper.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+// may there exist already a define .-(
+#ifndef css
+namespace css = ::com::sun::star;
+#endif
+
+//_______________________________________________
+// declarations
+
+class LoadEnvListener : private ThreadHelpBase
+ , public ::cppu::WeakImplHelper2< css::frame::XLoadEventListener ,
+ css::frame::XDispatchResultListener >
+{
+ private:
+
+ void** m_ppCheck ;
+ LoadEnv* m_pLoadEnv;
+
+ public:
+
+ //_______________________________________
+ LoadEnvListener(void* pCheck ,
+ LoadEnv* pLoadEnv)
+ {
+ m_ppCheck = &pCheck ;
+ m_pLoadEnv = pLoadEnv;
+ }
+
+ //_______________________________________
+ // frame.XLoadEventListener
+ virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
+ throw(css::uno::RuntimeException);
+
+ virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
+ throw(css::uno::RuntimeException);
+
+ //_______________________________________
+ // frame.XDispatchResultListener
+ virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
+ throw(css::uno::RuntimeException);
+
+ //_______________________________________
+ // lang.XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException);
+};
+
+
+LoadEnv::LoadEnv(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ throw(LoadEnvException, css::uno::RuntimeException)
+ : ThreadHelpBase( )
+ , m_xSMGR (xSMGR)
+ , m_pCheck (this )
+ , m_pQuietInteraction( 0 )
+{
+}
+
+
+LoadEnv::~LoadEnv()
+{
+ m_pCheck = 0;
+}
+
+
+css::uno::Reference< css::lang::XComponent > LoadEnv::loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader,
+ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ const ::rtl::OUString& sURL ,
+ const ::rtl::OUString& sTarget,
+ sal_Int32 nFlags ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArgs )
+ throw(css::lang::IllegalArgumentException,
+ css::io::IOException ,
+ css::uno::RuntimeException )
+{
+ css::uno::Reference< css::lang::XComponent > xComponent;
+
+ try
+ {
+ LoadEnv aEnv(xSMGR);
+
+ aEnv.initializeLoading(sURL,
+ lArgs,
+ css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY),
+ sTarget,
+ nFlags,
+ LoadEnv::E_NO_FEATURE);
+ aEnv.startLoading();
+ aEnv.waitWhileLoading(); // wait for ever!
+
+ xComponent = aEnv.getTargetComponent();
+ }
+ catch(const LoadEnvException& ex)
+ {
+ switch(ex.m_nID)
+ {
+ case LoadEnvException::ID_INVALID_MEDIADESCRIPTOR:
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Optional list of arguments seem to be corrupted.")),
+ xLoader,
+ 4);
+
+ case LoadEnvException::ID_UNSUPPORTED_CONTENT:
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL seems to be an unsupported one.")),
+ xLoader,
+ 1);
+
+ default: xComponent.clear();
+ break;
+ }
+ }
+
+ return xComponent;
+}
+
+//-----------------------------------------------
+::comphelper::MediaDescriptor impl_mergeMediaDescriptorWithMightExistingModelArgs(const css::uno::Sequence< css::beans::PropertyValue >& lOutsideDescriptor)
+{
+ ::comphelper::MediaDescriptor lDescriptor(lOutsideDescriptor);
+ css::uno::Reference< css::frame::XModel > xModel = lDescriptor.getUnpackedValueOrDefault(
+ ::comphelper::MediaDescriptor::PROP_MODEL (),
+ css::uno::Reference< css::frame::XModel > ());
+ if (xModel.is ())
+ {
+ ::comphelper::MediaDescriptor lModelDescriptor(xModel->getArgs());
+ ::comphelper::MediaDescriptor::iterator pIt = lModelDescriptor.find( ::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE() );
+ if ( pIt != lModelDescriptor.end() )
+ lDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] = pIt->second;
+ }
+
+ return lDescriptor;
+}
+
+
+void LoadEnv::initializeLoading(const ::rtl::OUString& sURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor,
+ const css::uno::Reference< css::frame::XFrame >& xBaseFrame ,
+ const ::rtl::OUString& sTarget ,
+ sal_Int32 nSearchFlags ,
+ EFeature eFeature , // => use default ...
+ EContentType eContentType ) // => use default ...
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // Handle still running processes!
+ if (m_xAsynchronousJob.is())
+ throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
+
+ // take over all new parameters.
+ m_xTargetFrame.clear();
+ m_xBaseFrame = xBaseFrame ;
+ m_lMediaDescriptor = impl_mergeMediaDescriptorWithMightExistingModelArgs(lMediaDescriptor);
+ m_sTarget = sTarget ;
+ m_nSearchFlags = nSearchFlags ;
+ m_eFeature = eFeature ;
+ m_eContentType = eContentType ;
+ m_bCloseFrameOnError = sal_False ;
+ m_bReactivateControllerOnError = sal_False ;
+ m_bLoaded = sal_False ;
+
+ // try to find out, if its realy a content, which can be loaded or must be "handled"
+ // We use a default value for this in-parameter. Then we have to start a complex check method
+ // internaly. But if this check was already done outside it can be supressed to perform
+ // the load request. We take over the result then!
+ if (m_eContentType == E_UNSUPPORTED_CONTENT)
+ {
+ m_eContentType = LoadEnv::classifyContent(sURL, lMediaDescriptor);
+ if (m_eContentType == E_UNSUPPORTED_CONTENT)
+ throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
+ }
+
+ // make URL part of the MediaDescriptor
+ // It doesnt mater, if its already an item of it.
+ // It must be the same value ... so we can overwrite it :-)
+ m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_URL()] <<= sURL;
+
+ // parse it - because some following code require that
+ m_aURL.Complete = sURL;
+ css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
+ xParser->parseStrict(m_aURL);
+
+ // BTW: Split URL and JumpMark ...
+ // Because such mark is an explicit value of the media descriptor!
+ if (m_aURL.Mark.getLength())
+ m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_JUMPMARK()] <<= m_aURL.Mark;
+
+ // By the way: remove the old and deprecated value "FileName" from the descriptor!
+ ::comphelper::MediaDescriptor::iterator pIt = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FILENAME());
+ if (pIt != m_lMediaDescriptor.end())
+ m_lMediaDescriptor.erase(pIt);
+
+ // patch the MediaDescriptor, so it fullfill the outside requirements
+ // Means especialy items like e.g. UI InteractionHandler, Status Indicator,
+ // MacroExecutionMode etcpp.
+
+ /*TODO progress is bound to a frame ... How can we set it here? */
+
+ // UI mode
+ const bool bUIMode =
+ ( ( m_eFeature & E_WORK_WITH_UI ) == E_WORK_WITH_UI ) &&
+ ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ) == sal_False ) &&
+ ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_PREVIEW(), sal_False ) == sal_False );
+
+ initializeUIDefaults(
+ m_xSMGR,
+ m_lMediaDescriptor,
+ bUIMode,
+ &m_pQuietInteraction
+ );
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+
+void LoadEnv::initializeUIDefaults( const css::uno::Reference< css::lang::XMultiServiceFactory >& i_rSMGR,
+ ::comphelper::MediaDescriptor& io_lMediaDescriptor, const bool i_bUIMode,
+ QuietInteraction** o_ppQuietInteraction )
+{
+ css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler;
+ sal_Int16 nMacroMode ;
+ sal_Int16 nUpdateMode ;
+
+ if ( i_bUIMode )
+ {
+ nMacroMode = css::document::MacroExecMode::USE_CONFIG;
+ nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG;
+ try
+ {
+ xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(i_rSMGR->createInstance(IMPLEMENTATIONNAME_UIINTERACTIONHANDLER), css::uno::UNO_QUERY);
+ }
+ catch(const css::uno::RuntimeException&) {throw;}
+ catch(const css::uno::Exception& ) { }
+ }
+ // hidden mode
+ else
+ {
+ nMacroMode = css::document::MacroExecMode::NEVER_EXECUTE;
+ nUpdateMode = css::document::UpdateDocMode::NO_UPDATE;
+ QuietInteraction* pQuietInteraction = new QuietInteraction();
+ xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(static_cast< css::task::XInteractionHandler* >(pQuietInteraction), css::uno::UNO_QUERY);
+ if ( o_ppQuietInteraction != NULL )
+ {
+ *o_ppQuietInteraction = pQuietInteraction;
+ (*o_ppQuietInteraction)->acquire();
+ }
+ }
+
+ if (
+ (xInteractionHandler.is() ) &&
+ (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()) == io_lMediaDescriptor.end())
+ )
+ {
+ io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= xInteractionHandler;
+ }
+
+ if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()) == io_lMediaDescriptor.end())
+ io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] <<= nMacroMode;
+
+ if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()) == io_lMediaDescriptor.end())
+ io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()] <<= nUpdateMode;
+}
+
+
+void LoadEnv::startLoading()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ // Handle still running processes!
+ if (m_xAsynchronousJob.is())
+ throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
+
+ // content can not be loaded or handled
+ // check "classifyContent()" failed before ...
+ if (m_eContentType == E_UNSUPPORTED_CONTENT)
+ throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
+
+ // <- SAFE
+ aReadLock.unlock();
+
+ // detect its type/filter etcpp.
+ // These information will be available by the
+ // used descriptor member afterwards and is needed
+ // for all following operations!
+ // Note: An exception will be thrown, in case operation was not successfully ...
+ if (m_eContentType != E_CAN_BE_SET)/* Attention: special feature to set existing component on a frame must ignore type detection! */
+ impl_detectTypeAndFilter();
+
+ // start loading the content ...
+ // Attention: Dont check m_eContentType deeper then UNSUPPORTED/SUPPORTED!
+ // Because it was made in th easiest way ... may a flat detection was made only.
+ // And such simple detection can fail some times .-)
+ // Use another strategy here. Try it and let it run into the case "loading not possible".
+ sal_Bool bStarted = sal_False;
+ if (
+ ((m_eFeature & E_ALLOW_CONTENTHANDLER) == E_ALLOW_CONTENTHANDLER) &&
+ (m_eContentType != E_CAN_BE_SET ) /* Attention: special feature to set existing component on a frame must ignore type detection! */
+ )
+ {
+ bStarted = impl_handleContent();
+ }
+
+ if (!bStarted)
+ bStarted = impl_loadContent();
+
+ // not started => general error
+ // We cant say - what was the reason for.
+ if (!bStarted)
+ throw LoadEnvException(LoadEnvException::ID_GENERAL_ERROR);
+}
+
+/*-----------------------------------------------
+ TODO
+ First draft does not implement timeout using [ms].
+ Current implementation counts yield calls only ...
+-----------------------------------------------*/
+sal_Bool LoadEnv::waitWhileLoading(sal_uInt32 nTimeout)
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // Because its not a good idea to block the main thread
+ // (and we cant be shure that we are currently not used inside the
+ // main thread!), we cant use conditions here realy. We must yield
+ // in an intellegent manner :-)
+
+ sal_Int32 nTime = nTimeout;
+ while(true)
+ {
+ // SAFE -> ------------------------------
+ ReadGuard aReadLock1(m_aLock);
+ if (!m_xAsynchronousJob.is())
+ break;
+ aReadLock1.unlock();
+ // <- SAFE ------------------------------
+
+ Application::Yield();
+
+ // forever!
+ if (nTimeout==0)
+ continue;
+
+ // timed out?
+ --nTime;
+ if (nTime<1)
+ break;
+ }
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock2(m_aLock);
+ return !m_xAsynchronousJob.is();
+ // <- SAFE ----------------------------------
+}
+
+
+void LoadEnv::cancelLoading()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // PARTIAL(!) SAFE -> ------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ // Still running? Might waitWhileLoading()
+ // runned into the timeout!
+ if (m_xAsynchronousJob.is())
+ {
+ // try to cancel it ... if its an asynchronous frame loader
+ css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(m_xAsynchronousJob, css::uno::UNO_QUERY);
+ if (xAsyncLoader.is())
+ {
+ aReadLock.unlock();
+ // <- BREAK SAFE ------------------------------
+ xAsyncLoader->cancel();
+ // <- RESTART SAFE ----------------------------
+ aReadLock.lock();
+ /* Attention:
+ After returning from any cancel/dispose call, neither the frame nor weself
+ may be called back. Because only we can cancel this job, we already know
+ the result! => Thats why its not usefull nor neccessary to wait for any
+ asynchronous listener notification.
+ */
+ m_bLoaded = sal_False;
+ m_xAsynchronousJob.clear();
+ }
+ // or may be its a content handler? Such handler cant be cancelled in its running
+ // operation :-( And we cant deregister us there again :-(
+ // => The only chance is an exception :-)
+ else
+ throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
+ }
+
+ impl_reactForLoadingState();
+
+ aReadLock.unlock();
+ // <- PARTIAL(!) SAFE ------------------------------
+}
+
+
+css::uno::Reference< css::frame::XFrame > LoadEnv::getTarget() const
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ return m_xTargetFrame;
+ // <- SAFE
+}
+
+
+css::uno::Reference< css::lang::XComponent > LoadEnv::getTargetComponent() const
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ if (!m_xTargetFrame.is())
+ return css::uno::Reference< css::lang::XComponent >();
+
+ css::uno::Reference< css::frame::XController > xController = m_xTargetFrame->getController();
+ if (!xController.is())
+ return css::uno::Reference< css::lang::XComponent >(m_xTargetFrame->getComponentWindow(), css::uno::UNO_QUERY);
+
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
+ if (!xModel.is())
+ return css::uno::Reference< css::lang::XComponent >(xController, css::uno::UNO_QUERY);
+
+ return css::uno::Reference< css::lang::XComponent >(xModel, css::uno::UNO_QUERY);
+ // <- SAFE
+}
+
+
+void SAL_CALL LoadEnvListener::loadFinished(const css::uno::Reference< css::frame::XFrameLoader >&)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_ppCheck && *m_ppCheck)
+ m_pLoadEnv->impl_setResult(sal_True);
+ m_ppCheck = NULL;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+
+void SAL_CALL LoadEnvListener::loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >&)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_ppCheck && *m_ppCheck)
+ m_pLoadEnv->impl_setResult(sal_False);
+ m_ppCheck = NULL;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+
+void SAL_CALL LoadEnvListener::dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (!m_ppCheck || !*m_ppCheck)
+ return;
+
+ switch(aEvent.State)
+ {
+ case css::frame::DispatchResultState::FAILURE :
+ m_pLoadEnv->impl_setResult(sal_False);
+ break;
+
+ case css::frame::DispatchResultState::SUCCESS :
+ m_pLoadEnv->impl_setResult(sal_False);
+ break;
+
+ case css::frame::DispatchResultState::DONTKNOW :
+ m_pLoadEnv->impl_setResult(sal_False);
+ break;
+ }
+ m_ppCheck = NULL;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+
+void SAL_CALL LoadEnvListener::disposing(const css::lang::EventObject&)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_ppCheck && *m_ppCheck)
+ m_pLoadEnv->impl_setResult(sal_False);
+ m_ppCheck = NULL;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+
+void LoadEnv::impl_setResult(sal_Bool bResult)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ m_bLoaded = bResult;
+
+ impl_reactForLoadingState();
+
+ // clearing of this reference will unblock waitWhileLoading()!
+ // So we must be shure, that loading process was realy finished.
+ // => do it as last operation of this method ...
+ m_xAsynchronousJob.clear();
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ TODO: Is it a good idea to change Sequence<>
+ parameter to stl-adapter?
+-----------------------------------------------*/
+LoadEnv::EContentType LoadEnv::classifyContent(const ::rtl::OUString& sURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor)
+{
+ //-------------------------------------------
+ // (i) Filter some special well known URL protocols,
+ // which can not be handled or loaded in general.
+ // Of course an empty URL must be ignored here too.
+ // Note: These URL schemata are fix and well known ...
+ // But there can be some additional ones, which was not
+ // defined at implementation time of this class :-(
+ // So we have to make shure, that the following code
+ // can detect such protocol schemata too :-)
+
+ if(
+ (!sURL.getLength() ) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_UNO )) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SLOT )) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MACRO )) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SERVICE)) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MAILTO )) ||
+ (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_NEWS ))
+ )
+ {
+ return E_UNSUPPORTED_CONTENT;
+ }
+
+ //-------------------------------------------
+ // (ii) Some special URLs indicates a given input stream,
+ // a full featured document model directly or
+ // specify a request for opening an empty document.
+ // Such contents are loadable in general.
+ // But we have to check, if the media descriptor contains
+ // all needed resources. If they are missing - the following
+ // load request will fail.
+
+ /* Attention: The following code cant work on such special URLs!
+ It should not break the office .. but it make no sense
+ to start expensive object creations and complex search
+ algorithm if its clear, that such URLs must be handled
+ in a special way .-)
+ */
+
+ // creation of new documents
+ if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_FACTORY))
+ return E_CAN_BE_LOADED;
+
+ // using of an existing input stream
+ ::comphelper::MediaDescriptor stlMediaDescriptor(lMediaDescriptor);
+ ::comphelper::MediaDescriptor::const_iterator pIt;
+ if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_STREAM))
+ {
+ pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INPUTSTREAM());
+ css::uno::Reference< css::io::XInputStream > xStream;
+ if (pIt != stlMediaDescriptor.end())
+ pIt->second >>= xStream;
+ if (xStream.is())
+ return E_CAN_BE_LOADED;
+ LOG_WARNING("LoadEnv::classifyContent()", "loading from stream with right URL but invalid stream detected")
+ return E_UNSUPPORTED_CONTENT;
+ }
+
+ // using of a full featured document
+ if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_OBJECT))
+ {
+ pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MODEL());
+ css::uno::Reference< css::frame::XModel > xModel;
+ if (pIt != stlMediaDescriptor.end())
+ pIt->second >>= xModel;
+ if (xModel.is())
+ return E_CAN_BE_SET;
+ LOG_WARNING("LoadEnv::classifyContent()", "loading with object with right URL but invalid object detected")
+ return E_UNSUPPORTED_CONTENT;
+ }
+
+ // following operatons can work on an internal type name only :-(
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory();
+ css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);
+
+ ::rtl::OUString sType = xDetect->queryTypeByURL(sURL);
+
+ css::uno::Sequence< css::beans::NamedValue > lQuery(1) ;
+ css::uno::Reference< css::container::XContainerQuery > xContainer ;
+ css::uno::Reference< css::container::XEnumeration > xSet ;
+ css::uno::Sequence< ::rtl::OUString > lTypesReg(1);
+
+
+ //-------------------------------------------
+ // (iii) If a FrameLoader service (or at least
+ // a Filter) can be found, which supports
+ // this URL - it must be a loadable content.
+ // Because both items are registered for types
+ // its enough to check for frame loaders only.
+ // Mos of our filters are handled by our global
+ // default loader. But there exist some specialized
+ // loader, which does not work on top of filters!
+ // So its not enough to search on the filter configuration.
+ // Further its not enough to search for types!
+ // Because there exist some types, which are referenced by
+ // other objects ... but not by filters nor frame loaders!
+
+ lTypesReg[0] = sType;
+ lQuery[0].Name = ::framework::constant::FrameLoader::PROP_TYPES;
+ lQuery[0].Value <<= lTypesReg;
+
+ xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY);
+ xSet = xContainer->createSubSetEnumerationByProperties(lQuery);
+ // at least one registered frame loader is enough!
+ if (xSet->hasMoreElements())
+ return E_CAN_BE_LOADED;
+
+ //-------------------------------------------
+ // (iv) Some URL protocols are supported by special services.
+ // E.g. ContentHandler.
+ // Such contents can be handled ... but not loaded.
+
+ lTypesReg[0] = sType;
+ lQuery[0].Name = ::framework::constant::ContentHandler::PROP_TYPES;
+ lQuery[0].Value <<= lTypesReg;
+
+ xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY);
+ xSet = xContainer->createSubSetEnumerationByProperties(lQuery);
+ // at least one registered content handler is enough!
+ if (xSet->hasMoreElements())
+ return E_CAN_BE_HANDLED;
+
+ //-------------------------------------------
+ // (v) Last but not least the UCB is used inside office to
+ // load contents. He has a special configuration to know
+ // which URL schemata can be used inside office.
+ css::uno::Reference< css::ucb::XContentProviderManager > xUCB(xSMGR->createInstance(SERVICENAME_UCBCONTENTBROKER), css::uno::UNO_QUERY);
+ if (xUCB->queryContentProvider(sURL).is())
+ return E_CAN_BE_LOADED;
+
+ //-------------------------------------------
+ // (TODO) At this point, we have no idea .-)
+ // But it seems to be better, to break all
+ // further requests for this URL. Otherwhise
+ // we can run into some trouble.
+ LOG_WARNING("LoadEnv::classifyContent()", "realy an unsupported content?")
+ return E_UNSUPPORTED_CONTENT;
+}
+
+
+void LoadEnv::impl_detectTypeAndFilter()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ static ::rtl::OUString TYPEPROP_PREFERREDFILTER(RTL_CONSTASCII_USTRINGPARAM("PreferredFilter"));
+ static ::rtl::OUString FILTERPROP_FLAGS (RTL_CONSTASCII_USTRINGPARAM("Flags"));
+ static sal_Int32 FILTERFLAG_TEMPLATEPATH = 16;
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ // Attention: Because our stl media descriptor is a copy of an uno sequence
+ // we cant use as an in/out parameter here. Copy it before and dont forget to
+ // update structure afterwards again!
+ css::uno::Sequence< css::beans::PropertyValue > lDescriptor = m_lMediaDescriptor.getAsConstPropertyValueList();
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ ::rtl::OUString sType;
+ css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);
+ if (xDetect.is())
+ sType = xDetect->queryTypeByDescriptor(lDescriptor, sal_True); /*TODO should deep detection be able for enable/disable it from outside? */
+
+ // no valid content -> loading not possible
+ if (!sType.getLength())
+ throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+
+ // detection was successfully => update the descriptor member of this class
+ m_lMediaDescriptor << lDescriptor;
+ m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType;
+ // Is there an already detected (may be preselected) filter?
+ // see below ...
+ ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString());
+
+ aWriteLock.unlock();
+ // <- SAFE
+
+ // But the type isnt enough. For loading sometimes we need more informations.
+ // E.g. for our "_default" feature, where we recylce any frame which contains
+ // and "Untitled" document, we must know if the new document is based on a template!
+ // But this information is available as a filter property only.
+ // => We must try(!) to detect the right filter for this load request.
+ // On the other side ... if no filter is available .. ignore it.
+ // Then the type information must be enough.
+ if (!sFilter.getLength())
+ {
+ // no -> try to find a preferred filter for the detected type.
+ // Dont forget to updatet he media descriptor.
+ css::uno::Reference< css::container::XNameAccess > xTypeCont(xDetect, css::uno::UNO_QUERY_THROW);
+ try
+ {
+ ::comphelper::SequenceAsHashMap lTypeProps(xTypeCont->getByName(sType));
+ sFilter = lTypeProps.getUnpackedValueOrDefault(TYPEPROP_PREFERREDFILTER, ::rtl::OUString());
+ if (sFilter.getLength())
+ {
+ // SAFE ->
+ aWriteLock.lock();
+ m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
+ aWriteLock.unlock();
+ // <- SAFE
+ }
+ }
+ catch(const css::container::NoSuchElementException&)
+ {}
+ }
+
+ // check if the filter (if one exists) points to a template format filter.
+ // Then we have to add the property "AsTemplate".
+ // We need this information to decide afterwards if we can use a "recycle frame"
+ // for target "_default" or has to create a new one everytimes.
+ // On the other side we have to supress that, if this property already exists
+ // and should trigger a special handling. Then the outside calli of this method here,
+ // has to know, what he is doing .-)
+
+ sal_Bool bIsOwnTemplate = sal_False;
+ if (sFilter.getLength())
+ {
+ css::uno::Reference< css::container::XNameAccess > xFilterCont(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY_THROW);
+ try
+ {
+ ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter));
+ sal_Int32 nFlags = lFilterProps.getUnpackedValueOrDefault(FILTERPROP_FLAGS, (sal_Int32)0);
+ bIsOwnTemplate = ((nFlags & FILTERFLAG_TEMPLATEPATH) == FILTERFLAG_TEMPLATEPATH);
+ }
+ catch(const css::container::NoSuchElementException&)
+ {}
+ }
+ if (bIsOwnTemplate)
+ {
+ // SAFE ->
+ aWriteLock.lock();
+ // Dont overwrite external decisions! See comments before ...
+ ::comphelper::MediaDescriptor::const_iterator pAsTemplateItem = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_ASTEMPLATE());
+ if (pAsTemplateItem == m_lMediaDescriptor.end())
+ m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_ASTEMPLATE()] <<= sal_True;
+ aWriteLock.unlock();
+ // <- SAFE
+ }
+}
+
+
+sal_Bool LoadEnv::impl_handleContent()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE -> -----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ // the type must exist inside the descriptor ... otherwhise this class is implemented wrong :-)
+ ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString());
+ if (!sType.getLength())
+ throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);
+
+ // convert media descriptor and URL to right format for later interface call!
+ css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
+ m_lMediaDescriptor >> lDescriptor;
+ css::util::URL aURL = m_aURL;
+
+ // get neccessary container to query for a handler object
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory(m_xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY);
+ css::uno::Reference< css::container::XContainerQuery > xQuery (xFactory , css::uno::UNO_QUERY);
+
+ aReadLock.unlock();
+ // <- SAFE -----------------------------------
+
+ // query
+ css::uno::Sequence< ::rtl::OUString > lTypeReg(1);
+ lTypeReg[0] = sType;
+
+ css::uno::Sequence< css::beans::NamedValue > lQuery(1);
+ lQuery[0].Name = ::framework::constant::ContentHandler::PROP_TYPES;
+ lQuery[0].Value <<= lTypeReg;
+
+ css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery);
+ while(xSet->hasMoreElements())
+ {
+ ::comphelper::SequenceAsHashMap lProps (xSet->nextElement());
+ ::rtl::OUString sHandler = lProps.getUnpackedValueOrDefault(::framework::constant::ContentHandler::PROP_NAME, ::rtl::OUString());
+
+ css::uno::Reference< css::frame::XNotifyingDispatch > xHandler;
+ try
+ {
+ xHandler = css::uno::Reference< css::frame::XNotifyingDispatch >(xFactory->createInstance(sHandler), css::uno::UNO_QUERY);
+ if (!xHandler.is())
+ continue;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { continue; }
+
+ // SAFE -> -----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xAsynchronousJob = xHandler;
+ m_pCheck = this;
+ LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this);
+ aWriteLock.unlock();
+ // <- SAFE -----------------------------------
+
+ css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pListener), css::uno::UNO_QUERY);
+ xHandler->dispatchWithNotification(aURL, lDescriptor, xListener);
+
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//-----------------------------------------------
+sal_Bool LoadEnv::impl_furtherDocsAllowed()
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE
+
+ sal_Bool bAllowed = sal_True;
+
+ try
+ {
+ css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
+ xSMGR,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Misc")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MaxOpenDocuments")),
+ ::comphelper::ConfigurationHelper::E_READONLY);
+
+ // NIL means: count of allowed documents = infinite !
+ // => return sal_True
+ if ( ! aVal.hasValue())
+ bAllowed = sal_True;
+ else
+ {
+ sal_Int32 nMaxOpenDocuments = 0;
+ aVal >>= nMaxOpenDocuments;
+
+ css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
+ xSMGR->createInstance(SERVICENAME_DESKTOP),
+ css::uno::UNO_QUERY_THROW);
+
+ FrameListAnalyzer aAnalyzer(xDesktop,
+ css::uno::Reference< css::frame::XFrame >(),
+ FrameListAnalyzer::E_HELP |
+ FrameListAnalyzer::E_BACKINGCOMPONENT |
+ FrameListAnalyzer::E_HIDDEN);
+
+ sal_Int32 nOpenDocuments = aAnalyzer.m_lOtherVisibleFrames.getLength();
+ bAllowed = (nOpenDocuments < nMaxOpenDocuments);
+ }
+ }
+ catch(const css::uno::Exception&)
+ { bAllowed = sal_True; } // !! internal errors are no reason to disturb the office from opening documents .-)
+
+ if ( ! bAllowed )
+ {
+ // SAFE ->
+ aReadLock.lock();
+ css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault(
+ ::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER(),
+ css::uno::Reference< css::task::XInteractionHandler >());
+ aReadLock.unlock();
+ // <- SAFE
+
+ if (xInteraction.is())
+ {
+ css::uno::Any aInteraction;
+ css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations(2);
+
+ comphelper::OInteractionAbort* pAbort = new comphelper::OInteractionAbort();
+ comphelper::OInteractionApprove* pApprove = new comphelper::OInteractionApprove();
+
+ lContinuations[0] = css::uno::Reference< css::task::XInteractionContinuation >(
+ static_cast< css::task::XInteractionContinuation* >(pAbort),
+ css::uno::UNO_QUERY_THROW);
+ lContinuations[1] = css::uno::Reference< css::task::XInteractionContinuation >(
+ static_cast< css::task::XInteractionContinuation* >(pApprove),
+ css::uno::UNO_QUERY_THROW);
+
+ css::task::ErrorCodeRequest aErrorCode;
+ aErrorCode.ErrCode = ERRCODE_SFX_NOMOREDOCUMENTSALLOWED;
+ aInteraction <<= aErrorCode;
+ xInteraction->handle( InteractionRequest::CreateRequest(aInteraction, lContinuations) );
+ }
+ }
+
+ return bAllowed;
+}
+
+//-----------------------------------------------
+sal_Bool LoadEnv::impl_loadContent()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE -> -----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // search or create right target frame
+ ::rtl::OUString sTarget = m_sTarget;
+ if (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT))
+ {
+ m_xTargetFrame = impl_searchAlreadyLoaded();
+ if (m_xTargetFrame.is())
+ {
+ impl_setResult(sal_True);
+ return sal_True;
+ }
+ m_xTargetFrame = impl_searchRecycleTarget();
+ }
+
+ if (! m_xTargetFrame.is())
+ {
+ if (
+ (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_BLANK )) ||
+ (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT))
+ )
+ {
+ if (! impl_furtherDocsAllowed())
+ return sal_False;
+ m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0);
+ m_bCloseFrameOnError = m_xTargetFrame.is();
+ }
+ else
+ {
+ sal_Int32 nFlags = m_nSearchFlags & ~css::frame::FrameSearchFlag::CREATE;
+ m_xTargetFrame = m_xBaseFrame->findFrame(sTarget, nFlags);
+ if (! m_xTargetFrame.is())
+ {
+ if (! impl_furtherDocsAllowed())
+ return sal_False;
+ m_xTargetFrame = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0);
+ m_bCloseFrameOnError = m_xTargetFrame.is();
+ }
+ }
+ }
+
+ // If we couldn't find a valid frame or the frame has no container window
+ // we have to throw an exception.
+ if (
+ ( ! m_xTargetFrame.is() ) ||
+ ( ! m_xTargetFrame->getContainerWindow().is() )
+ )
+ throw LoadEnvException(LoadEnvException::ID_NO_TARGET_FOUND);
+
+ css::uno::Reference< css::frame::XFrame > xTargetFrame = m_xTargetFrame;
+
+ // Now we have a valid frame ... and type detection was already done.
+ // We should apply the module dependend window position and size to the
+ // frame window.
+ impl_applyPersistentWindowState(xTargetFrame->getContainerWindow());
+
+ // Don't forget to lock task for following load process. Otherwise it could die
+ // during this operation runs by terminating the office or closing this task via api.
+ // If we set this lock "close()" will return false and closing will be broken.
+ // Attention: Don't forget to reset this lock again after finishing operation.
+ // Otherwise task AND office couldn't die!!!
+ // This includes gracefully handling of Exceptions (Runtime!) too ...
+ // Thats why we use a specialized guard, which will reset the lock
+ // if it will be run out of scope.
+
+ // Note further: ignore if this internal guard already contains a resource.
+ // Might impl_searchRecylcTarget() set it before. But incase this impl-method wasnt used
+ // and the target frame was new created ... this lock here must be set!
+ css::uno::Reference< css::document::XActionLockable > xTargetLock(xTargetFrame, css::uno::UNO_QUERY);
+ m_aTargetLock.setResource(xTargetLock);
+
+ // Add status indicator to descriptor. Loader can show an progresses then.
+ // But don't do it, if loading should be hidden or preview is used ...!
+ // So we prevent our code against wrong using. Why?
+ // It could be, that using of this progress could make trouble. e.g. He make window visible ...
+ // but shouldn't do that. But if no indicator is available ... nobody has a chance to do that!
+ sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False );
+ sal_Bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED() , sal_False );
+ sal_Bool bPreview = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PREVIEW() , sal_False );
+ css::uno::Reference< css::task::XStatusIndicator > xProgress = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), css::uno::Reference< css::task::XStatusIndicator >());
+
+ if (!bHidden && !bMinimized && !bPreview && !xProgress.is())
+ {
+ // Note: its an optional interface!
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY);
+ if (xProgressFactory.is())
+ {
+ xProgress = xProgressFactory->createStatusIndicator();
+ if (xProgress.is())
+ m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xProgress;
+ }
+ }
+
+ // convert media descriptor and URL to right format for later interface call!
+ css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
+ m_lMediaDescriptor >> lDescriptor;
+ ::rtl::OUString sURL = m_aURL.Complete;
+
+ // try to locate any interested frame loader
+ css::uno::Reference< css::uno::XInterface > xLoader = impl_searchLoader();
+ css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(xLoader, css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XSynchronousFrameLoader > xSyncLoader (xLoader, css::uno::UNO_QUERY);
+
+ if (xAsyncLoader.is())
+ {
+ // SAFE -> -----------------------------------
+ aWriteLock.lock();
+ m_xAsynchronousJob = xAsyncLoader;
+ m_pCheck = this;
+ LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this);
+ aWriteLock.unlock();
+ // <- SAFE -----------------------------------
+
+ css::uno::Reference< css::frame::XLoadEventListener > xListener(static_cast< css::frame::XLoadEventListener* >(pListener), css::uno::UNO_QUERY);
+ xAsyncLoader->load(xTargetFrame, sURL, lDescriptor, xListener);
+
+ return sal_True;
+ }
+ else
+ if (xSyncLoader.is())
+ {
+ sal_Bool bResult = xSyncLoader->load(lDescriptor, xTargetFrame);
+ // react for the result here, so the outside waiting
+ // code can ask for it later.
+ impl_setResult(bResult);
+ // But the return value indicates a valid started(!) operation.
+ // And thats true everxtimes, we reach this line :-)
+ return sal_True;
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE
+
+ return sal_False;
+}
+
+
+css::uno::Reference< css::uno::XInterface > LoadEnv::impl_searchLoader()
+{
+ // SAFE -> -----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ // special mode to set an existing component on this frame
+ // In such case the laoder is fix. It must be the SFX based implementation,
+ // which can create a view on top of such xModel components :-)
+ if (m_eContentType == E_CAN_BE_SET)
+ {
+ try
+ {
+ return m_xSMGR->createInstance(IMPLEMENTATIONNAME_GENERICFRAMELOADER);
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ {}
+ throw LoadEnvException(LoadEnvException::ID_INVALID_ENVIRONMENT);
+ }
+
+ // Otherwhise ...
+ // We need this type information to locate an registered frame loader
+ // Without such information we cant work!
+ ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString());
+ if (!sType.getLength())
+ throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);
+
+ // try to locate any interested frame loader
+ css::uno::Reference< css::lang::XMultiServiceFactory > xLoaderFactory(m_xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY);
+ css::uno::Reference< css::container::XContainerQuery > xQuery (xLoaderFactory , css::uno::UNO_QUERY);
+
+ aReadLock.unlock();
+ // <- SAFE -----------------------------------
+
+ css::uno::Sequence< ::rtl::OUString > lTypesReg(1);
+ lTypesReg[0] = sType;
+
+ css::uno::Sequence< css::beans::NamedValue > lQuery(1);
+ lQuery[0].Name = ::framework::constant::FrameLoader::PROP_TYPES;
+ lQuery[0].Value <<= lTypesReg;
+
+ css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery);
+ while(xSet->hasMoreElements())
+ {
+ // try everyone ...
+ // Ignore any loader, which makes trouble :-)
+ ::comphelper::SequenceAsHashMap lLoaderProps(xSet->nextElement());
+ ::rtl::OUString sLoader = lLoaderProps.getUnpackedValueOrDefault(::framework::constant::FrameLoader::PROP_NAME, ::rtl::OUString());
+ css::uno::Reference< css::uno::XInterface > xLoader ;
+ try
+ {
+ xLoader = xLoaderFactory->createInstance(sLoader);
+ if (xLoader.is())
+ return xLoader;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { continue; }
+ }
+
+ return css::uno::Reference< css::uno::XInterface >();
+}
+
+
+void LoadEnv::impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame,
+ const css::util::URL& aURL )
+{
+ if (! aURL.Mark.getLength())
+ return;
+
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider(xFrame, css::uno::UNO_QUERY);
+ if (! xProvider.is())
+ return;
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE
+
+ css::util::URL aCmd;
+ aCmd.Complete = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:JumpToMark"));
+
+ css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
+ xParser->parseStrict(aCmd);
+
+ css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch(aCmd, SPECIALTARGET_SELF, 0);
+ if (! xDispatcher.is())
+ return;
+
+ ::comphelper::SequenceAsHashMap lArgs;
+ lArgs[::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Bookmark"))] <<= aURL.Mark;
+ xDispatcher->dispatch(aCmd, lArgs.getAsConstPropertyValueList());
+}
+
+
+css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ // such search is allowed for special requests only ...
+ // or better its not allowed for some requests in general :-)
+ if (
+ ( ! TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::E_DEFAULT) ) ||
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) ||
+// (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False) == sal_True) ||
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True)
+ )
+ {
+ return css::uno::Reference< css::frame::XFrame >();
+ }
+
+ // check URL
+ // May its not usefull to start expensive document search, if it
+ // can fail only .. because we load from a stream or model directly!
+ if (
+ (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) ||
+ (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT ))
+ /*TODO should be private:factory here tested too? */
+ )
+ {
+ return css::uno::Reference< css::frame::XFrame >();
+ }
+
+ // otherwhise - iterate through the tasks of the desktop container
+ // to find out, which of them might contains the requested document
+ css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
+ css::uno::Reference< css::container::XIndexAccess > xTaskList(xSupplier->getFrames() , css::uno::UNO_QUERY);
+
+ if (!xTaskList.is())
+ return css::uno::Reference< css::frame::XFrame >(); // task list can be empty!
+
+ // Note: To detect if a document was alrady loaded before
+ // we check URLs here only. But might the existing and the requred
+ // document has different versions! Then its URLs are the same ...
+ sal_Int16 nNewVersion = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int16)(-1));
+
+ // will be used to save the first hidden frame referring the searched model
+ // Normaly we are interested on visible frames ... but if there is no such visible
+ // frame we referr to any hidden frame also (but as fallback only).
+ css::uno::Reference< css::frame::XFrame > xHiddenTask;
+ css::uno::Reference< css::frame::XFrame > xTask;
+
+ sal_Int32 count = xTaskList->getCount();
+ for (sal_Int32 i=0; i<count; ++i)
+ {
+ try
+ {
+ // locate model of task
+ // Note: Without a model there is no chance to decide if
+ // this task contains the searched document or not!
+ xTaskList->getByIndex(i) >>= xTask;
+ if (!xTask.is())
+ continue;
+
+ css::uno::Reference< css::frame::XController > xController = xTask->getController();
+ if (!xController.is())
+ {
+ xTask.clear ();
+ continue;
+ }
+
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
+ if (!xModel.is())
+ {
+ xTask.clear ();
+ continue;
+ }
+
+ // don't check the complete URL here.
+ // use its main part - ignore optional jumpmarks!
+ const ::rtl::OUString sURL = xModel->getURL();
+ if (!::utl::UCBContentHelper::EqualURLs( m_aURL.Main, sURL ))
+ {
+ xTask.clear ();
+ continue;
+ }
+
+ // get the original load arguments from the current document
+ // and decide if its realy the same then the one will be.
+ // It must be visible and must use the same file revision ...
+ // or must not have any file revision set (-1 == -1!)
+ ::comphelper::MediaDescriptor lOldDocDescriptor(xModel->getArgs());
+
+ if (lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int32)(-1)) != nNewVersion)
+ {
+ xTask.clear ();
+ continue;
+ }
+
+ // Hidden frames are special.
+ // They will be used as "last chance" if there is no visible frame pointing to the same model.
+ // Safe the result but continue with current loop might be looking for other visible frames.
+ ::sal_Bool bIsHidden = lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False);
+ if (
+ ( bIsHidden ) &&
+ ( ! xHiddenTask.is())
+ )
+ {
+ xHiddenTask = xTask;
+ xTask.clear ();
+ continue;
+ }
+
+ // We found a visible task pointing to the right model ...
+ // Break search.
+ break;
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { continue; }
+ }
+
+ css::uno::Reference< css::frame::XFrame > xResult;
+ if (xTask.is())
+ xResult = xTask;
+ else
+ if (xHiddenTask.is())
+ xResult = xHiddenTask;
+
+ if (xResult.is())
+ {
+ // Now we are shure, that this task includes the searched document.
+ // It's time to activate it. As special feature we try to jump internaly
+ // if an optional jumpmark is given too.
+ if (m_aURL.Mark.getLength())
+ impl_jumpToMark(xResult, m_aURL);
+
+ // bring it to front and make sure it's visible...
+ impl_makeFrameWindowVisible(xResult->getContainerWindow(), sal_True);
+ }
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ return xResult;
+}
+
+
+sal_Bool LoadEnv::impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const
+{
+ css::uno::Reference< css::document::XActionLockable > xLock(xFrame, css::uno::UNO_QUERY);
+
+ // ? no lock interface ?
+ // Might its an external written frame implementation :-(
+ // Allowing using of it ... but it can fail if its not synchronized with our processes !
+ if (!xLock.is())
+ return sal_False;
+
+ // Otherwhise we have to look for any other existing lock.
+ return xLock->isActionLocked();
+}
+
+
+css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ // SAFE -> ..................................
+ ReadGuard aReadLock(m_aLock);
+
+ // The special backing mode frame will be recycled by definition!
+ // It does'nt matter if somehwere whish to create a new view
+ // or open a new untitled document ...
+ // The only exception form that - hidden frames!
+ if (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False) == sal_True)
+ return css::uno::Reference< css::frame::XFrame >();
+
+ css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
+ FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference< css::frame::XFrame >(), FrameListAnalyzer::E_BACKINGCOMPONENT);
+ if (aTasksAnalyzer.m_xBackingComponent.is())
+ {
+ if (!impl_isFrameAlreadyUsedForLoading(aTasksAnalyzer.m_xBackingComponent))
+ {
+ // bring it to front ...
+ impl_makeFrameWindowVisible(aTasksAnalyzer.m_xBackingComponent->getContainerWindow(), sal_True);
+ return aTasksAnalyzer.m_xBackingComponent;
+ }
+ }
+
+ // These states indicates the wishing for creation of a new view in general.
+ if (
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) ||
+ (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True)
+ )
+ {
+ return css::uno::Reference< css::frame::XFrame >();
+ }
+
+ // On the other side some special URLs will open a new frame everytimes (expecting
+ // they can use the backing-mode frame!)
+ if (
+ (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_FACTORY )) ||
+ (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) ||
+ (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT ))
+ )
+ {
+ return css::uno::Reference< css::frame::XFrame >();
+ }
+
+ // No backing frame! No special URL => recycle active task - if possible.
+ // Means - if it does not already contains a modified document, or
+ // use another office module.
+ css::uno::Reference< css::frame::XFrame > xTask = xSupplier->getActiveFrame();
+
+ // not a real error - but might a focus problem!
+ if (!xTask.is())
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // not a real error - may its a view only
+ css::uno::Reference< css::frame::XController > xController = xTask->getController();
+ if (!xController.is())
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // not a real error - may its a db component instead of a full feartured office document
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
+ if (!xModel.is())
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // get some more informations ...
+
+ // A valid set URL means: there is already a location for this document.
+ // => it was saved there or opened from there. Such Documents can not be used here.
+ // We search for empty document ... created by a private:factory/ URL!
+ if (xModel->getURL().getLength()>0)
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // The old document must be unmodified ...
+ css::uno::Reference< css::util::XModifiable > xModified(xModel, css::uno::UNO_QUERY);
+ if (xModified->isModified())
+ return css::uno::Reference< css::frame::XFrame >();
+
+ Window* pWindow = VCLUnoHelper::GetWindow(xTask->getContainerWindow());
+ if (pWindow && pWindow->IsInModalMode())
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // find out the application type of this document
+ // We can recycle only documents, which uses the same application
+ // then the new one.
+ SvtModuleOptions::EFactory eOldApp = SvtModuleOptions::ClassifyFactoryByModel(xModel);
+ SvtModuleOptions::EFactory eNewApp = SvtModuleOptions::ClassifyFactoryByURL (m_aURL.Complete, m_lMediaDescriptor.getAsConstPropertyValueList());
+
+ aReadLock.unlock();
+ // <- SAFE ..................................
+
+ if (eOldApp != eNewApp)
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // OK this task seams to be useable for recycling
+ // But we should mark it as such - means set an action lock.
+ // Otherwhise it would be used more then ones or will be destroyed
+ // by a close() or terminate() request.
+ // But if such lock already exist ... it means this task is used for
+ // any other operation already. Don't use it then.
+ if (impl_isFrameAlreadyUsedForLoading(xTask))
+ return css::uno::Reference< css::frame::XFrame >();
+
+ // OK - there is a valid target frame.
+ // But may be it contains already a document.
+ // Then we have to ask it, if it allows recylcing of this frame .-)
+ sal_Bool bReactivateOldControllerOnError = sal_False;
+ css::uno::Reference< css::frame::XController > xOldDoc = xTask->getController();
+ if (xOldDoc.is())
+ {
+ bReactivateOldControllerOnError = xOldDoc->suspend(sal_True);
+ if (! bReactivateOldControllerOnError)
+ return css::uno::Reference< css::frame::XFrame >();
+ }
+
+ // SAFE -> ..................................
+ WriteGuard aWriteLock(m_aLock);
+
+ css::uno::Reference< css::document::XActionLockable > xLock(xTask, css::uno::UNO_QUERY);
+ if (!m_aTargetLock.setResource(xLock))
+ return css::uno::Reference< css::frame::XFrame >();
+
+ m_bReactivateControllerOnError = bReactivateOldControllerOnError;
+ aWriteLock.unlock();
+ // <- SAFE ..................................
+
+ // bring it to front ...
+ impl_makeFrameWindowVisible(xTask->getContainerWindow(), sal_True);
+
+ return xTask;
+}
+
+
+void LoadEnv::impl_reactForLoadingState()
+ throw(LoadEnvException, css::uno::RuntimeException)
+{
+ /*TODO reset action locks */
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ if (m_bLoaded)
+ {
+ // Bring the new loaded document to front (if allowed!).
+ // Note: We show new created frames here only.
+ // We dont hide already visible frames here ...
+ css::uno::Reference< css::awt::XWindow > xWindow = m_xTargetFrame->getContainerWindow();
+ sal_Bool bHidden = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False);
+ sal_Bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED(), sal_False);
+
+ if (bMinimized)
+ {
+ SolarMutexGuard aSolarGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ // check for system window is neccessary to guarantee correct pointer cast!
+ if (pWindow && pWindow->IsSystemWindow())
+ ((WorkWindow*)pWindow)->Minimize();
+ }
+ else
+ if (!bHidden)
+ {
+ // show frame ... if it's not still visible ...
+ // But do nothing if it's already visible!
+ impl_makeFrameWindowVisible(xWindow, sal_False);
+ }
+
+ // Note: Only if an existing property "FrameName" is given by this media descriptor,
+ // it should be used. Otherwhise we should do nothing. May be the outside code has already
+ // set a frame name on the target!
+ ::comphelper::MediaDescriptor::const_iterator pFrameName = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FRAMENAME());
+ if (pFrameName != m_lMediaDescriptor.end())
+ {
+ ::rtl::OUString sFrameName;
+ pFrameName->second >>= sFrameName;
+ // Check the name again. e.g. "_default" isnt allowed.
+ // On the other side "_beamer" is a valid name :-)
+ if (TargetHelper::isValidNameForFrame(sFrameName))
+ m_xTargetFrame->setName(sFrameName);
+ }
+ }
+ else if (m_bReactivateControllerOnError)
+ {
+ // Try to reactivate the old document (if any exists!)
+ css::uno::Reference< css::frame::XController > xOldDoc = m_xTargetFrame->getController();
+ // clear does not depend from reactivation state of a might existing old document!
+ // We must make shure, that a might following getTargetComponent() call does not return
+ // the old document!
+ m_xTargetFrame.clear();
+ if (xOldDoc.is())
+ {
+ sal_Bool bReactivated = xOldDoc->suspend(sal_False);
+ if (!bReactivated)
+ throw LoadEnvException(LoadEnvException::ID_COULD_NOT_REACTIVATE_CONTROLLER);
+ m_bReactivateControllerOnError = sal_False;
+ }
+ }
+ else if (m_bCloseFrameOnError)
+ {
+ // close empty frames
+ css::uno::Reference< css::util::XCloseable > xCloseable (m_xTargetFrame, css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XComponent > xDisposable(m_xTargetFrame, css::uno::UNO_QUERY);
+
+ try
+ {
+ if (xCloseable.is())
+ xCloseable->close(sal_True);
+ else
+ if (xDisposable.is())
+ xDisposable->dispose();
+ }
+ catch(const css::util::CloseVetoException&)
+ {}
+ catch(const css::lang::DisposedException&)
+ {}
+ m_xTargetFrame.clear();
+ }
+
+ // This max force an implicit closing of our target frame ...
+ // e.g. in case close(sal_True) was called before and the frame
+ // kill itself if our external use-lock is released here!
+ // Thats why we releas this lock AFTER ALL OPERATIONS on this frame
+ // are finished. The frame itslef must handle then
+ // this situation gracefully.
+ m_aTargetLock.freeResource();
+
+ // Last but not least :-)
+ // We have to clear the current media descriptor.
+ // Otherwhise it hold a might existing stream open!
+ m_lMediaDescriptor.clear();
+
+ css::uno::Any aRequest;
+ bool bThrow = false;
+ if ( !m_bLoaded && m_pQuietInteraction && m_pQuietInteraction->wasUsed() )
+ {
+ aRequest = m_pQuietInteraction->getRequest();
+ m_pQuietInteraction->release();
+ m_pQuietInteraction = 0;
+ bThrow = true;
+ }
+
+ aReadLock.unlock();
+
+ if (bThrow)
+ {
+ if ( aRequest.isExtractableTo( ::cppu::UnoType< css::uno::Exception >::get() ) )
+ throw LoadEnvException( LoadEnvException::ID_GENERAL_ERROR, aRequest );
+ }
+
+ // <- SAFE ----------------------------------
+}
+
+
+void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow ,
+ sal_Bool bForceToFront)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY );
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ SolarMutexGuard aSolarGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ if ( pWindow )
+ {
+ bool bForceFrontAndFocus(false);
+ css::uno::Any a = ::comphelper::ConfigurationHelper::readDirectKey(
+ xSMGR,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/View")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NewDocumentHandling")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ForceFocusAndToFront")),
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ a >>= bForceFrontAndFocus;
+
+ if( pWindow->IsVisible() && (bForceFrontAndFocus || bForceToFront) )
+ pWindow->ToTop();
+ else
+ pWindow->Show(sal_True, (bForceFrontAndFocus || bForceToFront) ? SHOW_FOREGROUNDTASK : 0 );
+ }
+}
+
+
+void LoadEnv::impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow)
+{
+ static ::rtl::OUString PACKAGE_SETUP_MODULES(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Setup/Office/Factories"));
+
+ // no window -> action not possible
+ if (!xWindow.is())
+ return;
+
+ // window already visible -> do nothing! If we use a "recycle frame" for loading ...
+ // the current position and size must be used.
+ css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xWindow, css::uno::UNO_QUERY);
+ if (
+ (xVisibleCheck.is() ) &&
+ (xVisibleCheck->isVisible())
+ )
+ return;
+
+ // SOLAR SAFE ->
+ SolarMutexClearableGuard aSolarGuard1;
+
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ if (!pWindow)
+ return;
+
+ sal_Bool bSystemWindow = pWindow->IsSystemWindow();
+ sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW);
+
+ if (!bSystemWindow && !bWorkWindow)
+ return;
+
+ // dont overwrite this special state!
+ WorkWindow* pWorkWindow = (WorkWindow*)pWindow;
+ if (pWorkWindow->IsMinimized())
+ return;
+
+ aSolarGuard1.clear();
+ // <- SOLAR SAFE
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ // no filter -> no module -> no persistent window state
+ ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(
+ ::comphelper::MediaDescriptor::PROP_FILTERNAME(),
+ ::rtl::OUString());
+ if (!sFilter.getLength())
+ return;
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ try
+ {
+ // retrieve the module name from the filter configuration
+ css::uno::Reference< css::container::XNameAccess > xFilterCfg(
+ xSMGR->createInstance(SERVICENAME_FILTERFACTORY),
+ css::uno::UNO_QUERY_THROW);
+ ::comphelper::SequenceAsHashMap lProps (xFilterCfg->getByName(sFilter));
+ ::rtl::OUString sModule = lProps.getUnpackedValueOrDefault(FILTER_PROPNAME_DOCUMENTSERVICE, ::rtl::OUString());
+
+ // get access to the configuration of this office module
+ css::uno::Reference< css::container::XNameAccess > xModuleCfg(::comphelper::ConfigurationHelper::openConfig(
+ xSMGR,
+ PACKAGE_SETUP_MODULES,
+ ::comphelper::ConfigurationHelper::E_READONLY),
+ css::uno::UNO_QUERY_THROW);
+
+ // read window state from the configuration
+ // and apply it on the window.
+ // Do nothing, if no configuration entry exists!
+ ::rtl::OUString sWindowState ;
+ ::comphelper::ConfigurationHelper::readRelativeKey(xModuleCfg, sModule, OFFICEFACTORY_PROPNAME_WINDOWATTRIBUTES) >>= sWindowState;
+ if (sWindowState.getLength())
+ {
+ // SOLAR SAFE ->
+ SolarMutexGuard aSolarGuard;
+
+ // We have to retrieve the window pointer again. Because nobody can guarantee
+ // that the XWindow was not disposed inbetween .-)
+ // But if we get a valid pointer we can be sure, that it's the system window pointer
+ // we already checked and used before. Because nobody recylce the same uno reference for
+ // a new internal c++ implementation ... hopefully .-))
+ Window* pWindowCheck = VCLUnoHelper::GetWindow(xWindow);
+ if (! pWindowCheck)
+ return;
+
+ SystemWindow* pSystemWindow = (SystemWindow*)pWindowCheck;
+ pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8));
+ // <- SOLAR SAFE
+ }
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/loadenv/targethelper.cxx b/framework/source/loadenv/targethelper.cxx
new file mode 100644
index 000000000000..d761556e744e
--- /dev/null
+++ b/framework/source/loadenv/targethelper.cxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// own includes
+
+#include <loadenv/targethelper.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//_______________________________________________
+// declarations
+
+/*-----------------------------------------------
+ 05.08.2003 09:08
+-----------------------------------------------*/
+sal_Bool TargetHelper::matchSpecialTarget(const ::rtl::OUString& sCheckTarget ,
+ ESpecialTarget eSpecialTarget)
+{
+ switch(eSpecialTarget)
+ {
+ case E_SELF :
+ return (
+ (!sCheckTarget.getLength() ) ||
+ (sCheckTarget.equals(SPECIALTARGET_SELF))
+ );
+
+ case E_PARENT :
+ return (sCheckTarget.equals(SPECIALTARGET_PARENT));
+
+ case E_TOP :
+ return (sCheckTarget.equals(SPECIALTARGET_TOP));
+
+ case E_BLANK :
+ return (sCheckTarget.equals(SPECIALTARGET_BLANK));
+
+ case E_DEFAULT :
+ return (sCheckTarget.equals(SPECIALTARGET_DEFAULT));
+
+ case E_BEAMER :
+ return (sCheckTarget.equals(SPECIALTARGET_BEAMER));
+
+ case E_MENUBAR :
+ return (sCheckTarget.equals(SPECIALTARGET_MENUBAR));
+
+ case E_HELPAGENT :
+ return (sCheckTarget.equals(SPECIALTARGET_HELPAGENT));
+
+ case E_HELPTASK :
+ return (sCheckTarget.equals(SPECIALTARGET_HELPTASK));
+ default:
+ return sal_False;
+ }
+
+ return sal_False;
+}
+
+/*-----------------------------------------------
+ 05.08.2003 09:17
+-----------------------------------------------*/
+sal_Bool TargetHelper::isValidNameForFrame(const ::rtl::OUString& sName)
+{
+ // some special targets are realy special ones :-)
+ // E.g. the are realy used to locate one frame inside the frame tree.
+ if (
+ (!sName.getLength() ) ||
+ (TargetHelper::matchSpecialTarget(sName, E_HELPTASK)) ||
+ (TargetHelper::matchSpecialTarget(sName, E_BEAMER) )
+ )
+ return sal_True;
+
+ // all other names must be checked more general
+ // special targets starts with a "_".
+ return (sName.indexOf('_') != 0);
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/lomenubar/AwtKeyToDbusmenuString.cxx b/framework/source/lomenubar/AwtKeyToDbusmenuString.cxx
new file mode 100644
index 000000000000..4fd377db75ce
--- /dev/null
+++ b/framework/source/lomenubar/AwtKeyToDbusmenuString.cxx
@@ -0,0 +1,145 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#define XK_MISCELLANY
+#define XK_LATIN1
+#define XK_PUBLISHING
+
+#include <X11/Xlib.h>
+#include <X11/keysymdef.h>
+
+#include <glib.h>
+
+#include <com/sun/star/awt/Key.hpp>
+
+using namespace ::com::sun::star;
+
+KeySym MapAwtToXKey (guint16 aKeyCode);
+
+gchar*
+AwtKeyToDbusmenuString (guint16 aKeyCode)
+{
+ KeySym code = (KeySym)0;
+
+ if (!aKeyCode)
+ return NULL;
+
+ //We try the consecutive ranges first, if the code is not there
+ //we use MapAwtToXKey(), se below
+ if (aKeyCode >= awt::Key::A && aKeyCode <= awt::Key::Z)
+ code = (KeySym)aKeyCode - (KeySym)awt::Key::A + XK_A;
+ else if (aKeyCode >= awt::Key::F1 && aKeyCode <= awt::Key::F26)
+ code = (KeySym)aKeyCode - (KeySym)awt::Key::F1 + XK_F1;
+ else if (aKeyCode >= awt::Key::NUM0 && aKeyCode <= awt::Key::NUM9)
+ code = (KeySym)aKeyCode - (KeySym)awt::Key::NUM0 + XK_0;
+ else
+ code = MapAwtToXKey (aKeyCode);
+
+ if (code == 0)
+ return NULL;
+
+ return XKeysymToString (code);;
+}
+
+
+//This is a 1-1 mapper between com::sun::star::awt:Key values and X11 KeySyms
+//note that some symbols are missing
+KeySym
+MapAwtToXKey (guint16 aKeyCode)
+{
+ switch (aKeyCode)
+ {
+ case awt::Key::UP:
+ return XK_Up;
+ case awt::Key::DOWN:
+ return XK_Down;
+ case awt::Key::LEFT:
+ return XK_Left;
+ case awt::Key::RIGHT:
+ return XK_Right;
+ case awt::Key::HOME:
+ return XK_Home;
+ case awt::Key::END:
+ return XK_End;
+ case awt::Key::PAGEUP:
+ return XK_Page_Up;
+ case awt::Key::PAGEDOWN:
+ return XK_Page_Down;
+ case awt::Key::RETURN:
+ return XK_Return;
+ case awt::Key::ESCAPE:
+ return XK_Escape;
+ case awt::Key::TAB:
+ return XK_Tab;
+ case awt::Key::BACKSPACE:
+ return XK_BackSpace;
+ case awt::Key::SPACE:
+ return XK_space;
+ case awt::Key::INSERT:
+ return XK_Insert;
+ case awt::Key::DELETE:
+ return XK_Delete;
+ case awt::Key::ADD:
+ return XK_plus;
+ case awt::Key::SUBTRACT:
+ return XK_minus;
+ case awt::Key::MULTIPLY:
+ return XK_asterisk;
+ case awt::Key::DIVIDE:
+ return XK_slash;
+ case awt::Key::POINT:
+ return XK_period;
+ case awt::Key::COMMA:
+ return XK_comma;
+ case awt::Key::LESS:
+ return XK_less;
+ case awt::Key::GREATER:
+ return XK_greater;
+ case awt::Key::EQUAL:
+ return XK_equal;
+ case awt::Key::UNDO:
+ return XK_Undo;
+ case awt::Key::REPEAT:
+ return XK_Redo;
+ case awt::Key::FIND:
+ return XK_Find;
+ case awt::Key::DECIMAL:
+ return XK_decimalpoint;
+ case awt::Key::TILDE:
+ return XK_asciitilde;
+ case awt::Key::QUOTELEFT:
+ return XK_leftsinglequotemark;
+ //Sun keys and other unsupported symbols
+ case awt::Key::OPEN:
+ case awt::Key::CUT:
+ case awt::Key::COPY:
+ case awt::Key::PASTE:
+ case awt::Key::PROPERTIES:
+ case awt::Key::FRONT:
+ case awt::Key::CONTEXTMENU:
+ case awt::Key::HELP:
+ case awt::Key::MENU:
+ default:
+ return 0;
+ }
+}
diff --git a/framework/source/lomenubar/AwtKeyToDbusmenuString.hxx b/framework/source/lomenubar/AwtKeyToDbusmenuString.hxx
new file mode 100644
index 000000000000..faa61b6dbaa5
--- /dev/null
+++ b/framework/source/lomenubar/AwtKeyToDbusmenuString.hxx
@@ -0,0 +1,33 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef __AWT_KEY_TO_DBUSMENU_STRING_HXX__
+#define __AWT_KEY_TO_DBUSMENU_STRING_HXX__
+#include <X11/X.h>
+#include <glib.h>
+
+gchar*
+AwtKeyToDbusmenuString (guint16 aKeyCode);
+
+
+#endif //__AWT_KEY_TO_DBUSMENU_STRING_HXX__
diff --git a/framework/source/lomenubar/DesktopJob.cxx b/framework/source/lomenubar/DesktopJob.cxx
new file mode 100644
index 000000000000..6d94368a3ac3
--- /dev/null
+++ b/framework/source/lomenubar/DesktopJob.cxx
@@ -0,0 +1,161 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "DesktopJob.hxx"
+#include "FrameJob.hxx"
+
+#include <gio/gio.h>
+//#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#include <libdbusmenu-glib/server.h>
+#pragma GCC diagnostic error "-Wignored-qualifiers"
+//#pragma GCC diagnostic pop
+
+#include <rtl/process.h>
+#include <osl/diagnose.h>
+#include <cppuhelper/implbase1.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/document/EventObject.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+
+using rtl::OUString;
+using com::sun::star::beans::XPropertySet;
+using com::sun::star::beans::NamedValue;
+using com::sun::star::document::XEventListener;
+using com::sun::star::document::XEventBroadcaster;
+using com::sun::star::frame::XFrame;
+using com::sun::star::frame::XFramesSupplier;
+using com::sun::star::frame::XFrameActionListener;
+using com::sun::star::frame::XModel;
+using com::sun::star::frame::XLayoutManager;
+using com::sun::star::frame::FrameActionEvent;
+using com::sun::star::frame::XFrameActionListener;
+using com::sun::star::lang::IllegalArgumentException;
+using com::sun::star::lang::XMultiServiceFactory;
+using com::sun::star::lang::EventObject;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::Exception;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::UNO_QUERY_THROW;
+using com::sun::star::uno::XInterface;
+
+//-------------------------- D-Bus Callbacks ----------------------------------
+static void
+on_bus (GDBusConnection * /*connection*/,
+ const gchar * /*name*/,
+ gpointer /*user_data*/)
+{
+ //TODO: Should we actually do something here?
+ return;
+}
+
+static void
+name_lost (GDBusConnection * /*connection*/, const gchar * name, gpointer /*user_data*/)
+{
+ g_error ("Unable to get name '%s' on DBus", name);
+ return;
+}
+
+// --------------------------- DesktopJob ----------------------------------
+Any SAL_CALL DesktopJob::execute( const Sequence< NamedValue >& /*aArguments*/ )
+ throw ( IllegalArgumentException, Exception, RuntimeException )
+{
+ g_type_init ();
+
+ g_bus_own_name(G_BUS_TYPE_SESSION,
+ LIBREOFFICE_BUSNAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus,
+ NULL,
+ name_lost,
+ NULL,
+ NULL);
+
+ return Any ();
+}
+
+OUString
+DesktopJob_getImplementationName ()
+ throw (RuntimeException)
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( DESKTOPJOB_IMPLEMENTATION_NAME ) );
+}
+
+sal_Bool SAL_CALL
+DesktopJob_supportsService( const OUString& ServiceName )
+ throw (RuntimeException)
+{
+ return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( DESKTOPJOB_SERVICE_NAME ) );
+}
+
+Sequence< OUString > SAL_CALL
+DesktopJob_getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ Sequence < OUString > aRet(1);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( DESKTOPJOB_SERVICE_NAME ) );
+ return aRet;
+}
+
+Reference< XInterface > SAL_CALL
+DesktopJob_createInstance( const Reference< XMultiServiceFactory > & rSMgr)
+ throw( Exception )
+{
+ return (cppu::OWeakObject*) new DesktopJob(rSMgr);
+}
+
+// XServiceInfo
+OUString SAL_CALL
+DesktopJob::getImplementationName()
+ throw (RuntimeException)
+{
+ return DesktopJob_getImplementationName();
+}
+
+sal_Bool SAL_CALL
+DesktopJob::supportsService( const OUString& rServiceName )
+ throw (RuntimeException)
+{
+ return DesktopJob_supportsService( rServiceName );
+}
+
+Sequence< OUString > SAL_CALL
+DesktopJob::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return DesktopJob_getSupportedServiceNames();
+}
diff --git a/framework/source/lomenubar/DesktopJob.hxx b/framework/source/lomenubar/DesktopJob.hxx
new file mode 100644
index 000000000000..9d8cb3e3f031
--- /dev/null
+++ b/framework/source/lomenubar/DesktopJob.hxx
@@ -0,0 +1,90 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef __DESKTOP_JOB_HXX__
+#define __DESKTOP_JOB_HXX__
+
+#include <glib.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+#define LIBREOFFICE_BUSNAME "org.libreoffice.dbusmenu"
+#define DESKTOPJOB_IMPLEMENTATION_NAME "org.libreoffice.comp.framework.lomenubar.DesktopJob"
+#define DESKTOPJOB_SERVICE_NAME "com.sun.star.task.Job"
+
+namespace css = ::com::sun::star;
+using css::uno::Reference;
+using css::uno::Sequence;
+using css::uno::Any;
+using css::uno::Exception;
+using css::uno::RuntimeException;
+using css::lang::IllegalArgumentException;
+
+class DesktopJob : public cppu::WeakImplHelper2 < css::task::XJob, css::lang::XServiceInfo >
+{
+ private:
+ Reference< css::lang::XMultiServiceFactory > mxMSF;
+
+ public:
+ DesktopJob( const Reference< css::lang::XMultiServiceFactory > &rxMSF)
+ : mxMSF( rxMSF ) {}
+
+ virtual ~DesktopJob() {}
+
+ // XJob
+ virtual Any SAL_CALL execute(const css::uno::Sequence< css::beans::NamedValue >& Arguments)
+ throw (IllegalArgumentException, Exception, RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (RuntimeException);
+
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (RuntimeException);
+};
+
+
+::rtl::OUString
+DesktopJob_getImplementationName()
+ throw ( RuntimeException );
+
+sal_Bool SAL_CALL
+DesktopJob_supportsService( const ::rtl::OUString& ServiceName )
+ throw ( RuntimeException );
+
+Sequence< ::rtl::OUString > SAL_CALL
+DesktopJob_getSupportedServiceNames()
+ throw ( RuntimeException );
+
+Reference< css::uno::XInterface >
+SAL_CALL DesktopJob_createInstance( const css::uno::Reference< css::lang::XMultiServiceFactory > & rSMgr)
+ throw ( Exception );
+
+#endif //__DESKTOP_JOB_HXX__
+
diff --git a/framework/source/lomenubar/FrameHelper.cxx b/framework/source/lomenubar/FrameHelper.cxx
new file mode 100644
index 000000000000..7b749648d34c
--- /dev/null
+++ b/framework/source/lomenubar/FrameHelper.cxx
@@ -0,0 +1,862 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "FrameHelper.hxx"
+#include "AwtKeyToDbusmenuString.hxx"
+#include "MenuItemInfo.hxx"
+#include "MenuItemStatusListener.hxx"
+
+#include <boost/foreach.hpp>
+
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/awt/SystemDependentXWindow.hpp>
+#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/awt/Key.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/awt/MenuEvent.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/awt/XPopupMenu.hpp>
+#include <com/sun/star/awt/XMenuExtended.hpp>
+#include <com/sun/star/awt/XMenuListener.hpp>
+#include <com/sun/star/awt/XPopupMenuExtended.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchHelper.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/frame/XPopupMenuController.hpp>
+#include <com/sun/star/frame/FrameAction.hpp>
+#include <com/sun/star/frame/FrameActionEvent.hpp>
+#include <com/sun/star/lang/SystemDependent.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/ui/XUIElement.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <rtl/process.h>
+
+#include <gio/gio.h>
+//#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#include <libdbusmenu-glib/client.h>
+#pragma GCC diagnostic error "-Wignored-qualifiers"
+//#pragma GCC diagnostic pop
+#include <libdbusmenu-gtk/menuitem.h>
+
+using rtl::OUString;
+using rtl::OString;
+using rtl::OUStringToOString;
+
+using namespace ::com::sun::star;
+
+using com::sun::star::awt::KeyEvent;
+using com::sun::star::awt::MenuEvent;
+using com::sun::star::awt::SystemDependentXWindow;
+using com::sun::star::awt::XMenuListener;
+using com::sun::star::awt::XMenuExtended;
+using com::sun::star::awt::XMenuListener;
+using com::sun::star::awt::MenuEvent;
+using com::sun::star::awt::XPopupMenu;
+using com::sun::star::awt::XPopupMenuExtended;
+using com::sun::star::awt::XSystemDependentWindowPeer;
+using com::sun::star::awt::XWindow2;
+using com::sun::star::beans::XPropertySet;
+using com::sun::star::beans::PropertyValue;
+using com::sun::star::container::XNameAccess;
+using com::sun::star::container::NoSuchElementException;
+using com::sun::star::frame::XController;
+using com::sun::star::frame::XComponentLoader;
+using com::sun::star::frame::XDispatch;
+using com::sun::star::frame::XDispatchProvider;
+using com::sun::star::frame::XDispatchHelper;
+using com::sun::star::frame::XModel;
+using com::sun::star::frame::XModuleManager;
+using com::sun::star::frame::XLayoutManager;
+using com::sun::star::frame::XPopupMenuController;
+using com::sun::star::lang::SystemDependent::SYSTEM_XWINDOW;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::UNO_QUERY_THROW;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::XComponentContext;
+using com::sun::star::uno::XInterface;
+using com::sun::star::ui::XUIElement;
+using com::sun::star::ui::XUIConfigurationManager;
+using com::sun::star::ui::XUIConfigurationManagerSupplier;
+using com::sun::star::ui::XAcceleratorConfiguration;
+using com::sun::star::ui::XModuleUIConfigurationManagerSupplier;
+using com::sun::star::util::URL;
+using com::sun::star::util::XURLTransformer;
+
+
+namespace
+{
+ static Sequence<Any> lcl_initArgs(const OUString& sModuleName, const Reference<XFrame> xFrame)
+ {
+ // These are the arguments needed for the XPopupMenuController
+ Sequence<Any> aResult(2);
+ PropertyValue item;
+
+ item.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleName"));
+ item.Value <<= sModuleName;
+ aResult[0] <<= item;
+
+ item.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Frame"));
+ item.Value <<= xFrame;
+ aResult[1] <<= item;
+ return aResult;
+ };
+
+ struct DispatchConnection
+ {
+ Reference<XDispatch> m_xDispatch;
+ URL m_aUrl;
+ DispatchConnection(Reference<XDispatch> xDispatch, URL aUrl)
+ : m_xDispatch(xDispatch), m_aUrl(aUrl)
+ {}
+ };
+}
+
+namespace framework { namespace lomenubar
+{
+ class DispatchRegistry
+ {
+ private:
+ ::std::vector<DispatchConnection> m_vDispatchConnections;
+ const Reference<XStatusListener> m_xStatusListener;
+ public:
+ DispatchRegistry(const Reference<XStatusListener> xStatusListener)
+ : m_xStatusListener(xStatusListener)
+ {}
+ ~DispatchRegistry()
+ {
+ BOOST_FOREACH(const DispatchConnection& rConnection, m_vDispatchConnections)
+ {
+ rConnection.m_xDispatch->removeStatusListener(m_xStatusListener, rConnection.m_aUrl);
+ }
+ }
+ void Connect(Reference<XDispatch> xDispatch, URL aURL)
+ {
+ const DispatchConnection connection(xDispatch, aURL);
+ m_vDispatchConnections.push_back(connection);
+ xDispatch->addStatusListener(m_xStatusListener, aURL);
+ }
+ };
+}}
+
+// ------------------------ Item callbacks ---------------------------
+// Item activated. It distpatches the command associated to a given menu item.
+void
+item_activated (DbusmenuMenuitem *item, guint /*timestamp*/, gpointer user_data)
+{
+ FrameHelper *helper = (FrameHelper*)user_data;
+ OUString command = OUString::createFromAscii(dbusmenu_menuitem_property_get (item, "CommandURL"));
+ helper->dispatchCommand (command);
+}
+
+// Rebuilds the submenu
+gboolean
+item_about_to_show (DbusmenuMenuitem *item, gpointer user_data)
+{
+ //Get the XMenu interface for the MenuBar UIElement
+ FrameHelper *helper = (FrameHelper*)user_data;
+ Reference < XFrame > xFrame = helper->getFrame ();
+ Reference< XPropertySet > frameProps (xFrame, UNO_QUERY);
+ Reference < XLayoutManager > xLayoutManager(frameProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LayoutManager"))),
+ UNO_QUERY);
+ Reference < XUIElement > menuBar(xLayoutManager->getElement (OUString(RTL_CONSTASCII_USTRINGPARAM("private:resource/menubar/menubar"))),
+ UNO_QUERY);
+ Reference < XPropertySet > menuPropSet (menuBar, UNO_QUERY);
+
+ if (!menuPropSet.is ())
+ {
+ return FALSE;
+ }
+
+ Reference < XMenu > xMenu(menuPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("XMenuBar"))),
+ UNO_QUERY);
+ if (!xMenu.is())
+ {
+ return FALSE;
+ }
+
+ //Find xMenu for the first level item
+ Reference < XMenu > xSubMenu;
+ Reference < XMenuExtended > xMenuEx (xMenu, UNO_QUERY);
+ guint16 root_count = xMenu->getItemCount();
+ for (guint16 i = 0; i<root_count ;i++)
+ {
+
+ guint16 id = xMenu->getItemId (i);
+ if (id == 0)
+ continue;
+
+ OUString command = xMenuEx->getCommand (id);
+
+ //We must find the element with the same command URL
+ if (! OUString::createFromAscii (dbusmenu_menuitem_property_get (item, "CommandURL")).equals (command))
+ continue;
+
+ Reference <XPopupMenu> subPopup (xMenu->getPopupMenu (id), UNO_QUERY);
+ xSubMenu = Reference <XMenu> (subPopup, UNO_QUERY);
+ break;
+ }
+
+ //We only do this for toplevel items
+ if (xSubMenu.is ())
+ {
+ helper->rebuildMenu (xSubMenu, item);
+ return FALSE;
+ }
+
+ //If it is not a toplevel item we stop trying to rebuild
+ return TRUE;
+}
+
+void
+destroy_menuitem (gpointer data)
+{
+ g_object_unref (G_OBJECT (data));
+}
+
+void
+destroy_menu_item_info (gpointer data)
+{
+ delete (MenuItemInfo*)data;
+}
+
+// ------------------------ FrameHelper Class -------------------------------
+FrameHelper::FrameHelper(const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& xFrame,
+ DbusmenuServer* server)
+ : m_xStatusListener(new MenuItemStatusListener(this))
+ , m_pDispatchRegistry(new framework::lomenubar::DispatchRegistry(m_xStatusListener))
+ , m_xMSF(rServiceManager)
+ , m_xTrans(m_xMSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer" ))), UNO_QUERY)
+ , m_xMM(m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.ModuleManager"))),UNO_QUERY)
+ , m_xPCF(m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.PopupMenuControllerFactory"))), UNO_QUERY)
+ , m_xFrame(xFrame)
+ , m_xdp(xFrame, UNO_QUERY)
+ , m_args(lcl_initArgs(m_xMM->identify(xFrame), xFrame))
+ , m_server(server)
+ , m_root(NULL)
+ , m_watcher_set(FALSE)
+ , m_blockDetach(FALSE)
+{
+
+ //Get xUICommands database (to retrieve labels, see FrameJob::getLabelFromCommandURL ())
+ Reference < XNameAccess > xNameAccess (m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.UICommandDescription"))),
+ UNO_QUERY);
+ xNameAccess->getByName(m_xMM->identify(xFrame)) >>= m_xUICommands;
+
+
+ // This initializes the shortcut database
+ getAcceleratorConfigurations (xFrame->getController()->getModel (), m_xMM);
+
+ // This is a hash table that maps Command URLs to MenuItemInfo classes
+ // to cache command information
+ m_commandsInfo = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ destroy_menu_item_info);
+
+}
+
+void SAL_CALL
+FrameHelper::disposing (const EventObject& /*aEvent*/ ) throw (RuntimeException)
+{}
+
+FrameHelper::~FrameHelper()
+{
+ ::boost::scoped_ptr< ::framework::lomenubar::DispatchRegistry>().swap(m_pDispatchRegistry);
+ if (m_server)
+ g_object_unref (m_server);
+
+ if (m_watcher_set)
+ g_bus_unwatch_name (m_watcher);
+
+ g_hash_table_destroy (m_commandsInfo);
+}
+
+void
+FrameHelper::setRootItem (DbusmenuMenuitem *root)
+{
+ this->m_root = root;
+}
+
+void
+FrameHelper::setRegistrarWatcher (guint watcher)
+{
+ m_watcher_set = TRUE;
+ this->m_watcher = watcher;
+}
+
+void
+FrameHelper::setServer (DbusmenuServer *server)
+{
+ this->m_server = server;
+}
+
+//Getters
+Reference < XFrame >
+FrameHelper::getFrame ()
+{
+ return m_xFrame;
+}
+
+GHashTable*
+FrameHelper::getCommandsInfo ()
+{
+ return m_commandsInfo;
+}
+
+unsigned long
+FrameHelper::getXID ()
+{
+ Reference< XSystemDependentWindowPeer > xWin( m_xFrame->getContainerWindow(), UNO_QUERY );
+
+ if (!xWin.is())
+ return 0;
+
+ sal_Int8 processID[16];
+ rtl_getGlobalProcessId( (sal_uInt8*)processID );
+ Sequence <signed char> pidSeq (processID, 16);
+
+ SystemDependentXWindow xWindow;
+ xWin->getWindowHandle (pidSeq, SYSTEM_XWINDOW) >>= xWindow;
+
+ return xWindow.WindowHandle;
+}
+
+void SAL_CALL
+FrameHelper::frameAction(const FrameActionEvent& action) throw (RuntimeException)
+{
+ //If theh component is detached from the frame, remove this action listener,
+ //it is then disposed and destroyed by the frame. We deregister the window
+ //from the AppMenu Registrar
+
+ //This is a special case, .uno:printPreview detaches the component but we are
+ //not actually switching to another document.
+ if (m_blockDetach)
+ {
+ m_blockDetach = TRUE;
+ return;
+ }
+
+ if (action.Action == frame::FrameAction_COMPONENT_DETACHING)
+ {
+ GError *error = NULL;
+
+
+ m_xFrame->removeFrameActionListener (this);
+ Reference< XPropertySet > frameProps (m_xFrame, UNO_QUERY);
+ Reference < XLayoutManager > xLayoutManager(frameProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LayoutManager"))),
+ UNO_QUERY);
+ xLayoutManager->showElement (OUString(RTL_CONSTASCII_USTRINGPARAM("private:resource/menubar/menubar")));
+
+ unsigned long xid = getXID();
+
+ GDBusProxy *proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "com.canonical.AppMenu.Registrar",
+ "/com/canonical/AppMenu/Registrar",
+ "com.canonical.AppMenu.Registrar",
+ NULL,
+ &error);
+ if (error)
+ {
+ g_warning ("Couldn't get /com/canonical/AppMenu/Registrar proxy");
+ g_error_free (error);
+ return;
+ }
+
+ //TODO: Check if window is registered already
+ g_dbus_proxy_call_sync (proxy,
+ "UnregisterWindow",
+ g_variant_new ("(u)", (guint32)xid),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ g_warning ("Couldn't call /com/canonical/AppMenu/Registrar.UnregisterWindow");
+ g_error_free (error);
+ }
+
+ if (m_server)
+ {
+ g_object_unref (m_server);
+ m_server = NULL;
+ m_root = NULL;
+ }
+
+ if (m_watcher_set)
+ {
+ g_bus_unwatch_name (m_watcher);
+ m_watcher_set = FALSE;
+ }
+
+ return;
+ }
+}
+
+//This function rebuilds (or builds from scratch) a DbusmenuMenuitem structure
+//from a given pair of XMenu/Dbusmenuitem.
+void
+FrameHelper::rebuildMenu (Reference < XMenu > xMenu,
+ DbusmenuMenuitem *parent)
+{
+ g_return_if_fail (parent != NULL);
+ GList *items = dbusmenu_menuitem_get_children (parent);
+ guint nitems = g_list_length (items); //number of available Dbusmenuitems
+ guint16 count = xMenu->getItemCount (); //number of real menu items
+
+ // One item does not represent always the same command.
+ // We do this for performance reasons, as it's really hard to match a command with
+ // a single dbusmenuitem given the lack of information provided by the status listener
+ if (count > nitems)
+ {
+ // Add enough Dbusmenuitems to replicate all
+ for (guint16 i = 0; i < (count - nitems); i++)
+ {
+ DbusmenuMenuitem *item = dbusmenu_menuitem_new ();
+ dbusmenu_menuitem_child_append (parent, item);
+ g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(item_activated), this);
+ }
+ items = dbusmenu_menuitem_get_children (parent);
+ }
+ if (count < nitems)
+ {
+ // If there is an excess of Dbusmenuitems we make them invisible
+ for (guint16 i = nitems - 1; i >= count; i--)
+ {
+ DbusmenuMenuitem *item = DBUSMENU_MENUITEM (g_list_nth_data(items, i));
+ dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
+ }
+ }
+
+ for (guint16 i = 0; i<count; i++)
+ {
+ Reference < XMenuExtended > xMenuEx (xMenu, UNO_QUERY);
+ guint16 id = xMenu->getItemId (i);
+ OUString oUCommand = xMenuEx->getCommand (id);
+ OString command = OUStringToOString (oUCommand, RTL_TEXTENCODING_ASCII_US);
+
+ DbusmenuMenuitem *item = DBUSMENU_MENUITEM(g_list_nth_data(items, i));
+
+ if (!item)
+ continue;
+
+ if (!DBUSMENU_IS_MENUITEM (item))
+ continue;
+
+ // We drop the WindowList, doesn't work properly and it's useless anyhow
+ if (oUCommand.equals (OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:WindowList"))))
+ continue;
+
+ //We set the default properties (in case it was not visible or a separator)
+ dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_DEFAULT);
+ dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
+
+ if (id == 0)
+ {
+ dbusmenu_menuitem_property_set (item, "CommandURL", "slot:0");
+ dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
+ //Getting rid of any possible children
+ g_list_free_full (dbusmenu_menuitem_take_children (item), destroy_menuitem);
+ continue;
+ }
+
+ //Setting the command
+ dbusmenu_menuitem_property_set (item, "CommandURL", command.getStr());
+
+ //Getting a shortcut
+ KeyEvent kev = findShortcutForCommand (oUCommand);
+
+ if (kev.KeyCode != 0) //KeyCode must have a value
+ {
+ GVariantBuilder builder;
+ const gchar* keystring = AwtKeyToDbusmenuString(kev.KeyCode);
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+
+ //We map KeyEvent.Modifiers with Dbusmenu modifiers strings
+ if (awt::KeyModifier::SHIFT & kev.Modifiers)
+ g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_SHIFT);
+ if (awt::KeyModifier::MOD2 & kev.Modifiers)
+ g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_ALT);
+ if (awt::KeyModifier::MOD1 & kev.Modifiers || awt::KeyModifier::MOD3 & kev.Modifiers)
+ g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_CONTROL);
+
+ g_variant_builder_add(&builder, "s", keystring);
+
+ GVariant * inside = g_variant_builder_end(&builder);
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add_value(&builder, inside);
+
+ GVariant * outsidevariant = g_variant_builder_end(&builder);
+ dbusmenu_menuitem_property_set_variant(item, DBUSMENU_MENUITEM_PROP_SHORTCUT, outsidevariant);
+ }
+
+ // Lookup for a MenuItemInfo object for this menuitem, create one if it doesn't exist
+ // this object caches the values that change on status updates.
+ MenuItemInfo* commInfo = (MenuItemInfo*)g_hash_table_lookup (m_commandsInfo, (gconstpointer)command.getStr());
+ if (!commInfo)
+ {
+ commInfo = new MenuItemInfo ();
+ g_hash_table_insert (m_commandsInfo, g_strdup (command.getStr()), commInfo);
+
+ OUString oULabel = getLabelFromCommandURL(oUCommand);
+ if (oULabel.getLength() == 0)
+ {
+ oULabel = xMenu->getItemText (id);
+ }
+
+ //Replace tilde with underscore for Dbusmenu Alt accelerators
+ oULabel = oULabel.replace ((sal_Unicode)0x007e, (sal_Unicode)0x005f);
+ // GLib behaves better than OUStringToOString wrt encoding transformation
+ gchar* label = g_utf16_to_utf8 (oULabel.getStr(),
+ oULabel.getLength(),
+ NULL, NULL, NULL);
+ commInfo->setLabel (label);
+ g_free (label);
+ }
+
+ //Update the check state directly from the data, this is more reliable
+ Reference < XPopupMenu > popUp (xMenu, UNO_QUERY);
+ if (popUp.is() && popUp->isItemChecked (id))
+ {
+ commInfo->setCheckState (DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED);
+ }
+
+ dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_LABEL, commInfo->getLabel ());
+ dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, commInfo->getEnabled ());
+
+ //TODO: Find a selection of which commands are radio toggle type
+ if (commInfo->getCheckState () != DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN)
+ {
+ dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, commInfo->getCheckType ());
+ dbusmenu_menuitem_property_set_int (item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, commInfo->getCheckState ());
+ }
+
+ // Adding status listener
+ URL commandURL;
+ commandURL.Complete = oUCommand;
+ m_xTrans->parseStrict (commandURL);
+
+ Reference < XDispatch > xDispatch = m_xdp->queryDispatch (commandURL, OUString(), 0);
+ if(xDispatch.is())
+ m_pDispatchRegistry->Connect(xDispatch, commandURL);
+
+ Reference < XPopupMenu > subPopMenu (xMenu->getPopupMenu (id), UNO_QUERY);
+
+ //Some menus do not provide the information available through the normal XMenu interface,
+ //we need to access that info through a special XPopupMenuController
+ if (isSpecialSubmenu (oUCommand))
+ {
+ Reference < XPropertySet > xMSFProps (m_xMSF, UNO_QUERY);
+ Reference <XComponentContext> xContext (xMSFProps->getPropertyValue (OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext"))),
+ UNO_QUERY);
+
+ Reference < XPopupMenuController > xRFC (m_xPCF->createInstanceWithArgumentsAndContext(oUCommand,
+ m_args,
+ xContext),
+ UNO_QUERY);
+
+ Reference < XPopupMenu > xPO (m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("stardiv.Toolkit.VCLXPopupMenu"))),
+ UNO_QUERY);
+
+ if (xRFC.is () && xPO.is ())
+ {
+ xRFC->setPopupMenu (xPO);
+ xRFC->updatePopupMenu ();
+ Reference < XMenu > subMenu (xPO, UNO_QUERY);
+ rebuildMenu (subMenu, item);
+ }
+ else if (subPopMenu.is ())
+ {
+ Reference <XMenu> subMenu (subPopMenu, UNO_QUERY);
+ rebuildMenu (subMenu, item);
+ }
+ }
+
+ // Introspect submenus
+ else if (subPopMenu.is ())
+ {
+ Reference <XMenu> subMenu (subPopMenu, UNO_QUERY);
+ g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW, G_CALLBACK(item_about_to_show), this);
+ rebuildMenu (subMenu, item);
+ }
+ else
+ {
+ //Getting rid of any possible children
+ g_list_free_full (dbusmenu_menuitem_take_children (item), destroy_menuitem);
+ }
+ }
+
+ return;
+}
+
+//Gets the menu item Label given a CommandURL
+//This is a work around for bug: https://bugs.freedesktop.org/show_bug.cgi?id=34127
+OUString
+FrameHelper::getLabelFromCommandURL (OUString commandURL)
+{
+ OUString label;
+
+ Sequence < PropertyValue > commandProps;
+
+ if (commandURL.getLength () < 1)
+ return label;
+
+ if (!m_xUICommands.is())
+ return label;
+
+ try
+ {
+ m_xUICommands->getByName (commandURL) >>= commandProps;
+ }
+ catch (com::sun::star::container::NoSuchElementException e)
+ {
+ return label;
+ }
+
+ for (sal_Int32 i = 0; i < commandProps.getLength(); i++)
+ {
+ if ( commandProps[i].Name.equalsAsciiL (RTL_CONSTASCII_STRINGPARAM ("Label")))
+ {
+ commandProps[i].Value >>= label;
+ label = label.replace ((sal_Unicode)0x007e, (sal_Unicode)0x005f);
+ //break;
+ }
+ }
+
+ return label;
+}
+
+//This method is a facility to bootstrap the Dbusmenuitem strcuture from the menubar
+void
+FrameHelper::rebuildMenuFromRoot ()
+{
+ Reference < XFrame > xFrame = getFrame ();
+ Reference < XPropertySet > frameProps (xFrame, UNO_QUERY);
+ Reference < XLayoutManager > xLayoutManager (frameProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LayoutManager"))),
+ UNO_QUERY);
+ Reference < XUIElement > menuBar (xLayoutManager->getElement (OUString(RTL_CONSTASCII_USTRINGPARAM("private:resource/menubar/menubar"))),
+ UNO_QUERY);
+ Reference < XPropertySet > menuPropSet (menuBar, UNO_QUERY);
+
+ if (!menuPropSet.is ())
+ return;
+
+ Reference < XMenu > xMenu (menuPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("XMenuBar"))),
+ UNO_QUERY);
+ if (!xMenu.is ())
+ return;
+
+ rebuildMenu (xMenu, m_root);
+}
+
+//Some menus are special, this is the list of them
+gboolean
+FrameHelper::isSpecialSubmenu (OUString command)
+{
+ const gchar * specialSubmenus[11] = {".uno:CharFontName",
+ ".uno:FontHeight",
+ ".uno:ObjectMenue",
+ ".uno:InsertPageHeader",
+ ".uno:InsertPageFooter",
+ ".uno:ChangeControlType",
+ ".uno:AvailableToolbars",
+ ".uno:ScriptOrganizer",
+ ".uno:RecentFileList",
+ ".uno:AddDirect",
+ ".uno:AutoPilotMenu"};
+
+ for (gint i = 0; i < 11; i++)
+ {
+ if (command.equals (OUString::createFromAscii (specialSubmenus[i])))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+FrameHelper::dispatchCommand (OUString command)
+{
+ OUString target = OUString(RTL_CONSTASCII_USTRINGPARAM(""));
+ Reference < XDispatchHelper > xdh (m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.DispatchHelper"))),
+ UNO_QUERY);
+
+ // This is a special case, we don't want the helper to be disconnected from the frame
+ // when PrintPreview dettaches. See the frameAction method.
+ if (command.equals (OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:PrintPreview"))))
+ {
+ m_blockDetach = TRUE;
+ }
+
+ // This is a special case for the recentfilelist
+ if (command.matchAsciiL ("vnd.sun.star.popup:RecentFileList", 33, 0))
+ {
+ target = OUString(RTL_CONSTASCII_USTRINGPARAM("_default"));
+
+ Reference < XPropertySet > xMSFProps (m_xMSF, UNO_QUERY);
+ Reference <XComponentContext> xContext (xMSFProps->getPropertyValue (OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext"))),
+ UNO_QUERY);
+ Reference < XPopupMenuController > xRFC (m_xPCF->createInstanceWithArgumentsAndContext(OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:RecentFileList")),
+ m_args,
+ xContext),
+ UNO_QUERY);
+ Reference < XMenuListener > xML (xRFC, UNO_QUERY);
+
+ Reference < XPopupMenu > xPO (m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("stardiv.Toolkit.VCLXPopupMenu"))),
+ UNO_QUERY);
+
+ if (xRFC.is () && xPO.is ())
+ {
+ xRFC->setPopupMenu (xPO);
+ xRFC->updatePopupMenu ();
+ Reference < XMenu > subMenu (xPO, UNO_QUERY);
+ Reference < XMenuExtended > subMenuEx (xPO, UNO_QUERY);
+
+ //We need to find the item idd
+ for (int i = 0; i < subMenu->getItemCount (); i++)
+ {
+ int id = subMenu->getItemId (i);
+
+ if (subMenuEx->getCommand (id).equals (command))
+ {
+ MenuEvent mev;
+ mev.MenuId = id;
+
+ xML->select (mev);
+ }
+ }
+ }
+
+ return;
+ }
+
+ if (command.matchAsciiL ("private:factory/", 16, 0))
+ target = OUString(RTL_CONSTASCII_USTRINGPARAM("_blank"));
+
+ xdh->executeDispatch (Reference < XDispatchProvider > (m_xFrame, UNO_QUERY),
+ command,
+ target,
+ 0,
+ Sequence < PropertyValue > ());
+}
+
+//Set all the accelerator configuration sources
+void
+FrameHelper::getAcceleratorConfigurations (Reference < XModel > xModel,
+ Reference < XModuleManager> xModuleManager)
+{
+ //Get document shortcut database
+ Reference< XUIConfigurationManagerSupplier > docUISupplier(xModel, UNO_QUERY);
+ Reference< XUIConfigurationManager > docUIManager = docUISupplier->getUIConfigurationManager();
+ Reference< XAcceleratorConfiguration > docAccelConf(docUIManager->getShortCutManager(), UNO_QUERY);
+ this->m_docAccelConf = docAccelConf;
+
+ //Get module shurtcut database
+ Reference< XModuleUIConfigurationManagerSupplier > modUISupplier(m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ui.ModuleUIConfigurationManagerSupplier"))),
+ UNO_QUERY);
+ Reference< XUIConfigurationManager > modUIManager = modUISupplier->getUIConfigurationManager(xModuleManager->identify(m_xFrame));
+ Reference< XAcceleratorConfiguration > modAccelConf(modUIManager->getShortCutManager(), UNO_QUERY);
+ this->m_modAccelConf = modAccelConf;
+
+ //Get global shortcut database
+ Reference< XAcceleratorConfiguration > globAccelConf(m_xMSF->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ui.GlobalAcceleratorConfiguration"))),
+ UNO_QUERY);
+ this->m_globAccelConf = globAccelConf;
+}
+
+
+//This function finds a KeyEvent with the shortcut information for each command
+KeyEvent
+FrameHelper::findShortcutForCommand (OUString command)
+
+{
+ KeyEvent kev;
+
+ Sequence < OUString > commands (1);
+ commands[0] = command;
+
+ try
+ {
+ Sequence < Any > evs = m_docAccelConf->getPreferredKeyEventsForCommandList (commands);
+
+ for (int j = 0; j < evs.getLength (); j++)
+ {
+ KeyEvent ev;
+ if (evs[j] >>= ev)
+ return ev;
+ }
+ }
+ catch (...)
+ {}
+ try
+ {
+ Sequence < Any > evs = m_modAccelConf->getPreferredKeyEventsForCommandList (commands);
+
+ for (int j = 0; j < evs.getLength (); j++)
+ {
+ KeyEvent ev;
+ if (evs[j] >>= ev)
+ return ev;
+ }
+ }
+ catch (...)
+ {}
+ try
+ {
+ Sequence < Any > evs = m_globAccelConf->getPreferredKeyEventsForCommandList (commands);
+
+ for (int j = 0; j < evs.getLength (); j++)
+ {
+ KeyEvent ev;
+ if (evs[j] >>= ev)
+ return ev;
+ }
+ }
+ catch (...)
+ {}
+
+ //NOTE: For some reason this item does not return its shortcut. Setting manually:
+ if (command.equals (OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:HelpIndex"))))
+ {
+ kev.KeyCode = awt::Key::F1;
+ }
+
+ return kev;
+}
diff --git a/framework/source/lomenubar/FrameHelper.hxx b/framework/source/lomenubar/FrameHelper.hxx
new file mode 100644
index 000000000000..9264f26d2654
--- /dev/null
+++ b/framework/source/lomenubar/FrameHelper.hxx
@@ -0,0 +1,154 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef __FRAME_HELPER_HXX__
+#define __FRAME_HELPER_HXX__
+
+#include <vector>
+
+#include <boost/scoped_ptr.hpp>
+
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/awt/XMenu.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/frame/FrameAction.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/frame/XStatusListener.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+//#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#include <libdbusmenu-glib/server.h>
+#pragma GCC diagnostic error "-Wignored-qualifiers"
+//#pragma GCC diagnostic pop
+#include <libdbusmenu-glib/menuitem.h>
+
+using com::sun::star::awt::KeyEvent;
+using com::sun::star::awt::XMenu;
+using com::sun::star::beans::PropertyValue;
+using com::sun::star::container::XNameAccess;
+using com::sun::star::frame::FrameActionEvent;
+using com::sun::star::frame::XFrame;
+using com::sun::star::frame::XFramesSupplier;
+using com::sun::star::frame::XFrameActionListener;
+using com::sun::star::frame::XStatusListener;
+using com::sun::star::frame::XDispatchProvider;
+using com::sun::star::frame::XModuleManager;
+using com::sun::star::frame::XModel;
+using com::sun::star::lang::EventObject;
+using com::sun::star::lang::XMultiServiceFactory;
+using com::sun::star::lang::XMultiComponentFactory;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::util::XURLTransformer;
+using com::sun::star::ui::XAcceleratorConfiguration;
+using rtl::OUString;
+
+
+namespace framework { namespace lomenubar
+{
+ class DispatchRegistry;
+}}
+
+/* This class is a helper in charge of closing the dbusmenu server when a frame is closed,
+ * and also allows the menuitem callbacks to dispatch commands.
+ */
+
+class FrameHelper : public cppu::WeakImplHelper1 < XFrameActionListener >
+{
+ private:
+ const Reference < XStatusListener > m_xStatusListener;
+ ::boost::scoped_ptr< ::framework::lomenubar::DispatchRegistry> m_pDispatchRegistry;
+ const Reference < XMultiServiceFactory > m_xMSF;
+ const Reference < XURLTransformer > m_xTrans;
+ const Reference < XModuleManager> m_xMM;
+ const Reference < XMultiComponentFactory > m_xPCF;
+ const Reference < XFrame > m_xFrame;
+ const Reference < XDispatchProvider > m_xdp;
+ const Sequence < Any > m_args;
+ Reference < XNameAccess > m_xUICommands;
+ DbusmenuServer *m_server;
+ DbusmenuMenuitem *m_root;
+ gboolean m_watcher_set;
+ guint m_watcher;
+ GHashTable *m_commandsInfo;
+ //This variable prevents the helper from being disconnected from the frame
+ //for special cases of component dettaching like print preview
+ gboolean m_blockDetach;
+
+
+ gboolean isSpecialSubmenu (OUString command);
+
+ //This is to build the shortcut database
+ Reference< XAcceleratorConfiguration > m_docAccelConf;
+ Reference< XAcceleratorConfiguration > m_modAccelConf;
+ Reference< XAcceleratorConfiguration > m_globAccelConf;
+
+ void getAcceleratorConfigurations (Reference < XModel >,
+ Reference < XModuleManager>);
+
+ KeyEvent findShortcutForCommand (OUString);
+
+ public:
+ FrameHelper(const Reference< XMultiServiceFactory >&,
+ const Reference< XFrame >&,
+ DbusmenuServer*);
+
+ virtual ~FrameHelper();
+ virtual void SAL_CALL frameAction(const FrameActionEvent& action)
+ throw (RuntimeException);
+
+ virtual void SAL_CALL disposing(const EventObject& aEvent)
+ throw (RuntimeException);
+
+ //Setters
+ void setRootItem (DbusmenuMenuitem *);
+ void setRegistrarWatcher (guint watcher);
+ void setServer (DbusmenuServer *);
+
+ //Getters
+ Reference < XFrame > getFrame ();
+ unsigned long getXID ();
+ GHashTable* getCommandsInfo ();
+ ::rtl::OUString getLabelFromCommandURL (::rtl::OUString);
+
+ //Menu Related actions
+ void dispatchCommand (OUString);
+ void rebuildMenu (Reference < XMenu >, DbusmenuMenuitem*);
+ void rebuildMenuFromRoot ();
+ void populateWindowList (DbusmenuMenuitem *);
+};
+#endif // __FRAME_HELPER_HXX__
diff --git a/framework/source/lomenubar/FrameJob.cxx b/framework/source/lomenubar/FrameJob.cxx
new file mode 100644
index 000000000000..27b0350a2100
--- /dev/null
+++ b/framework/source/lomenubar/FrameJob.cxx
@@ -0,0 +1,397 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "FrameJob.hxx"
+#include "DesktopJob.hxx"
+#include "FrameHelper.hxx"
+
+#define OBJ_PATH_PREFIX "/com/canonical/menu/"
+
+#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
+#include <com/sun/star/awt/SystemDependentXWindow.hpp>
+#include <com/sun/star/awt/XMenu.hpp>
+#include <com/sun/star/awt/XMenuExtended.hpp>
+#include <com/sun/star/awt/XMenuBar.hpp>
+#include <com/sun/star/awt/XPopupMenu.hpp>
+#include <com/sun/star/awt/XPopupMenuExtended.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchHelper.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XFrameActionListener.hpp>
+#include <com/sun/star/frame/XStatusListener.hpp>
+#include <com/sun/star/frame/FrameAction.hpp>
+#include <com/sun/star/lang/EventObject.hpp>
+#include <com/sun/star/lang/SystemDependent.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIElementSettings.hpp>
+#include <com/sun/star/ui/XUIElement.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+#include <iostream>
+#include <fstream>
+
+#include <gio/gio.h>
+//#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wignored-qualifiers"
+#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-glib/client.h>
+#pragma GCC diagnostic error "-Wignored-qualifiers"
+//#pragma GCC diagnostic pop
+
+#include <rtl/process.h>
+#include <osl/diagnose.h>
+
+using rtl::OUString;
+using rtl::OString;
+using rtl::OUStringToOString;
+
+using com::sun::star::awt::KeyEvent;
+using com::sun::star::awt::SystemDependentXWindow;
+using com::sun::star::awt::XMenu;
+using com::sun::star::awt::XMenuExtended;
+using com::sun::star::awt::XPopupMenu;
+using com::sun::star::awt::XPopupMenuExtended;
+using com::sun::star::awt::XMenuBar;
+using com::sun::star::awt::XSystemDependentWindowPeer;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::WeakReference;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Exception;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::XInterface;
+using com::sun::star::lang::IllegalArgumentException;
+using com::sun::star::lang::XMultiServiceFactory;
+using com::sun::star::lang::SystemDependent::SYSTEM_XWINDOW;
+using com::sun::star::lang::EventObject;
+using com::sun::star::beans::NamedValue;
+using com::sun::star::beans::PropertyValue;
+using com::sun::star::beans::XPropertySet;
+using com::sun::star::document::XEventBroadcaster;
+using com::sun::star::frame::XFrame;
+using com::sun::star::frame::XFrameActionListener;
+using com::sun::star::frame::FrameActionEvent;
+using com::sun::star::frame::XController;
+using com::sun::star::frame::XLayoutManager;
+using com::sun::star::frame::XModel;
+using com::sun::star::frame::XModuleManager;
+using com::sun::star::frame::XDispatch;
+using com::sun::star::frame::XDispatchProvider;
+using com::sun::star::frame::XDispatchHelper;
+using com::sun::star::frame::XStatusListener;
+using com::sun::star::frame::FeatureStateEvent;
+using com::sun::star::ui::XUIElement;
+using com::sun::star::ui::XUIElementSettings;
+using com::sun::star::ui::XUIConfigurationManagerSupplier;
+using com::sun::star::ui::XUIConfigurationManager;
+using com::sun::star::ui::XModuleUIConfigurationManagerSupplier;
+using com::sun::star::ui::XAcceleratorConfiguration;
+using com::sun::star::util::URL;
+using com::sun::star::util::XURLTransformer;
+using com::sun::star::container::XIndexContainer;
+using com::sun::star::container::XIndexAccess;
+using com::sun::star::container::XNameAccess;
+using com::sun::star::container::NoSuchElementException;
+
+
+// This is a helper utility to transform an xid to a /com/canonical/menu/<XID>
+// DBUS object path
+OString
+xid_to_object_path (unsigned long xid)
+{
+
+ GString *xid_str = g_string_new ("");
+ g_string_printf (xid_str, "%d", (guint32)xid);
+ OString object_path = OUStringToOString (OUString::createFromAscii (OBJ_PATH_PREFIX).concat (OUString::createFromAscii(xid_str->str)),
+ RTL_TEXTENCODING_ASCII_US);
+ g_string_free (xid_str, TRUE);
+ return object_path;
+}
+
+//-------------------------- GObject callbacks -------------------------------//
+//This is called when a registrar becomes available. It registers the hides the menubar.
+static void
+on_registrar_available (GDBusConnection * /*connection*/,
+ const gchar * /*name*/,
+ const gchar * /*name_owner*/,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GDBusProxy *proxy;
+
+ FrameHelper *helper = (FrameHelper*)user_data;
+ unsigned long xid = helper->getXID();
+
+ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "com.canonical.AppMenu.Registrar",
+ "/com/canonical/AppMenu/Registrar",
+ "com.canonical.AppMenu.Registrar",
+ NULL,
+ &error);
+ if (error)
+ {
+ g_warning ("Couldn't get /com/canonical/AppMenu/Registrar proxy");
+ return;
+ }
+
+
+ //TODO: Check if window is registered already
+ g_dbus_proxy_call_sync (proxy,
+ "RegisterWindow",
+ g_variant_new ("(uo)",
+ (guint32)xid,
+ xid_to_object_path (xid).getStr()),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ g_warning ("Couldn't call /com/canonical/AppMenu/Registrar.RegisterWindow");
+ return;
+ }
+
+ //Hide menubar
+ Reference < XFrame > xFrame = helper->getFrame ();
+ Reference< XPropertySet > frameProps (xFrame, UNO_QUERY);
+ Reference < XLayoutManager > xLayoutManager(frameProps->getPropertyValue(OUString::createFromAscii("LayoutManager")),
+ UNO_QUERY);
+ xLayoutManager->hideElement (OUString::createFromAscii("private:resource/menubar/menubar"));
+
+ return;
+}
+
+//This is called when the registrar becomes unavailable. It shows the menubar.
+static void
+on_registrar_unavailable (GDBusConnection * /*connection*/,
+ const gchar * /*name*/,
+ gpointer user_data)
+{
+ //TODO: Unregister window?
+
+ // Show menubar
+ FrameHelper *helper = (FrameHelper*)user_data;
+ Reference < XFrame > xFrame = helper->getFrame ();
+ Reference< XPropertySet > frameProps (xFrame, UNO_QUERY);
+ Reference < XLayoutManager > xLayoutManager(frameProps->getPropertyValue(OUString::createFromAscii("LayoutManager")),
+ UNO_QUERY);
+ xLayoutManager->showElement (OUString::createFromAscii("private:resource/menubar/menubar"));
+ return;
+}
+// ------------------------------- FrameJob --------------------------------------------
+Any SAL_CALL FrameJob::execute( const Sequence< NamedValue >& aArguments )
+ throw ( IllegalArgumentException, Exception, RuntimeException )
+{
+ Sequence< NamedValue > lEnv;
+ Reference< XModel > xModel;
+ sal_Int32 len = aArguments.getLength();
+
+ for (int i = 0; i<len; i++)
+ {
+ if (aArguments[i].Name.equalsAscii("Environment"))
+ {
+ aArguments[i].Value >>= lEnv;
+ break;
+ }
+ }
+
+ len = lEnv.getLength ();
+ for (int i = 0; i<len; i++)
+ {
+ if (lEnv[i].Name.equalsAscii("Model"))
+ {
+ lEnv[i].Value >>= xModel;
+ }
+ }
+
+ //If we didn't get the model we have to quit
+ if (!xModel.is())
+ return Any();
+
+
+ Reference< XController > xController( xModel->getCurrentController(), UNO_QUERY);
+ if (!xController.is())
+ return Any();
+
+ m_xFrame = Reference< XFrame > ( xController->getFrame(), UNO_QUERY);
+ if (!m_xFrame.is ())
+ return Any();
+
+ exportMenus (m_xFrame);
+ return Any();
+}
+
+// This function crates a DbusmenuServer and starts the watcher for the AppMenu Registrar bus name
+void
+FrameJob::exportMenus (Reference < XFrame > xFrame)
+{
+ //Set the xFrame for this object
+
+ this->m_xFrame = xFrame;
+
+ //Create dbusmenu server object path string
+ DbusmenuServer *server = dbusmenu_server_new (xid_to_object_path(getXID (xFrame)).getStr());
+
+
+ Reference< XPropertySet > frameProps (xFrame, UNO_QUERY);
+ Reference < XLayoutManager > xLayoutManager(frameProps->getPropertyValue(OUString::createFromAscii("LayoutManager")),
+ UNO_QUERY);
+ if (!xLayoutManager.is())
+ {
+ g_object_unref (server);
+ return;
+ }
+
+ Reference < XUIElement > menuBar(xLayoutManager->getElement (OUString::createFromAscii("private:resource/menubar/menubar")),
+ UNO_QUERY);
+ Reference < XPropertySet > menuPropSet (menuBar, UNO_QUERY);
+
+ if (!menuPropSet.is())
+ {
+ g_object_unref (server);
+ return;
+ }
+
+ Reference < XMenu > xMenu (menuPropSet->getPropertyValue(OUString::createFromAscii("XMenuBar")),
+ UNO_QUERY);
+
+ if (!xMenu.is ())
+ {
+ g_object_unref (server);
+ return;
+ }
+
+ //Create a new frame helper to close the server when needed
+ FrameHelper *helper = new FrameHelper (m_xMSF, xFrame, server);
+ xFrame->addFrameActionListener (Reference < XFrameActionListener > (helper));
+
+ //Populate dbusmenu items and start the server
+ DbusmenuMenuitem *root = getRootMenuitem (xMenu, (gpointer)helper);
+ dbusmenu_server_set_root (server, root);
+
+ //Listen to the availability of the registrar
+ guint watcher = g_bus_watch_name (G_BUS_TYPE_SESSION,
+ "com.canonical.AppMenu.Registrar",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ on_registrar_available,
+ on_registrar_unavailable,
+ helper,
+ NULL);
+ helper->setRegistrarWatcher (watcher);
+}
+
+
+//Gets the XID for a given XFrame
+unsigned long
+FrameJob::getXID (css::uno::Reference < css::frame::XFrame > xFrame)
+{
+ Reference< XSystemDependentWindowPeer > xWin( xFrame->getContainerWindow(), UNO_QUERY);
+
+ if (!xWin.is())
+ return 0;
+
+ sal_Int8 processID[16];
+ rtl_getGlobalProcessId( (sal_uInt8*)processID );
+ Sequence <signed char> pidSeq (processID, 16);
+
+ SystemDependentXWindow xWindow;
+ xWin->getWindowHandle (pidSeq, SYSTEM_XWINDOW) >>= xWindow;
+
+ return xWindow.WindowHandle;
+}
+
+// Builds a Dbusmenuitem structure from an XMenu object
+DbusmenuMenuitem*
+FrameJob::getRootMenuitem (Reference < XMenu > xMenu, gpointer helper)
+{
+
+ DbusmenuMenuitem *root = dbusmenu_menuitem_new_with_id (0);
+ ((FrameHelper*)helper)->setRootItem(root);
+ ((FrameHelper*)helper)->rebuildMenu (xMenu, root);
+
+ return root;
+}
+
+// XJob
+OUString FrameJob_getImplementationName ()
+ throw (RuntimeException)
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( FRAMEJOB_IMPLEMENTATION_NAME ) );
+}
+
+sal_Bool SAL_CALL FrameJob_supportsService( const OUString& ServiceName )
+ throw (RuntimeException)
+{
+ return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( FRAMEJOB_SERVICE_NAME ) );
+}
+
+Sequence< OUString > SAL_CALL FrameJob_getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ Sequence < OUString > aRet(1);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( FRAMEJOB_SERVICE_NAME ) );
+ return aRet;
+}
+
+Reference< XInterface > SAL_CALL FrameJob_createInstance( const Reference< XMultiServiceFactory > & rSMgr)
+ throw( Exception )
+{
+ return (cppu::OWeakObject*) new FrameJob(rSMgr);
+}
+
+// XServiceInfo
+OUString SAL_CALL FrameJob::getImplementationName()
+ throw (RuntimeException)
+{
+ return FrameJob_getImplementationName();
+}
+
+sal_Bool SAL_CALL FrameJob::supportsService( const OUString& rServiceName )
+ throw (RuntimeException)
+{
+ return FrameJob_supportsService( rServiceName );
+}
+
+Sequence< OUString > SAL_CALL FrameJob::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return FrameJob_getSupportedServiceNames();
+}
+
diff --git a/framework/source/lomenubar/FrameJob.hxx b/framework/source/lomenubar/FrameJob.hxx
new file mode 100644
index 000000000000..407b602f1c9c
--- /dev/null
+++ b/framework/source/lomenubar/FrameJob.hxx
@@ -0,0 +1,101 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef __FRAME_JOB_HXX__
+#define __MRAME_JOB_HXX__
+
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <com/sun/star/awt/XMenu.hpp>
+#include <com/sun/star/awt/KeyEvent.hpp>
+
+#include <glib.h>
+#include <libdbusmenu-glib/menuitem.h>
+
+#define FRAMEJOB_IMPLEMENTATION_NAME "org.libreoffice.comp.framework.lomenubar.FrameJob"
+#define FRAMEJOB_SERVICE_NAME "com.sun.star.task.Job"
+
+namespace css = ::com::sun::star;
+using css::uno::Reference;
+
+class FrameJob : public cppu::WeakImplHelper2 < css::task::XJob, css::lang::XServiceInfo >
+{
+ private:
+ Reference < css::lang::XMultiServiceFactory > m_xMSF;
+ Reference < css::container::XNameAccess > m_xUICommands;
+ Reference < css::frame::XFrame > m_xFrame;
+
+ unsigned long xid;
+
+ //Private methods
+ unsigned long getXID (Reference < css::frame::XFrame >);
+ DbusmenuMenuitem* getRootMenuitem (Reference < css::awt::XMenu >,
+ gpointer);
+
+ public:
+ FrameJob( const css::uno::Reference< css::lang::XMultiServiceFactory > &rxMSF)
+ : m_xMSF( rxMSF ) {};
+
+ void exportMenus (Reference < css::frame::XFrame > xFrame);
+
+ virtual ~FrameJob() {}
+
+ // XJob
+ virtual css::uno::Any SAL_CALL execute(const css::uno::Sequence< css::beans::NamedValue >& Arguments)
+ throw (css::lang::IllegalArgumentException, css::uno::Exception, css::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
+ throw (css::uno::RuntimeException);
+};
+
+
+::rtl::OUString FrameJob_getImplementationName()
+ throw ( css::uno::RuntimeException );
+
+sal_Bool SAL_CALL FrameJob_supportsService( const ::rtl::OUString& ServiceName )
+ throw ( css::uno::RuntimeException );
+
+css::uno::Sequence< ::rtl::OUString > SAL_CALL FrameJob_getSupportedServiceNames()
+ throw ( css::uno::RuntimeException );
+
+css::uno::Reference< css::uno::XInterface >
+SAL_CALL FrameJob_createInstance( const css::uno::Reference< css::lang::XMultiServiceFactory > & rSMgr)
+ throw ( css::uno::Exception );
+
+#endif
+
diff --git a/framework/source/lomenubar/HACKING b/framework/source/lomenubar/HACKING
new file mode 100644
index 000000000000..49d016f32c41
--- /dev/null
+++ b/framework/source/lomenubar/HACKING
@@ -0,0 +1,99 @@
+LibreOffice DbusMenu Integration Source Code
+============================================
+There are three main classes, DesktopJob, FrameJob and FrameHelper implemented
+in their respective .cxx/.h files:
+
+- src/DesktopJob.cxx
+- src/DesktopJob.h
+
+- src/FrameJob.cxx
+- src/FrameJob.h
+
+- src/FrameHelper.cxx
+- src/FrameHelper.h
+
+The first two classes are Jobs executed synchronously on two events, the events
+that trigger these jobs are defined in data/Jobs.xcu. Further explanation on
+each class can be found below.
+
+The FrameHelper class performs most of the tasks regarding communication between
+
+The src/export.cxx code is the entry point for the resulting shared object
+that conforms this extension. It exports the information needed to register and
+access all the interfaces implemented by the two jobs exported.
+
+GLib Integration
+----------------
+This extension assumes the presence of the GLib mainloop in the application,
+it is not recommended its installation on LibreOffice deployments that do not
+provide integration with the glib mainloop.
+
+g_type_init() is called in DesktopJob for safety.
+
+DesktopJob
+----------
+This class is a XJob that is instantiated and executed on LibreOffice startup
+just once during the lifetime of the process.
+
+This class does nothing but trying to acquire the "org.libreoffice.dbusmenu"
+busname. Once the executed method returns the object instance is destroyed.
+
+FrameJob & FrameHelper
+----------------------
+This class is a XJob that is instantiated and executed every time a document is
+created or loaded. It watches for the presence of the
+com.canonical.AppMenu.Registrar well-known D-Bus name.
+
+Afterwards it creates an instance of the FrameHelper class. FrameHelper is an
+XFrameActionListener that subscribes to the XFrame that represents the current
+Window. The lifetime of this FrameHelper is bound to the life of the current
+document being viewed/edited.
+
+FrameHelper creates the initial structure of Dbusmenu menuitems, and the
+dbusmenu server. If FrameHelper is destroyed, the frame is unregistered and
+the server shutdown. It also stops watching com.canonical.AppMenu.Registrar
+presence.
+
+Listening for menu changes - MenuItemInfo & MenuItemStatusListener
+------------------------------------------------------------------
+FrameHelper subscribes creates a cache in the commandsInfo GHashTable property.
+This cache maps each command URL with a MenuItemInfo object that stores the
+current information for a given menu item.
+
+To listen for menu changes and update the cache, FrameHelper creates an instance
+of MenuItemStatusListener per each command url. This listeners update the data
+for the respective MenuItemInfo associated to the command URL it is listening
+for. The source code for these two classes can be found in the following
+respective files:
+
+- src/MenuItemInfo.h
+- src/MenuItemInfo.cxx
+
+- src/MenuItemStatusListener.h
+- src/MenuItemStatusListener.cxx
+
+Special Popup Menus
+-------------------
+This is the set of special popup menus:
+- .uno:CharFontName
+- .uno:FontHeight
+- .uno:ObjectMenue
+- .uno:InsertPageHeader
+- .uno:InsertPageFooter
+- .uno:ChangeControlType
+- .uno:AvailableToolbars
+- .uno:ScriptOrganizer
+- .uno:RecentFileList
+- .uno:AddDirect
+- .uno:AutoPilotMenu
+
+These menus cannot be introspected as they are created dinamically when the user
+clicks on the menu. Therefor they are treated differently, see the usage of
+isSpecialSubmenu in the rebuildMenu method from the FrameHelper class.
+
+In the case of the recent file list, the command URLs provided by this
+workaround are not enough to open the document. A workaround for this is present
+in the FrameHelper::dispatchCommand method.
+
+For further reference on this type of submenus follow this link:
+http://wiki.services.openoffice.org/wiki/Framework/Tutorial/Popup_Menu_Controller
diff --git a/framework/source/lomenubar/Jobs.xcu b/framework/source/lomenubar/Jobs.xcu
new file mode 100644
index 000000000000..de2bb6087691
--- /dev/null
+++ b/framework/source/lomenubar/Jobs.xcu
@@ -0,0 +1,34 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<oor:component-data oor:name="Jobs" oor:package="org.openoffice.Office" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <node oor:name="Jobs">
+ <node oor:name="AppMenuDesktopJob" oor:op="replace">
+ <prop oor:name="Service">
+ <value>org.libreoffice.comp.framework.lomenubar.DesktopJob</value>
+ </prop>
+ </node>
+ <node oor:name="AppMenuFrameJob" oor:op="replace">
+ <prop oor:name="Service">
+ <value>org.libreoffice.comp.framework.lomenubar.FrameJob</value>
+ </prop>
+ </node>
+ </node>
+ <node oor:name="Events">
+ <node oor:name="OnStartApp" oor:op="replace">
+ <node oor:name="JobList">
+ <node oor:name="AppMenuDesktopJob" oor:op="replace"/>
+ </node>
+ </node>
+ <node oor:name="onDocumentOpened" oor:op="replace">
+ <node oor:name="JobList">
+ <node oor:name="AppMenuFrameJob" oor:op="replace"/>
+ </node>
+ </node>
+ <!--node oor:name="OnNew" oor:op="replace">
+ <node oor:name="JobList">
+ <node oor:name="AppMenuFrameJob" oor:op="replace"/>
+ </node>
+ </node-->
+
+ </node>
+</oor:component-data>
diff --git a/framework/source/lomenubar/MenuItemInfo.cxx b/framework/source/lomenubar/MenuItemInfo.cxx
new file mode 100644
index 000000000000..641c2c4b2017
--- /dev/null
+++ b/framework/source/lomenubar/MenuItemInfo.cxx
@@ -0,0 +1,103 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "MenuItemInfo.hxx"
+#include <libdbusmenu-gtk/menuitem.h>
+
+MenuItemInfo::MenuItemInfo ()
+{
+ m_label = NULL;
+ m_check_state = DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN;
+ m_check_type = (gchar*)DBUSMENU_MENUITEM_TOGGLE_CHECK;
+
+ m_is_visible = TRUE;
+ m_is_enabled = TRUE;
+}
+
+MenuItemInfo::~MenuItemInfo ()
+{
+ if (m_label)
+ g_free(m_label);
+}
+
+//Setters
+void
+MenuItemInfo::setLabel (gchar* label)
+{
+ this->m_label = g_strdup (label);
+}
+
+void
+MenuItemInfo::setEnabled (gboolean is_enabled)
+{
+ this->m_is_enabled = is_enabled;
+}
+
+void
+MenuItemInfo::setCheckState (gint check_state)
+{
+ this->m_check_state = check_state;
+}
+
+void
+MenuItemInfo::setCheckType (const gchar* check_type)
+{
+ this->m_check_type = (gchar*)check_type;
+}
+
+void
+MenuItemInfo::setVisible (gboolean is_visible)
+{
+ this->m_is_visible = is_visible;
+}
+
+//Getters
+gchar*
+MenuItemInfo::getLabel ()
+{
+ return m_label;
+}
+
+gboolean
+MenuItemInfo::getEnabled ()
+{
+ return m_is_enabled;
+}
+
+gint
+MenuItemInfo::getCheckState ()
+{
+ return m_check_state;
+}
+
+const gchar*
+MenuItemInfo::getCheckType ()
+{
+ return m_check_type;
+}
+
+gboolean
+MenuItemInfo::getVisible ()
+{
+ return m_is_visible;
+}
diff --git a/framework/source/lomenubar/MenuItemInfo.hxx b/framework/source/lomenubar/MenuItemInfo.hxx
new file mode 100644
index 000000000000..5699432ef9f6
--- /dev/null
+++ b/framework/source/lomenubar/MenuItemInfo.hxx
@@ -0,0 +1,54 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef __MENU_ITEM_INFO_HXX__
+#define __MENU_ITEM_INFO_HXX__
+#include <glib.h>
+
+// This is used in a hash table with commandurls as keys
+class MenuItemInfo {
+ gchar* m_label; //Label text in UTF-8 with tildes subst by underscores
+ gint m_check_state;
+ gchar* m_check_type;
+ gboolean m_is_enabled;
+ gboolean m_is_visible;
+
+ public:
+ MenuItemInfo ();
+ ~MenuItemInfo ();
+
+ //Setters
+ void setLabel (gchar* label);
+ void setEnabled (gboolean is_enabled);
+ void setCheckState (gint check_state);
+ void setCheckType (const gchar* check_type);
+ void setVisible (gboolean is_visible);
+
+ //Getters
+ gchar* getLabel ();
+ gboolean getEnabled ();
+ gint getCheckState ();
+ const gchar* getCheckType ();
+ gboolean getVisible ();
+};
+#endif // __MENU_ITEM_INFO_HXX__
diff --git a/framework/source/lomenubar/MenuItemStatusListener.cxx b/framework/source/lomenubar/MenuItemStatusListener.cxx
new file mode 100644
index 000000000000..6b7f7384f906
--- /dev/null
+++ b/framework/source/lomenubar/MenuItemStatusListener.cxx
@@ -0,0 +1,82 @@
+#include "MenuItemStatusListener.hxx"
+#include "MenuItemInfo.hxx"
+
+#include <com/sun/star/frame/status/Visibility.hpp>
+
+using com::sun::star::frame::status::Visibility;
+
+MenuItemStatusListener::MenuItemStatusListener (FrameHelper *helper)
+ : m_helper(helper)
+{
+ OSL_ENSURE(m_helper, "FrameHelper cannot be NULL");
+}
+
+void SAL_CALL
+MenuItemStatusListener::statusChanged(const FeatureStateEvent& Event)
+ throw (RuntimeException)
+{
+ sal_Bool isChecked;
+ Visibility visible;
+ OUString url = Event.FeatureURL.Complete;
+ OUString oULabel;
+
+ gchar* c_url = g_utf16_to_utf8 (url.getStr(),
+ url.getLength(),
+ NULL, NULL, NULL);
+
+ GHashTable *commandsInfo = m_helper->getCommandsInfo ();
+ MenuItemInfo *info = (MenuItemInfo*)g_hash_table_lookup (commandsInfo, (gpointer)c_url);
+ if (!info)
+ {
+ info = new MenuItemInfo ();
+ g_hash_table_insert (commandsInfo, c_url, info);
+
+ //Set the default label
+ oULabel = m_helper->getLabelFromCommandURL(url);
+ // Replace tilde with underscore for Dbusmenu Alt accelerators
+ oULabel = oULabel.replace ((sal_Unicode)0x007e, (sal_Unicode)0x005f);
+
+ // GLib behaves better than OUStringToOString wrt encoding transformation
+ gchar* label = g_utf16_to_utf8 (oULabel.getStr(),
+ oULabel.getLength(),
+ NULL, NULL, NULL);
+ info->setLabel (label);
+ g_free (label);
+ }
+ else
+ {
+ //Since we're not introducing it in the hash table, we get rid of this string
+ g_free (c_url);
+ }
+
+ //We set the enabled/disabled state
+ info->setEnabled ((gboolean)Event.IsEnabled);
+
+ //We find out what the new state is by casting
+
+ //For some reason, URLs can slip through as labels, we make sure
+ //this doesn't happen.
+ if ((Event.State >>= oULabel) &&
+ !oULabel.matchAsciiL ("private:", 8, 0) &&
+ !oULabel.matchAsciiL (".uno:", 5, 0) &&
+ !oULabel.matchAsciiL ("slot:", 5, 0) &&
+ !oULabel.matchAsciiL ("service:", 8, 0) &&
+ !oULabel.matchAsciiL (".cmd:", 5, 0) &&
+ !oULabel.matchAsciiL ("macro:///", 5, 0))
+ {
+ oULabel = oULabel.replace ((sal_Unicode)0x007e, (sal_Unicode)0x005f);
+ gchar* label = g_utf16_to_utf8 (oULabel.getStr(),
+ oULabel.getLength(),
+ NULL, NULL, NULL);
+ info->setLabel (label);
+ g_free (label);
+ }
+ else if (Event.State >>= isChecked)
+ {
+ info->setCheckState (isChecked);
+ }
+ else if (Event.State >>= visible)
+ {
+ info->setVisible (visible.bVisible);
+ }
+}
diff --git a/framework/source/lomenubar/MenuItemStatusListener.hxx b/framework/source/lomenubar/MenuItemStatusListener.hxx
new file mode 100644
index 000000000000..7fdab64ad23c
--- /dev/null
+++ b/framework/source/lomenubar/MenuItemStatusListener.hxx
@@ -0,0 +1,35 @@
+#ifndef __MENU_ITEM_STATUS_LISTENER_HXX__
+#define __MENU_ITEM_STATUS_LISTENER_HXX__
+
+#include "FrameHelper.hxx"
+
+#include <glib.h>
+
+#include <com/sun/star/frame/XStatusListener.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+#include <rtl/process.h>
+
+using com::sun::star::frame::FeatureStateEvent;
+using com::sun::star::frame::XStatusListener;
+using com::sun::star::lang::EventObject;
+
+// This class listens for changes in each menuitem and notifies FrameHelper about it
+class MenuItemStatusListener : public cppu::WeakImplHelper1 < XStatusListener >
+{
+ private:
+ guint16 m_id;
+ FrameHelper* const m_helper;
+
+ public:
+ MenuItemStatusListener (FrameHelper *helper);
+ ~MenuItemStatusListener () {}
+
+ virtual void SAL_CALL
+ statusChanged(const FeatureStateEvent& Event)
+ throw (RuntimeException);
+
+ virtual void SAL_CALL disposing(const EventObject& /*aEvent*/)
+ throw (RuntimeException) {}
+};
+#endif
diff --git a/framework/source/lomenubar/README b/framework/source/lomenubar/README
new file mode 100644
index 000000000000..45176349b094
--- /dev/null
+++ b/framework/source/lomenubar/README
@@ -0,0 +1,15 @@
+LibreOffice Global Menubar Extension for DBusMenu
+=================================================
+
+This library is an extension for LibreOffice that exports the Menubar structure,
+actions and shortcuts through the DBusMenu D-Bus interface. If there is a
+present DbusMenu client (The Unity panel or the Appmenu applet for GNOME Panel
+for instance), LibreOffice will had its menu structure.
+
+For more information, visit the official website:
+http://launchpad.net/lo-menubar
+
+Known Issues
+------------
+- The menubar is shown briefly before it is hidden.
+- The LibreOffice Start Center does not hide/export its menu structure.
diff --git a/framework/source/lomenubar/exports.cxx b/framework/source/lomenubar/exports.cxx
new file mode 100644
index 000000000000..8ee63aa3e4c5
--- /dev/null
+++ b/framework/source/lomenubar/exports.cxx
@@ -0,0 +1,94 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * A LibreOffice extension to send the menubar structure through DBusMenu
+ *
+ * Copyright 2011 Canonical, Ltd.
+ * Authors:
+ * Alberto Ruiz <alberto.ruiz@codethink.co.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the the GNU Lesser General Public License version 3, as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
+ * SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR PURPOSE. See the applicable
+ * version of the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include <stdio.h>
+
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+#include <cppuhelper/factory.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <sal/types.h>
+
+#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#endif
+
+#include "DesktopJob.hxx"
+#include "FrameJob.hxx"
+
+namespace css = ::com::sun::star;
+
+static void writeInfo(const css::uno::Reference< css::registry::XRegistryKey >& xRegistryKey ,
+ const char* pImplementationName,
+ const char* pServiceName )
+{
+ ::rtl::OUStringBuffer sKey(256);
+ sKey.append (::rtl::OUString::createFromAscii(pImplementationName));
+ sKey.appendAscii("/UNO/SERVICES/");
+ sKey.append (::rtl::OUString::createFromAscii(pServiceName));
+
+ xRegistryKey->createKey(sKey.makeStringAndClear());
+}
+
+extern "C"
+{
+SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(const sal_Char** ppEnvTypeName,
+ uno_Environment** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory(const sal_Char* pImplName ,
+ void* pServiceManager,
+ void* /*pRegistryKey*/ )
+{
+ if ( !pServiceManager || !pImplName )
+ return 0;
+
+ css::uno::Reference< css::lang::XSingleServiceFactory > xFactory ;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR (reinterpret_cast< css::lang::XMultiServiceFactory* >(pServiceManager), css::uno::UNO_QUERY);
+ ::rtl::OUString sImplName = ::rtl::OUString::createFromAscii(pImplName);
+
+ if (sImplName.equalsAscii(DESKTOPJOB_IMPLEMENTATION_NAME))
+ {
+ css::uno::Sequence< ::rtl::OUString > lNames(1);
+ lNames[0] = ::rtl::OUString::createFromAscii(DESKTOPJOB_IMPLEMENTATION_NAME);
+ xFactory = ::cppu::createSingleFactory(xSMGR, sImplName, DesktopJob_createInstance, lNames);
+ }
+ if (sImplName.equalsAscii(FRAMEJOB_IMPLEMENTATION_NAME))
+ {
+ css::uno::Sequence< ::rtl::OUString > lNames(1);
+ lNames[0] = ::rtl::OUString::createFromAscii(FRAMEJOB_IMPLEMENTATION_NAME);
+ xFactory = ::cppu::createSingleFactory(xSMGR, sImplName, FrameJob_createInstance, lNames);
+ }
+
+
+ if (!xFactory.is())
+ return 0;
+
+ xFactory->acquire();
+ return xFactory.get();
+}
+
+} // extern C
diff --git a/framework/source/recording/dispatchrecorder.cxx b/framework/source/recording/dispatchrecorder.cxx
new file mode 100644
index 000000000000..f7cce11699bb
--- /dev/null
+++ b/framework/source/recording/dispatchrecorder.cxx
@@ -0,0 +1,496 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <recording/dispatchrecorder.hxx>
+#include <com/sun/star/frame/DispatchStatement.hpp>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <services.h>
+#include <vcl/svapp.hxx>
+
+using namespace ::com::sun::star::uno;
+
+namespace framework{
+
+// used to mark a dispatch as comment (mostly it indicates an error) Changing of this wdefine will impact all using of such comments ...
+#define REM_AS_COMMENT "rem "
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_6(
+ DispatchRecorder,
+ OWeakObject,
+ DIRECT_INTERFACE(css::lang::XTypeProvider),
+ DIRECT_INTERFACE(css::lang::XServiceInfo),
+ DIRECT_INTERFACE(css::frame::XDispatchRecorder),
+ DIRECT_INTERFACE(css::container::XIndexReplace),
+ DIRECT_INTERFACE(css::container::XIndexAccess),
+ DIRECT_INTERFACE(css::container::XElementAccess))
+
+DEFINE_XTYPEPROVIDER_6(
+ DispatchRecorder,
+ css::lang::XTypeProvider,
+ css::lang::XServiceInfo,
+ css::frame::XDispatchRecorder,
+ css::container::XIndexReplace,
+ css::container::XIndexAccess,
+ css::container::XElementAccess)
+
+DEFINE_XSERVICEINFO_MULTISERVICE(
+ DispatchRecorder,
+ ::cppu::OWeakObject,
+ SERVICENAME_DISPATCHRECORDER,
+ IMPLEMENTATIONNAME_DISPATCHRECORDER)
+
+DEFINE_INIT_SERVICE(
+ DispatchRecorder,
+ {
+ }
+)
+
+#include <typelib/typedescription.h>
+
+//--------------------------------------------------------------------------------------------------
+void flatten_struct_members(
+ ::std::vector< Any > * vec, void const * data,
+ typelib_CompoundTypeDescription * pTD )
+ SAL_THROW( () )
+{
+ if (pTD->pBaseTypeDescription)
+ {
+ flatten_struct_members( vec, data, pTD->pBaseTypeDescription );
+ }
+ for ( sal_Int32 nPos = 0; nPos < pTD->nMembers; ++nPos )
+ {
+ vec->push_back(
+ Any( (char const *)data + pTD->pMemberOffsets[ nPos ], pTD->ppTypeRefs[ nPos ] ) );
+ }
+}
+//==================================================================================================
+Sequence< Any > make_seq_out_of_struct(
+ Any const & val )
+ SAL_THROW( (RuntimeException) )
+{
+ Type const & type = val.getValueType();
+ TypeClass eTypeClass = type.getTypeClass();
+ if (TypeClass_STRUCT != eTypeClass && TypeClass_EXCEPTION != eTypeClass)
+ {
+ throw RuntimeException(
+ type.getTypeName() +
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("is no struct or exception!") ),
+ Reference< XInterface >() );
+ }
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, type.getTypeLibType() );
+ OSL_ASSERT( pTD );
+ if (! pTD)
+ {
+ throw RuntimeException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get type descr of type ") ) +
+ type.getTypeName(),
+ Reference< XInterface >() );
+ }
+
+ ::std::vector< Any > vec;
+ vec.reserve( ((typelib_CompoundTypeDescription *)pTD)->nMembers ); // good guess
+ flatten_struct_members( &vec, val.getValue(), (typelib_CompoundTypeDescription *)pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ return Sequence< Any >( &vec[ 0 ], vec.size() );
+}
+
+//***********************************************************************
+DispatchRecorder::DispatchRecorder( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , ::cppu::OWeakObject( )
+ , m_xSMGR ( xSMGR )
+ , m_xConverter( m_xSMGR->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter"))), css::uno::UNO_QUERY )
+{
+}
+
+//************************************************************************
+DispatchRecorder::~DispatchRecorder()
+{
+}
+
+//*************************************************************************
+// generate header
+void SAL_CALL DispatchRecorder::startRecording( const css::uno::Reference< css::frame::XFrame >& ) throw( css::uno::RuntimeException )
+{
+ /* SAFE{ */
+ /* } */
+}
+
+//*************************************************************************
+void SAL_CALL DispatchRecorder::recordDispatch( const css::util::URL& aURL,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException )
+{
+ ::rtl::OUString aTarget;
+
+ com::sun::star::frame::DispatchStatement aStatement( aURL.Complete, aTarget, lArguments, 0, sal_False );
+ m_aStatements.push_back( aStatement );
+}
+
+//*************************************************************************
+void SAL_CALL DispatchRecorder::recordDispatchAsComment( const css::util::URL& aURL,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException )
+{
+ ::rtl::OUString aTarget;
+
+ // last parameter must be set to true -> it's a comment
+ com::sun::star::frame::DispatchStatement aStatement( aURL.Complete, aTarget, lArguments, 0, sal_True );
+ m_aStatements.push_back( aStatement );
+}
+
+//*************************************************************************
+void SAL_CALL DispatchRecorder::endRecording() throw( css::uno::RuntimeException )
+{
+ /* SAFE{ */
+ WriteGuard aWriteLock(m_aLock);
+ m_aStatements.clear();
+ /* } */
+}
+
+//*************************************************************************
+::rtl::OUString SAL_CALL DispatchRecorder::getRecordedMacro() throw( css::uno::RuntimeException )
+{
+ /* SAFE{ */
+ WriteGuard aWriteLock(m_aLock);
+
+ if ( m_aStatements.empty() )
+ return ::rtl::OUString();
+
+ ::rtl::OUStringBuffer aScriptBuffer;
+ aScriptBuffer.ensureCapacity(10000);
+ m_nRecordingID = 1;
+
+ aScriptBuffer.appendAscii("rem ----------------------------------------------------------------------\n");
+ aScriptBuffer.appendAscii("rem define variables\n");
+ aScriptBuffer.appendAscii("dim document as object\n");
+ aScriptBuffer.appendAscii("dim dispatcher as object\n");
+ aScriptBuffer.appendAscii("rem ----------------------------------------------------------------------\n");
+ aScriptBuffer.appendAscii("rem get access to the document\n");
+ aScriptBuffer.appendAscii("document = ThisComponent.CurrentController.Frame\n");
+ aScriptBuffer.appendAscii("dispatcher = createUnoService(\"com.sun.star.frame.DispatchHelper\")\n\n");
+
+ std::vector< com::sun::star::frame::DispatchStatement>::iterator p;
+ for ( p = m_aStatements.begin(); p != m_aStatements.end(); ++p )
+ implts_recordMacro( p->aCommand, p->aArgs, p->bIsComment, aScriptBuffer );
+ ::rtl::OUString sScript = aScriptBuffer.makeStringAndClear();
+ return sScript;
+ /* } */
+}
+
+//*************************************************************************
+void SAL_CALL DispatchRecorder::AppendToBuffer( css::uno::Any aValue, ::rtl::OUStringBuffer& aArgumentBuffer )
+{
+ // if value == bool
+ if (aValue.getValueTypeClass() == css::uno::TypeClass_STRUCT )
+ {
+ // structs are recorded as arrays, convert to "Sequence of any"
+ Sequence< Any > aSeq = make_seq_out_of_struct( aValue );
+ aArgumentBuffer.appendAscii("Array(");
+ for ( sal_Int32 nAny=0; nAny<aSeq.getLength(); nAny++ )
+ {
+ AppendToBuffer( aSeq[nAny], aArgumentBuffer );
+ if ( nAny+1 < aSeq.getLength() )
+ // not last argument
+ aArgumentBuffer.appendAscii(",");
+ }
+
+ aArgumentBuffer.appendAscii(")");
+ }
+ else if (aValue.getValueTypeClass() == css::uno::TypeClass_SEQUENCE )
+ {
+ // convert to "Sequence of any"
+ css::uno::Sequence < css::uno::Any > aSeq;
+ css::uno::Any aNew;
+ try { aNew = m_xConverter->convertTo( aValue, ::getCppuType((const css::uno::Sequence < css::uno::Any >*)0) ); }
+ catch (css::uno::Exception&) {}
+
+ aNew >>= aSeq;
+ aArgumentBuffer.appendAscii("Array(");
+ for ( sal_Int32 nAny=0; nAny<aSeq.getLength(); nAny++ )
+ {
+ AppendToBuffer( aSeq[nAny], aArgumentBuffer );
+ if ( nAny+1 < aSeq.getLength() )
+ // not last argument
+ aArgumentBuffer.appendAscii(",");
+ }
+
+ aArgumentBuffer.appendAscii(")");
+ }
+ else if (aValue.getValueTypeClass() == css::uno::TypeClass_STRING )
+ {
+ // strings need \"
+ ::rtl::OUString sVal;
+ aValue >>= sVal;
+
+ // encode non printable characters or '"' by using the CHR$ function
+ if ( sVal.getLength() )
+ {
+ const sal_Unicode* pChars = sVal.getStr();
+ sal_Bool bInString = sal_False;
+ for ( sal_Int32 nChar=0; nChar<sVal.getLength(); nChar ++ )
+ {
+ if ( pChars[nChar] < 32 || pChars[nChar] == '"' )
+ {
+ // problematic character detected
+ if ( bInString )
+ {
+ // close current string
+ aArgumentBuffer.appendAscii("\"");
+ bInString = sal_False;
+ }
+
+ if ( nChar>0 )
+ // if this is not the first character, parts of the string have already been added
+ aArgumentBuffer.appendAscii("+");
+
+ // add the character constant
+ aArgumentBuffer.appendAscii("CHR$(");
+ aArgumentBuffer.append( (sal_Int32) pChars[nChar] );
+ aArgumentBuffer.appendAscii(")");
+ }
+ else
+ {
+ if ( !bInString )
+ {
+ if ( nChar>0 )
+ // if this is not the first character, parts of the string have already been added
+ aArgumentBuffer.appendAscii("+");
+
+ // start a new string
+ aArgumentBuffer.appendAscii("\"");
+ bInString = sal_True;
+ }
+
+ aArgumentBuffer.append( pChars[nChar] );
+ }
+ }
+
+ // close string
+ if ( bInString )
+ aArgumentBuffer.appendAscii("\"");
+ }
+ else
+ aArgumentBuffer.appendAscii("\"\"");
+ }
+ else if (aValue.getValueType() == getCppuCharType())
+ {
+ // character variables are recorded as strings, back conversion must be handled in client code
+ sal_Unicode nVal = *((sal_Unicode*)aValue.getValue());
+ aArgumentBuffer.appendAscii("\"");
+ if ( (sal_Unicode(nVal) == '\"') )
+ // encode \" to \"\"
+ aArgumentBuffer.append((sal_Unicode)nVal);
+ aArgumentBuffer.append((sal_Unicode)nVal);
+ aArgumentBuffer.appendAscii("\"");
+ }
+ else
+ {
+ css::uno::Any aNew;
+ try
+ {
+ aNew = m_xConverter->convertToSimpleType( aValue, css::uno::TypeClass_STRING );
+ }
+ catch (css::script::CannotConvertException&) {}
+ catch (css::uno::Exception&) {}
+ ::rtl::OUString sVal;
+ aNew >>= sVal;
+
+ if (aValue.getValueTypeClass() == css::uno::TypeClass_ENUM )
+ {
+ ::rtl::OUString aName = aValue.getValueType().getTypeName();
+ aArgumentBuffer.append( aName );
+ aArgumentBuffer.appendAscii(".");
+ }
+
+ aArgumentBuffer.append(sVal);
+ }
+}
+
+void SAL_CALL DispatchRecorder::implts_recordMacro( const ::rtl::OUString& aURL,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
+ sal_Bool bAsComment, ::rtl::OUStringBuffer& aScriptBuffer )
+{
+ ::rtl::OUStringBuffer aArgumentBuffer(1000);
+ ::rtl::OUString sArrayName;
+ // this value is used to name the arrays of aArgumentBuffer
+ sArrayName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("args"));
+ sArrayName += ::rtl::OUString::valueOf((sal_Int32)m_nRecordingID);
+
+ aScriptBuffer.appendAscii("rem ----------------------------------------------------------------------\n");
+
+ sal_Int32 nLength = lArguments.getLength();
+ sal_Int32 nValidArgs = 0;
+ for( sal_Int32 i=0; i<nLength; ++i )
+ {
+ if(!lArguments[i].Value.hasValue())
+ continue;
+
+ ::rtl::OUStringBuffer sValBuffer(100);
+ try
+ {
+ AppendToBuffer(lArguments[i].Value, sValBuffer);
+ }
+ catch(const css::uno::Exception&)
+ {
+ sValBuffer.setLength(0);
+ }
+ if (!sValBuffer.getLength())
+ continue;
+
+ {
+ // add arg().Name
+ if(bAsComment)
+ aArgumentBuffer.appendAscii(REM_AS_COMMENT);
+ aArgumentBuffer.append (sArrayName);
+ aArgumentBuffer.appendAscii("(");
+ aArgumentBuffer.append (nValidArgs);
+ aArgumentBuffer.appendAscii(").Name = \"");
+ aArgumentBuffer.append (lArguments[i].Name);
+ aArgumentBuffer.appendAscii("\"\n");
+
+ // add arg().Value
+ if(bAsComment)
+ aArgumentBuffer.appendAscii(REM_AS_COMMENT);
+ aArgumentBuffer.append (sArrayName);
+ aArgumentBuffer.appendAscii("(");
+ aArgumentBuffer.append (nValidArgs);
+ aArgumentBuffer.appendAscii(").Value = ");
+ aArgumentBuffer.append (sValBuffer.makeStringAndClear());
+ aArgumentBuffer.appendAscii("\n");
+
+ ++nValidArgs;
+ }
+ }
+
+ // if aArgumentBuffer exist - pack it into the aScriptBuffer
+ if(nValidArgs>0)
+ {
+ if(bAsComment)
+ aScriptBuffer.appendAscii(REM_AS_COMMENT);
+ aScriptBuffer.appendAscii("dim ");
+ aScriptBuffer.append (sArrayName);
+ aScriptBuffer.appendAscii("(");
+ aScriptBuffer.append ((sal_Int32)(nValidArgs-1)); // 0 based!
+ aScriptBuffer.appendAscii(") as new com.sun.star.beans.PropertyValue\n");
+ aScriptBuffer.append (aArgumentBuffer.makeStringAndClear());
+ aScriptBuffer.appendAscii("\n");
+ }
+
+ // add code for dispatches
+ if(bAsComment)
+ aScriptBuffer.appendAscii(REM_AS_COMMENT);
+ aScriptBuffer.appendAscii("dispatcher.executeDispatch(document, \"");
+ aScriptBuffer.append (aURL);
+ aScriptBuffer.appendAscii("\", \"\", 0, ");
+ if(nValidArgs<1)
+ aScriptBuffer.appendAscii("Array()");
+ else
+ {
+ aScriptBuffer.append( sArrayName.getStr() );
+ aScriptBuffer.appendAscii("()");
+ }
+ aScriptBuffer.appendAscii(")\n\n");
+
+ /* SAFE { */
+ m_nRecordingID++;
+ /* } */
+}
+
+com::sun::star::uno::Type SAL_CALL DispatchRecorder::getElementType() throw (::com::sun::star::uno::RuntimeException)
+{
+ return ::getCppuType((const com::sun::star::frame::DispatchStatement *)NULL);
+}
+
+sal_Bool SAL_CALL DispatchRecorder::hasElements() throw (::com::sun::star::uno::RuntimeException)
+{
+ return (! m_aStatements.empty());
+}
+
+sal_Int32 SAL_CALL DispatchRecorder::getCount() throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_aStatements.size();
+}
+
+com::sun::star::uno::Any SAL_CALL DispatchRecorder::getByIndex(sal_Int32 idx) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ if (idx >= (sal_Int32)m_aStatements.size()) {
+ throw com::sun::star::lang::IndexOutOfBoundsException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Dispatch recorder out of bounds") ),
+ Reference< XInterface >() );
+
+ }
+
+ Any element(&m_aStatements[idx],
+ ::getCppuType((const com::sun::star::frame::DispatchStatement *)NULL));
+
+ return element;
+}
+
+void SAL_CALL DispatchRecorder::replaceByIndex(sal_Int32 idx, const com::sun::star::uno::Any& element) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ if (element.getValueType() !=
+ ::getCppuType((const com::sun::star::frame::DispatchStatement *)NULL)) {
+ throw com::sun::star::lang::IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Illegal argument in dispatch recorder") ),
+ Reference< XInterface >(), 2 );
+ }
+
+ if (idx >= (sal_Int32)m_aStatements.size()) {
+ throw com::sun::star::lang::IndexOutOfBoundsException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "Dispatch recorder out of bounds") ),
+ Reference< XInterface >() );
+
+ }
+
+ com::sun::star::frame::DispatchStatement *pStatement;
+
+ pStatement = (com::sun::star::frame::DispatchStatement *)element.getValue();
+
+ com::sun::star::frame::DispatchStatement aStatement(
+ pStatement->aCommand,
+ pStatement->aTarget,
+ pStatement->aArgs,
+ pStatement->nFlags,
+ pStatement->bIsComment);
+
+ m_aStatements[idx] = aStatement;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/recording/dispatchrecordersupplier.cxx b/framework/source/recording/dispatchrecordersupplier.cxx
new file mode 100644
index 000000000000..f711ee5d9a91
--- /dev/null
+++ b/framework/source/recording/dispatchrecordersupplier.cxx
@@ -0,0 +1,224 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// include own things
+#include <recording/dispatchrecordersupplier.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// include interfaces
+#include <com/sun/star/frame/XRecordableDispatch.hpp>
+
+//_________________________________________________________________________________________________________________
+// include other projects
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+
+//_________________________________________________________________________________________________________________
+// declarations
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_3(
+ DispatchRecorderSupplier,
+ OWeakObject,
+ DIRECT_INTERFACE(css::lang::XTypeProvider),
+ DIRECT_INTERFACE(css::lang::XServiceInfo),
+ DIRECT_INTERFACE(css::frame::XDispatchRecorderSupplier))
+
+DEFINE_XTYPEPROVIDER_3(
+ DispatchRecorderSupplier,
+ css::lang::XTypeProvider,
+ css::lang::XServiceInfo,
+ css::frame::XDispatchRecorderSupplier)
+
+DEFINE_XSERVICEINFO_MULTISERVICE(
+ DispatchRecorderSupplier,
+ ::cppu::OWeakObject,
+ SERVICENAME_DISPATCHRECORDERSUPPLIER,
+ IMPLEMENTATIONNAME_DISPATCHRECORDERSUPPLIER)
+
+DEFINE_INIT_SERVICE(
+ DispatchRecorderSupplier,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+)
+
+//_____________________________________________________________________________
+/**
+ @short standard constructor to create instance
+ @descr Because an instance will be initialized by her interface methods
+ it's not neccessary to do anything here.
+ */
+DispatchRecorderSupplier::DispatchRecorderSupplier( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+ // init baseclasses first!
+ // Attention: Don't change order of initialization!
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , ::cppu::OWeakObject( )
+ // init member
+ , m_xDispatchRecorder( NULL )
+ , m_xFactory ( xFactory )
+{
+}
+
+//_____________________________________________________________________________
+/**
+ @short standard destructor
+ @descr We are a helper and not a real service. So we doesn't provide
+ dispose() functionality. This supplier dies by ref count mechanism
+ and should release all internal used ones too.
+ */
+DispatchRecorderSupplier::~DispatchRecorderSupplier()
+{
+ m_xFactory = NULL;
+ m_xDispatchRecorder = NULL;
+}
+
+//_____________________________________________________________________________
+/**
+ @short set a new dispatch recorder on this supplier
+ @descr Because there can exist more then one recorder implementations
+ (to generate java/basic/... scripts from recorded data) it must
+ be possible to set it on a supplier.
+
+ @see getDispatchRecorder()
+
+ @param xRecorder
+ the new recorder to set it
+ <br><NULL/> isn't recommended, because recording without a
+ valid recorder can't work. But it's not checked here. So user
+ of this supplier can decide that without changing this
+ implementation.
+
+ @change 09.04.2002 by Andreas Schluens
+ */
+void SAL_CALL DispatchRecorderSupplier::setDispatchRecorder( const css::uno::Reference< css::frame::XDispatchRecorder >& xRecorder ) throw (css::uno::RuntimeException)
+{
+ // SAFE =>
+ WriteGuard aWriteLock(m_aLock);
+ m_xDispatchRecorder=xRecorder;
+ // => SAFE
+}
+//_____________________________________________________________________________
+/**
+ @short provides access to the dispatch recorder of this supplier
+ @descr Such recorder can be used outside to record dispatches.
+ But normaly he is used internaly only. Of course he must used
+ from outside to get the recorded data e.g. for saving it as a
+ script.
+
+ @see setDispatchRecorder()
+
+ @return the internal used dispatch recorder
+ <br>May it can be <NULL/> if no one was set before.
+
+ @change 09.04.2002 by Andreas Schluens
+ */
+css::uno::Reference< css::frame::XDispatchRecorder > SAL_CALL DispatchRecorderSupplier::getDispatchRecorder() throw (css::uno::RuntimeException)
+{
+ // SAFE =>
+ ReadGuard aReadLock(m_aLock);
+ return m_xDispatchRecorder;
+ // => SAFE
+}
+
+//_____________________________________________________________________________
+/**
+ @short execute a dispatch request and record it
+ @descr If given dispatch object provides right recording interface it
+ will be used. If it's not supported it record the pure dispatch
+ parameters only. There is no code neither the possibility to
+ check if recording is enabled or not.
+
+ @param aURL the command URL
+ @param lArguments optional arguments (see com.sun.star.document.MediaDescriptor for further informations)
+ @param xDispatcher the original dispatch object which should be recorded
+
+ @change 09.04.2002 by Andreas Schluens
+ */
+void SAL_CALL DispatchRecorderSupplier::dispatchAndRecord( const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments ,
+ const css::uno::Reference< css::frame::XDispatch >& xDispatcher ) throw (css::uno::RuntimeException)
+{
+ // SAFE =>
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XDispatchRecorder > xRecorder = m_xDispatchRecorder;
+ aReadLock.unlock();
+ // => SAFE
+
+ // clear unspecific situations
+ if (!xDispatcher.is())
+ throw css::uno::RuntimeException(DECLARE_ASCII("specification violation: dispatcher is NULL"), static_cast< ::cppu::OWeakObject* >(this));
+
+ if (!xRecorder.is())
+ throw css::uno::RuntimeException(DECLARE_ASCII("specification violation: no valid dispatch recorder available"), static_cast< ::cppu::OWeakObject* >(this));
+
+ // check, if given dispatch supports record functionality by itself ...
+ // or must be wrapped.
+ css::uno::Reference< css::frame::XRecordableDispatch > xRecordable(
+ xDispatcher,
+ css::uno::UNO_QUERY);
+
+ if (xRecordable.is())
+ xRecordable->dispatchAndRecord(aURL,lArguments,xRecorder);
+ else
+ {
+ // There is no reason to wait for information about success
+ // of this request. Because status information of a dispatch
+ // are not guaranteed. So we execute it and record used
+ // parameters only.
+ xDispatcher->dispatch(aURL,lArguments);
+ xRecorder->recordDispatch(aURL,lArguments);
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/register/register3rdcomponents.cxx b/framework/source/register/register3rdcomponents.cxx
new file mode 100644
index 000000000000..c4fa80798507
--- /dev/null
+++ b/framework/source/register/register3rdcomponents.cxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+//_________________________________________________________________________________________________________________
+// includes of my own project
+//_________________________________________________________________________________________________________________
+#include <macros/registration.hxx>
+
+/*=================================================================================================================
+ Add new include and new register info to for new services.
+
+ Example:
+
+ #ifndef __YOUR_SERVICE_1_HXX_
+ #include <service1.hxx>
+ #endif
+
+ #ifndef __YOUR_SERVICE_2_HXX_
+ #include <service2.hxx>
+ #endif
+
+ COMPONENTGETIMPLEMENTATIONENVIRONMENT
+
+ COMPONENTGETFACTORY ( IFFACTORIE( Service1 )
+ else
+ IFFACTORIE( Service2 )
+ )
+=================================================================================================================*/
+#include <jobs/helponstartup.hxx>
+#include <tabwin/tabwinfactory.hxx>
+#include <dispatch/systemexec.hxx>
+#include <jobs/shelljob.hxx>
+
+COMPONENTGETIMPLEMENTATIONENVIRONMENT
+
+COMPONENTGETFACTORY ( IFFACTORY( ::framework::HelpOnStartup ) else
+ IFFACTORY( ::framework::TabWinFactory ) else
+ IFFACTORY( ::framework::SystemExec ) else
+ IFFACTORY( ::framework::ShellJob )
+ )
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/register/registerlogindialog.cxx b/framework/source/register/registerlogindialog.cxx
new file mode 100644
index 000000000000..c0f54947e8e3
--- /dev/null
+++ b/framework/source/register/registerlogindialog.cxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// includes of my own project
+//_________________________________________________________________________________________________________________
+#include <macros/registration.hxx>
+
+/*=================================================================================================================
+ Add new include and new register info to for new services.
+
+ Example:
+
+ #ifndef __YOUR_SERVICE_1_HXX_
+ #include <service1.hxx>
+ #endif
+
+ #ifndef __YOUR_SERVICE_2_HXX_
+ #include <service2.hxx>
+ #endif
+
+ COMPONENTGETIMPLEMENTATIONENVIRONMENT
+
+ COMPONENTGETFACTORY ( IFFACTORIE( Service1 )
+ else
+ IFFACTORIE( Service2 )
+ )
+=================================================================================================================*/
+
+#include <services/logindialog.hxx>
+
+COMPONENTGETIMPLEMENTATIONENVIRONMENT
+
+COMPONENTGETFACTORY ( IFFACTORY( ::framework::LoginDialog )
+ )
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/register/registerservices.cxx b/framework/source/register/registerservices.cxx
new file mode 100644
index 000000000000..a69f44a03f2d
--- /dev/null
+++ b/framework/source/register/registerservices.cxx
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <macros/registration.hxx>
+
+/*=================================================================================================================
+ Add new include and new register info to for new services.
+
+ Example:
+
+ #ifndef __YOUR_SERVICE_1_HXX_
+ #include <service1.hxx>
+ #endif
+
+ #ifndef __YOUR_SERVICE_2_HXX_
+ #include <service2.hxx>
+ #endif
+
+ COMPONENTGETIMPLEMENTATIONENVIRONMENT
+
+ COMPONENTGETFACTORY ( IFFACTORIE( Service1 )
+ else
+ IFFACTORIE( Service2 )
+ )
+=================================================================================================================*/
+#include <services/urltransformer.hxx>
+#include <services/desktop.hxx>
+#include <services/tabwindowservice.hxx>
+#include <services/frame.hxx>
+#include <services/modulemanager.hxx>
+#include <jobs/jobexecutor.hxx>
+#include <jobs/jobdispatch.hxx>
+#include <services/backingcomp.hxx>
+#include <services/layoutmanager.hxx>
+#include <uifactory/uielementfactorymanager.hxx>
+#include <uifactory/popupmenucontrollerfactory.hxx>
+#include <uielement/objectmenucontroller.hxx>
+#include <uielement/controlmenucontroller.hxx>
+#include <uielement/uicommanddescription.hxx>
+#include <uiconfiguration/uiconfigurationmanager.hxx>
+#include <uiconfiguration/moduleuicfgsupplier.hxx>
+#include <uiconfiguration/moduleuiconfigurationmanager.hxx>
+#include <uifactory/menubarfactory.hxx>
+#include <accelerators/globalacceleratorconfiguration.hxx>
+#include <accelerators/moduleacceleratorconfiguration.hxx>
+#include <accelerators/documentacceleratorconfiguration.hxx>
+#include <uifactory/toolboxfactory.hxx>
+#include <uifactory/addonstoolboxfactory.hxx>
+#include "uiconfiguration/windowstateconfiguration.hxx"
+#include "uifactory/toolbarcontrollerfactory.hxx"
+#include "uifactory/statusbarcontrollerfactory.hxx"
+#include <services/autorecovery.hxx>
+#include <helper/statusindicatorfactory.hxx>
+#include <uielement/recentfilesmenucontroller.hxx>
+#include <uifactory/statusbarfactory.hxx>
+#include <uiconfiguration/uicategorydescription.hxx>
+#include <services/sessionlistener.hxx>
+#include <services/taskcreatorsrv.hxx>
+
+#include <uielement/langselectionstatusbarcontroller.hxx>
+#include <uiconfiguration/imagemanager.hxx>
+#include <uifactory/windowcontentfactorymanager.hxx>
+#include <services/substitutepathvars.hxx>
+#include <services/pathsettings.hxx>
+
+COMPONENTGETIMPLEMENTATIONENVIRONMENT
+
+COMPONENTGETFACTORY ( IFFACTORY( ::framework::URLTransformer ) else
+ IFFACTORY( ::framework::Desktop ) else
+ IFFACTORY( ::framework::Frame ) else
+ IFFACTORY( ::framework::JobExecutor ) else
+ IFFACTORY( ::framework::JobDispatch ) else
+ IFFACTORY( ::framework::BackingComp ) else
+ IFFACTORY( ::framework::LayoutManager ) else
+ IFFACTORY( ::framework::UIElementFactoryManager ) else
+ IFFACTORY( ::framework::PopupMenuControllerFactory ) else
+ IFFACTORY( ::framework::ObjectMenuController ) else
+ IFFACTORY( ::framework::ControlMenuController ) else
+ IFFACTORY( ::framework::UICommandDescription ) else
+ IFFACTORY( ::framework::ModuleManager ) else
+ IFFACTORY( ::framework::UIConfigurationManager ) else
+ IFFACTORY( ::framework::ModuleUIConfigurationManagerSupplier ) else
+ IFFACTORY( ::framework::ModuleUIConfigurationManager ) else
+ IFFACTORY( ::framework::MenuBarFactory ) else
+ IFFACTORY( ::framework::GlobalAcceleratorConfiguration ) else
+ IFFACTORY( ::framework::ModuleAcceleratorConfiguration ) else
+ IFFACTORY( ::framework::DocumentAcceleratorConfiguration ) else
+ IFFACTORY( ::framework::ToolBoxFactory ) else
+ IFFACTORY( ::framework::AddonsToolBoxFactory ) else
+ IFFACTORY( ::framework::WindowStateConfiguration ) else
+ IFFACTORY( ::framework::ToolbarControllerFactory ) else
+ IFFACTORY( ::framework::AutoRecovery ) else
+ IFFACTORY( ::framework::StatusIndicatorFactory ) else
+ IFFACTORY( ::framework::RecentFilesMenuController ) else
+ IFFACTORY( ::framework::StatusBarFactory ) else
+ IFFACTORY( ::framework::UICategoryDescription ) else
+ IFFACTORY( ::framework::SessionListener ) else
+ IFFACTORY( ::framework::StatusbarControllerFactory ) else
+ IFFACTORY( ::framework::SessionListener ) else
+ IFFACTORY( ::framework::TaskCreatorService ) else
+ IFFACTORY( ::framework::ImageManager ) else
+ IFFACTORY( ::framework::LangSelectionStatusbarController ) else
+ IFFACTORY( ::framework::WindowContentFactoryManager ) else
+ IFFACTORY( ::framework::TabWindowService ) else
+ IFFACTORY( ::framework::SubstitutePathVariables ) else
+ IFFACTORY( ::framework::PathSettings )
+ )
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/register/registertemp.cxx b/framework/source/register/registertemp.cxx
new file mode 100644
index 000000000000..9680c2c288ff
--- /dev/null
+++ b/framework/source/register/registertemp.cxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+//_________________________________________________________________________________________________________________
+// includes of my own project
+//_________________________________________________________________________________________________________________
+#include <macros/registration.hxx>
+
+/*=================================================================================================================
+ Add new include and new register info to for new services.
+
+ Example:
+
+ #ifndef __YOUR_SERVICE_1_HXX_
+ #include <service1.hxx>
+ #endif
+
+ #ifndef __YOUR_SERVICE_2_HXX_
+ #include <service2.hxx>
+ #endif
+
+ COMPONENTGETIMPLEMENTATIONENVIRONMENT
+
+ COMPONENTGETFACTORY ( IFFACTORIE( Service1 )
+ else
+ IFFACTORIE( Service2 )
+ )
+=================================================================================================================*/
+#include <services/mediatypedetectionhelper.hxx>
+#include <dispatch/mailtodispatcher.hxx>
+#include <dispatch/oxt_handler.hxx>
+#include <dispatch/popupmenudispatcher.hxx>
+#include <dispatch/servicehandler.hxx>
+#include <services/dispatchhelper.hxx>
+#include <recording/dispatchrecorder.hxx>
+#include <recording/dispatchrecordersupplier.hxx>
+#include <services/license.hxx>
+#include <services/uriabbreviation.hxx>
+#include <uielement/simpletextstatusbarcontroller.hxx>
+#include <uielement/logoimagestatusbarcontroller.hxx>
+#include <uielement/logotextstatusbarcontroller.hxx>
+#include <uielement/fontmenucontroller.hxx>
+#include <uielement/fontsizemenucontroller.hxx>
+#include <uielement/footermenucontroller.hxx>
+#include <uielement/headermenucontroller.hxx>
+#include <uielement/langselectionmenucontroller.hxx>
+#include <uielement/macrosmenucontroller.hxx>
+#include <uielement/newmenucontroller.hxx>
+#include <uielement/toolbarsmenucontroller.hxx>
+#include <uielement/popupmenucontroller.hxx>
+
+COMPONENTGETIMPLEMENTATIONENVIRONMENT
+
+COMPONENTGETFACTORY ( IFFACTORY( ::framework::MediaTypeDetectionHelper )
+ IFFACTORY( ::framework::MailToDispatcher ) else
+ IFFACTORY( ::framework::ServiceHandler ) else
+ IFFACTORY( ::framework::LogoTextStatusbarController ) else
+ IFFACTORY( ::framework::LogoImageStatusbarController ) else
+ IFFACTORY( ::framework::License ) else
+ IFFACTORY( ::framework::PopupMenuDispatcher ) else
+ IFFACTORY( ::framework::DispatchHelper ) else
+ IFFACTORY( ::framework::DispatchRecorder ) else
+ IFFACTORY( ::framework::DispatchRecorderSupplier ) else
+ IFFACTORY( ::framework::SimpleTextStatusbarController ) else
+ IFFACTORY( ::framework::ToolbarsMenuController ) else
+ IFFACTORY( ::framework::FontMenuController ) else
+ IFFACTORY( ::framework::MacrosMenuController ) else
+ IFFACTORY( ::framework::NewMenuController ) else
+ IFFACTORY( ::framework::FontSizeMenuController ) else
+ IFFACTORY( ::framework::UriAbbreviation ) else
+ IFFACTORY( ::framework::FooterMenuController ) else
+ IFFACTORY( ::framework::HeaderMenuController ) else
+ IFFACTORY( ::framework::LanguageSelectionMenuController ) else
+ IFFACTORY( ::framework::Oxt_Handler ) else
+ IFFACTORY( ::framework::PopupMenuController )
+ )
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/autorecovery.cxx b/framework/source/services/autorecovery.cxx
new file mode 100644
index 000000000000..e61ae11c6bd6
--- /dev/null
+++ b/framework/source/services/autorecovery.cxx
@@ -0,0 +1,3642 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "services/autorecovery.hxx"
+#include <loadenv/loadenv.hxx>
+
+//_______________________________________________
+// own includes
+#include <loadenv/targethelper.hxx>
+#include <pattern/frame.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+#include <classes/resource.hrc>
+#include <classes/fwkresid.hxx>
+#include <protocols.h>
+#include <properties.h>
+#include <services.h>
+
+#include "helper/mischelper.hxx"
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/frame/XLoadable.hpp>
+#include <com/sun/star/frame/XModel2.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/frame/XTitle.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
+#include <com/sun/star/frame/XNotifyingDispatch.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XContainerQuery.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XDocumentRecovery.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+
+//_______________________________________________
+// other includes
+#include <comphelper/configurationhelper.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/pathoptions.hxx>
+#include <tools/link.hxx>
+#include <tools/string.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/tempfile.hxx>
+#include <ucbhelper/content.hxx>
+
+#include <osl/time.h>
+#include <vcl/msgbox.hxx>
+#include <osl/file.hxx>
+#include <unotools/bootstrap.hxx>
+#include <unotools/configmgr.hxx>
+#include <svl/documentlockfile.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+
+#include <tools/urlobj.hxx>
+
+#include <fwkdllapi.h>
+
+//_______________________________________________
+// namespaces
+
+#ifndef css
+namespace css = ::com::sun::star;
+#endif
+
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::container::XEnumeration;
+using ::com::sun::star::document::XDocumentRecovery;
+using ::com::sun::star::frame::XModel2;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::frame::XFrame;
+using ::com::sun::star::frame::XController2;
+using ::com::sun::star::frame::XLoadable;
+using ::com::sun::star::frame::XStorable;
+using ::com::sun::star::lang::XComponent;
+
+namespace fpf = ::framework::pattern::frame;
+
+
+namespace framework
+{
+
+//-----------------------------------------------
+// recovery.xcu
+static const ::rtl::OUString CFG_PACKAGE_RECOVERY(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Recovery/"));
+static const ::rtl::OUString CFG_ENTRY_RECOVERYLIST(RTL_CONSTASCII_USTRINGPARAM("RecoveryList"));
+static const ::rtl::OUString CFG_PATH_RECOVERYINFO(RTL_CONSTASCII_USTRINGPARAM("RecoveryInfo"));
+static const ::rtl::OUString CFG_ENTRY_ENABLED(RTL_CONSTASCII_USTRINGPARAM("Enabled"));
+static const ::rtl::OUString CFG_ENTRY_CRASHED(RTL_CONSTASCII_USTRINGPARAM("Crashed"));
+static const ::rtl::OUString CFG_ENTRY_SESSIONDATA(RTL_CONSTASCII_USTRINGPARAM("SessionData"));
+
+static const ::rtl::OUString CFG_ENTRY_AUTOSAVE_ENABLED(RTL_CONSTASCII_USTRINGPARAM("AutoSave/Enabled"));
+static const ::rtl::OUString CFG_ENTRY_AUTOSAVE_TIMEINTERVALL(RTL_CONSTASCII_USTRINGPARAM("AutoSave/TimeIntervall"));
+
+static const ::rtl::OUString CFG_PATH_AUTOSAVE(RTL_CONSTASCII_USTRINGPARAM("AutoSave"));
+static const ::rtl::OUString CFG_ENTRY_MINSPACE_DOCSAVE(RTL_CONSTASCII_USTRINGPARAM("MinSpaceDocSave"));
+static const ::rtl::OUString CFG_ENTRY_MINSPACE_CONFIGSAVE(RTL_CONSTASCII_USTRINGPARAM("MinSpaceConfigSave"));
+
+static const ::rtl::OUString CFG_PACKAGE_MODULES(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup/Office/Factories"));
+static const ::rtl::OUString CFG_ENTRY_REALDEFAULTFILTER(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryActualFilter"));
+
+static const ::rtl::OUString CFG_ENTRY_PROP_TEMPURL(RTL_CONSTASCII_USTRINGPARAM("TempURL"));
+static const ::rtl::OUString CFG_ENTRY_PROP_ORIGINALURL(RTL_CONSTASCII_USTRINGPARAM("OriginalURL"));
+static const ::rtl::OUString CFG_ENTRY_PROP_TEMPLATEURL(RTL_CONSTASCII_USTRINGPARAM("TemplateURL"));
+static const ::rtl::OUString CFG_ENTRY_PROP_FACTORYURL(RTL_CONSTASCII_USTRINGPARAM("FactoryURL"));
+static const ::rtl::OUString CFG_ENTRY_PROP_MODULE(RTL_CONSTASCII_USTRINGPARAM("Module"));
+static const ::rtl::OUString CFG_ENTRY_PROP_DOCUMENTSTATE(RTL_CONSTASCII_USTRINGPARAM("DocumentState"));
+static const ::rtl::OUString CFG_ENTRY_PROP_FILTER(RTL_CONSTASCII_USTRINGPARAM("Filter"));
+static const ::rtl::OUString CFG_ENTRY_PROP_TITLE(RTL_CONSTASCII_USTRINGPARAM("Title"));
+static const ::rtl::OUString CFG_ENTRY_PROP_ID(RTL_CONSTASCII_USTRINGPARAM("ID"));
+static const ::rtl::OUString CFG_ENTRY_PROP_VIEWNAMES(RTL_CONSTASCII_USTRINGPARAM("ViewNames"));
+
+static const ::rtl::OUString FILTER_PROP_TYPE(RTL_CONSTASCII_USTRINGPARAM("Type"));
+static const ::rtl::OUString FILTER_PROP_NAME(RTL_CONSTASCII_USTRINGPARAM("Name"));
+static const ::rtl::OUString TYPE_PROP_EXTENSIONS(RTL_CONSTASCII_USTRINGPARAM("Extensions"));
+static const ::rtl::OUString DOCINFO_PROP_TEMPLATE(RTL_CONSTASCII_USTRINGPARAM("TemplateFileName"));
+
+// setup.xcu
+static const ::rtl::OUString CFG_ENTRY_PROP_EMPTYDOCUMENTURL(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryEmptyDocumentURL"));
+static const ::rtl::OUString CFG_ENTRY_PROP_DEFAULTFILTER(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryDefaultFilter"));
+static const ::rtl::OUString CFG_ENTRY_PROP_FACTORYSERVICE(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryDocumentService"));
+
+static const ::rtl::OUString EVENT_ON_NEW(RTL_CONSTASCII_USTRINGPARAM("OnNew"));
+static const ::rtl::OUString EVENT_ON_LOAD(RTL_CONSTASCII_USTRINGPARAM("OnLoad"));
+static const ::rtl::OUString EVENT_ON_UNLOAD(RTL_CONSTASCII_USTRINGPARAM("OnUnload"));
+static const ::rtl::OUString EVENT_ON_MODIFYCHANGED(RTL_CONSTASCII_USTRINGPARAM("OnModifyChanged"));
+static const ::rtl::OUString EVENT_ON_SAVE(RTL_CONSTASCII_USTRINGPARAM("OnSave"));
+static const ::rtl::OUString EVENT_ON_SAVEAS(RTL_CONSTASCII_USTRINGPARAM("OnSaveAs"));
+static const ::rtl::OUString EVENT_ON_SAVETO(RTL_CONSTASCII_USTRINGPARAM("OnCopyTo"));
+static const ::rtl::OUString EVENT_ON_SAVEDONE(RTL_CONSTASCII_USTRINGPARAM("OnSaveDone"));
+static const ::rtl::OUString EVENT_ON_SAVEASDONE(RTL_CONSTASCII_USTRINGPARAM("OnSaveAsDone"));
+static const ::rtl::OUString EVENT_ON_SAVETODONE(RTL_CONSTASCII_USTRINGPARAM("OnCopyToDone"));
+static const ::rtl::OUString EVENT_ON_SAVEFAILED(RTL_CONSTASCII_USTRINGPARAM("OnSaveFailed"));
+static const ::rtl::OUString EVENT_ON_SAVEASFAILED(RTL_CONSTASCII_USTRINGPARAM("OnSaveAsFailed"));
+static const ::rtl::OUString EVENT_ON_SAVETOFAILED(RTL_CONSTASCII_USTRINGPARAM("OnCopyToFailed"));
+
+static const ::rtl::OUString RECOVERY_ITEM_BASE_IDENTIFIER(RTL_CONSTASCII_USTRINGPARAM("recovery_item_"));
+
+static const ::rtl::OUString CMD_PROTOCOL(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.autorecovery:"));
+
+static const ::rtl::OUString CMD_DO_AUTO_SAVE(RTL_CONSTASCII_USTRINGPARAM("/doAutoSave")); // force AutoSave ignoring the AutoSave timer
+static const ::rtl::OUString CMD_DO_PREPARE_EMERGENCY_SAVE(RTL_CONSTASCII_USTRINGPARAM("/doPrepareEmergencySave")); // prepare the office for the following EmergencySave step (hide windows etcpp.)
+static const ::rtl::OUString CMD_DO_EMERGENCY_SAVE(RTL_CONSTASCII_USTRINGPARAM("/doEmergencySave")); // do EmergencySave on crash
+static const ::rtl::OUString CMD_DO_RECOVERY(RTL_CONSTASCII_USTRINGPARAM("/doAutoRecovery")); // recover all crashed documents
+static const ::rtl::OUString CMD_DO_ENTRY_BACKUP(RTL_CONSTASCII_USTRINGPARAM("/doEntryBackup")); // try to store a temp or original file to a user defined location
+static const ::rtl::OUString CMD_DO_ENTRY_CLEANUP(RTL_CONSTASCII_USTRINGPARAM("/doEntryCleanUp")); // remove the specified entry from the recovery cache
+static const ::rtl::OUString CMD_DO_SESSION_SAVE(RTL_CONSTASCII_USTRINGPARAM("/doSessionSave")); // save all open documents if e.g. a window manager closes an user session
+static const ::rtl::OUString CMD_DO_SESSION_QUIET_QUIT(RTL_CONSTASCII_USTRINGPARAM("/doSessionQuietQuit")); // let the current session be quietly closed ( the saving should be done using doSessionSave previously ) if e.g. a window manager closes an user session
+static const ::rtl::OUString CMD_DO_SESSION_RESTORE(RTL_CONSTASCII_USTRINGPARAM("/doSessionRestore")); // restore a saved user session from disc
+static const ::rtl::OUString CMD_DO_DISABLE_RECOVERY(RTL_CONSTASCII_USTRINGPARAM("/disableRecovery")); // disable recovery and auto save (!) temp. for this office session
+static const ::rtl::OUString CMD_DO_SET_AUTOSAVE_STATE(RTL_CONSTASCII_USTRINGPARAM("/setAutoSaveState")); // disable/enable auto save (not crash save) for this office session
+
+static const ::rtl::OUString REFERRER_USER(RTL_CONSTASCII_USTRINGPARAM("private:user"));
+
+static const ::rtl::OUString PROP_DISPATCH_ASYNCHRON(RTL_CONSTASCII_USTRINGPARAM("DispatchAsynchron"));
+static const ::rtl::OUString PROP_PROGRESS(RTL_CONSTASCII_USTRINGPARAM("StatusIndicator"));
+static const ::rtl::OUString PROP_SAVEPATH(RTL_CONSTASCII_USTRINGPARAM("SavePath"));
+static const ::rtl::OUString PROP_ENTRY_ID(RTL_CONSTASCII_USTRINGPARAM("EntryID"));
+static const ::rtl::OUString PROP_AUTOSAVE_STATE(RTL_CONSTASCII_USTRINGPARAM("AutoSaveState"));
+
+static const ::rtl::OUString OPERATION_START(RTL_CONSTASCII_USTRINGPARAM("start"));
+static const ::rtl::OUString OPERATION_STOP(RTL_CONSTASCII_USTRINGPARAM("stop"));
+static const ::rtl::OUString OPERATION_UPDATE(RTL_CONSTASCII_USTRINGPARAM("update"));
+
+static const sal_Int32 MIN_DISCSPACE_DOCSAVE = 5; // [MB]
+static const sal_Int32 MIN_DISCSPACE_CONFIGSAVE = 1; // [MB]
+static const sal_Int32 RETRY_STORE_ON_FULL_DISC_FOREVER = 300; // not forever ... but often enough .-)
+static const sal_Int32 RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL = 3; // in case FULL DISC does not seam the real problem
+static const sal_Int32 GIVE_UP_RETRY = 1; // in case FULL DISC does not seam the real problem
+
+#define SAVE_IN_PROGRESS sal_True
+#define SAVE_FINISHED sal_False
+
+#define LOCK_FOR_CACHE_ADD_REMOVE sal_True
+#define LOCK_FOR_CACHE_USE sal_False
+
+#define MIN_TIME_FOR_USER_IDLE 10000 // 10s user idle
+
+// enable the following defines in case you whish to simulate a full disc for debug purposes .-)
+
+// this define throws everytime a document is stored or a configuration change
+// should be flushed an exception ... so the special error handler for this scenario is triggered
+// #define TRIGGER_FULL_DISC_CHECK
+
+// force "return sal_False" for the method impl_enoughDiscSpace().
+// #define SIMULATE_FULL_DISC
+
+//-----------------------------------------------
+// #define ENABLE_RECOVERY_LOGGING
+#undef ENABLE_RECOVERY_LOGGING
+#ifdef ENABLE_RECOVERY_LOGGING
+ #define LOGFILE_RECOVERY "recovery.log"
+
+ #define LOG_RECOVERY(MSG) \
+ { \
+ WRITE_LOGFILE(LOGFILE_RECOVERY, MSG) \
+ WRITE_LOGFILE(LOGFILE_RECOVERY, "\n") \
+ }
+#else
+ #undef LOGFILE_RECOVERY
+ #define LOG_RECOVERY(MSG)
+#endif
+
+//-----------------------------------------------
+class CacheLockGuard
+{
+ private:
+
+ // holds the outside calli alive, so it's shared resources
+ // are valid everytimes
+ css::uno::Reference< css::uno::XInterface > m_xOwner;
+
+ // mutex shared with outside calli !
+ LockHelper& m_rSharedMutex;
+
+ // this variable knows the state of the "cache lock"
+ sal_Int32& m_rCacheLock;
+
+ // to prevent increasing/decreasing of m_rCacheLock more then ones
+ // we must know if THIS guard has an actual lock set there !
+ sal_Bool m_bLockedByThisGuard;
+
+ public:
+
+ CacheLockGuard(AutoRecovery* pOwner ,
+ LockHelper& rMutex ,
+ sal_Int32& rCacheLock ,
+ sal_Bool bLockForAddRemoveVectorItems);
+ ~CacheLockGuard();
+
+ void lock(sal_Bool bLockForAddRemoveVectorItems);
+ void unlock();
+};
+
+//-----------------------------------------------
+CacheLockGuard::CacheLockGuard(AutoRecovery* pOwner ,
+ LockHelper& rMutex ,
+ sal_Int32& rCacheLock ,
+ sal_Bool bLockForAddRemoveVectorItems)
+ : m_xOwner (static_cast< css::frame::XDispatch* >(pOwner))
+ , m_rSharedMutex (rMutex )
+ , m_rCacheLock (rCacheLock )
+ , m_bLockedByThisGuard(sal_False )
+{
+ lock(bLockForAddRemoveVectorItems);
+}
+
+//-----------------------------------------------
+CacheLockGuard::~CacheLockGuard()
+{
+ unlock();
+ m_xOwner.clear();
+}
+
+//-----------------------------------------------
+void CacheLockGuard::lock(sal_Bool bLockForAddRemoveVectorItems)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_rSharedMutex);
+
+ if (m_bLockedByThisGuard)
+ return;
+
+ // This cache lock is needed only to prevent us from removing/adding
+ // items from/into the recovery cache ... during it's used at another code place
+ // for iterating .-)
+
+ // Modifying of item properties is allowed and sometimes needed!
+ // So we should detect only the dangerous state of concurrent add/remove
+ // requests and throw an exception then ... which can of course break the whole
+ // operation. On the other side a crash reasoned by an invalid stl iterator
+ // will have the same effect .-)
+
+ if (
+ (m_rCacheLock > 0 ) &&
+ (bLockForAddRemoveVectorItems)
+ )
+ {
+ OSL_FAIL("Re-entrance problem detected. Using of an stl structure in combination with iteration, adding, removing of elements etcpp.");
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Re-entrance problem detected. Using of an stl structure in combination with iteration, adding, removing of elements etcpp.")),
+ m_xOwner);
+ }
+
+ ++m_rCacheLock;
+ m_bLockedByThisGuard = sal_True;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void CacheLockGuard::unlock()
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_rSharedMutex);
+
+ if ( ! m_bLockedByThisGuard)
+ return;
+
+ --m_rCacheLock;
+ m_bLockedByThisGuard = sal_False;
+
+ if (m_rCacheLock < 0)
+ {
+ OSL_FAIL("Wrong using of member m_nDocCacheLock detected. A ref counted value shouldn't reach values <0 .-)");
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Wrong using of member m_nDocCacheLock detected. A ref counted value shouldn't reach values <0 .-)")),
+ m_xOwner);
+ }
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+DispatchParams::DispatchParams()
+ : m_nWorkingEntryID(-1)
+{
+};
+
+//-----------------------------------------------
+DispatchParams::DispatchParams(const ::comphelper::SequenceAsHashMap& lArgs ,
+ const css::uno::Reference< css::uno::XInterface >& xOwner)
+{
+ m_nWorkingEntryID = lArgs.getUnpackedValueOrDefault(PROP_ENTRY_ID, (sal_Int32)-1 );
+ m_xProgress = lArgs.getUnpackedValueOrDefault(PROP_PROGRESS, css::uno::Reference< css::task::XStatusIndicator >());
+ m_sSavePath = lArgs.getUnpackedValueOrDefault(PROP_SAVEPATH, ::rtl::OUString() );
+ m_xHoldRefForAsyncOpAlive = xOwner;
+};
+
+//-----------------------------------------------
+DispatchParams::DispatchParams(const DispatchParams& rCopy)
+{
+ m_xProgress = rCopy.m_xProgress;
+ m_sSavePath = rCopy.m_sSavePath;
+ m_nWorkingEntryID = rCopy.m_nWorkingEntryID;
+ m_xHoldRefForAsyncOpAlive = rCopy.m_xHoldRefForAsyncOpAlive;
+};
+
+//-----------------------------------------------
+DispatchParams::~DispatchParams()
+{};
+
+//-----------------------------------------------
+DispatchParams& DispatchParams::operator=(const DispatchParams& rCopy)
+{
+ m_xProgress = rCopy.m_xProgress;
+ m_sSavePath = rCopy.m_sSavePath;
+ m_nWorkingEntryID = rCopy.m_nWorkingEntryID;
+ m_xHoldRefForAsyncOpAlive = rCopy.m_xHoldRefForAsyncOpAlive;
+ return *this;
+}
+
+//-----------------------------------------------
+void DispatchParams::forget()
+{
+ m_sSavePath = ::rtl::OUString();
+ m_nWorkingEntryID = -1;
+ m_xProgress.clear();
+ m_xHoldRefForAsyncOpAlive.clear();
+};
+
+//-----------------------------------------------
+DEFINE_XINTERFACE_10(AutoRecovery ,
+ OWeakObject ,
+ DIRECT_INTERFACE (css::lang::XTypeProvider ),
+ DIRECT_INTERFACE (css::lang::XServiceInfo ),
+ DIRECT_INTERFACE (css::frame::XDispatch ),
+ DIRECT_INTERFACE (css::beans::XMultiPropertySet ),
+ DIRECT_INTERFACE (css::beans::XFastPropertySet ),
+ DIRECT_INTERFACE (css::beans::XPropertySet ),
+ DIRECT_INTERFACE (css::document::XEventListener ),
+ DIRECT_INTERFACE (css::util::XChangesListener ),
+ DIRECT_INTERFACE (css::util::XModifyListener ),
+ DERIVED_INTERFACE(css::lang::XEventListener, css::document::XEventListener))
+
+//-----------------------------------------------
+DEFINE_XTYPEPROVIDER_6(AutoRecovery ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::frame::XDispatch ,
+ css::beans::XMultiPropertySet,
+ css::beans::XFastPropertySet ,
+ css::beans::XPropertySet )
+
+//-----------------------------------------------
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(AutoRecovery ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_AUTORECOVERY ,
+ IMPLEMENTATIONNAME_AUTORECOVERY)
+
+//-----------------------------------------------
+DEFINE_INIT_SERVICE(
+ AutoRecovery,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+
+ // read configuration to know if autosave/recovery is on/off etcpp...
+ implts_readConfig();
+
+ implts_startListening();
+
+ // establish callback for our internal used timer.
+ // Note: Its only active, if the timer will be started ...
+ m_aTimer.SetTimeoutHdl(LINK(this, AutoRecovery, implts_timerExpired));
+ }
+ )
+
+//-----------------------------------------------
+AutoRecovery::AutoRecovery(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase (&Application::GetSolarMutex() )
+ , ::cppu::OBroadcastHelper ( m_aLock.getShareableOslMutex() )
+ , ::cppu::OPropertySetHelper( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
+ , ::cppu::OWeakObject ( )
+ , m_xSMGR (xSMGR )
+ , m_bListenForDocEvents (sal_False )
+ , m_bListenForConfigChanges (sal_False )
+ , m_nAutoSaveTimeIntervall (0 )
+ , m_eJob (AutoRecovery::E_NO_JOB )
+ , m_aAsyncDispatcher ( LINK( this, AutoRecovery, implts_asyncDispatch ) )
+ , m_eTimerType (E_DONT_START_TIMER )
+ , m_nIdPool (0 )
+ , m_lListener (m_aLock.getShareableOslMutex() )
+ , m_nDocCacheLock (0 )
+ , m_nMinSpaceDocSave (MIN_DISCSPACE_DOCSAVE )
+ , m_nMinSpaceConfigSave (MIN_DISCSPACE_CONFIGSAVE )
+
+ #if OSL_DEBUG_LEVEL > 1
+ , m_dbg_bMakeItFaster (sal_False )
+ #endif
+{
+}
+
+//-----------------------------------------------
+AutoRecovery::~AutoRecovery()
+{
+ implts_stopTimer();
+}
+
+//-----------------------------------------------
+void SAL_CALL AutoRecovery::dispatch(const css::util::URL& aURL ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
+ throw(css::uno::RuntimeException)
+{
+ LOG_RECOVERY("AutoRecovery::dispatch() starts ...")
+ LOG_RECOVERY(U2B(aURL.Complete).getStr())
+
+ // valid request ?
+ sal_Int32 eNewJob = AutoRecovery::implst_classifyJob(aURL);
+ if (eNewJob == AutoRecovery::E_NO_JOB)
+ return;
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // still running operation ... ignoring AUTO_SAVE.
+ // All other requests has higher prio!
+ if (
+ ( m_eJob != AutoRecovery::E_NO_JOB ) &&
+ ((m_eJob & AutoRecovery::E_AUTO_SAVE ) != AutoRecovery::E_AUTO_SAVE)
+ )
+ {
+ LOG_WARNING("AutoRecovery::dispatch()", "There is already an asynchronous dispatch() running. New request will be ignored!")
+ return;
+ }
+
+ ::comphelper::SequenceAsHashMap lArgs(lArguments);
+
+ // check if somewhere wish to disable recovery temp. for this office session
+ // This can be done immediatly ... must not been done asynchronous.
+ if ((eNewJob & AutoRecovery::E_DISABLE_AUTORECOVERY) == AutoRecovery::E_DISABLE_AUTORECOVERY)
+ {
+ // it's important to set a flag internaly, so AutoRecovery will be supressed - even if it's requested.
+ m_eJob |= eNewJob;
+ implts_stopTimer();
+ implts_stopListening();
+ return;
+ }
+
+ // disable/enable AutoSave for this office session only
+ // independend from the configuration entry.
+ if ((eNewJob & AutoRecovery::E_SET_AUTOSAVE_STATE) == AutoRecovery::E_SET_AUTOSAVE_STATE)
+ {
+ sal_Bool bOn = lArgs.getUnpackedValueOrDefault(PROP_AUTOSAVE_STATE, (sal_Bool)sal_True);
+ if (bOn)
+ {
+ // dont enable AutoSave hardly !
+ // reload configuration to know the current state.
+ implts_readAutoSaveConfig();
+ implts_updateTimer();
+ // can it happen that might be the listener was stopped ? .-)
+ // make sure it runs always ... even if AutoSave itself was disabled temporarly.
+ implts_startListening();
+ }
+ else
+ {
+ implts_stopTimer();
+ m_eJob &= ~AutoRecovery::E_AUTO_SAVE;
+ m_eTimerType = AutoRecovery::E_DONT_START_TIMER;
+ }
+ return;
+ }
+
+ m_eJob |= eNewJob;
+
+ sal_Bool bAsync = lArgs.getUnpackedValueOrDefault(PROP_DISPATCH_ASYNCHRON, (sal_Bool)sal_False);
+ DispatchParams aParams (lArgs, static_cast< css::frame::XDispatch* >(this));
+
+ // Hold this instance alive till the asynchronous operation will be finished.
+ if (bAsync)
+ m_aDispatchParams = aParams;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (bAsync)
+ m_aAsyncDispatcher.Post(0);
+ else
+ implts_dispatch(aParams);
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_dispatch(const DispatchParams& aParams)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ sal_Int32 eJob = m_eJob;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // in case a new dispatch overwrites a may ba active AutoSave session
+ // we must restore this session later. see below ...
+ sal_Bool bWasAutoSaveActive = ((eJob & AutoRecovery::E_AUTO_SAVE) == AutoRecovery::E_AUTO_SAVE);
+
+ // On the other side it make no sense to reactivate the AutoSave operation
+ // if the new dispatch indicates a final decision ...
+ // E.g. an EmergencySave/SessionSave indicates the end of life of the current office session.
+ // It make no sense to reactivate an AutoSave then.
+ // But a Recovery or SessionRestore should reactivate a may be already active AutoSave.
+ sal_Bool bAllowAutoSaveReactivation = sal_True;
+
+ implts_stopTimer();
+ implts_stopListening();
+
+ implts_informListener(eJob,
+ AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_START, NULL));
+
+ try
+ {
+ // Auto save is called from our internal timer ... not via dispatch() API !
+ // else
+ if (
+ ((eJob & AutoRecovery::E_PREPARE_EMERGENCY_SAVE) == AutoRecovery::E_PREPARE_EMERGENCY_SAVE) &&
+ ((eJob & AutoRecovery::E_DISABLE_AUTORECOVERY ) != AutoRecovery::E_DISABLE_AUTORECOVERY )
+ )
+ {
+ LOG_RECOVERY("... prepare emergency save ...")
+ bAllowAutoSaveReactivation = sal_False;
+ implts_prepareEmergencySave();
+ }
+ else
+ if (
+ ((eJob & AutoRecovery::E_EMERGENCY_SAVE ) == AutoRecovery::E_EMERGENCY_SAVE ) &&
+ ((eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) != AutoRecovery::E_DISABLE_AUTORECOVERY)
+ )
+ {
+ LOG_RECOVERY("... do emergency save ...")
+ bAllowAutoSaveReactivation = sal_False;
+ implts_doEmergencySave(aParams);
+ }
+ else
+ if (
+ ((eJob & AutoRecovery::E_RECOVERY ) == AutoRecovery::E_RECOVERY ) &&
+ ((eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) != AutoRecovery::E_DISABLE_AUTORECOVERY)
+ )
+ {
+ LOG_RECOVERY("... do recovery ...")
+ implts_doRecovery(aParams);
+ }
+ else
+ if (
+ ((eJob & AutoRecovery::E_SESSION_SAVE ) == AutoRecovery::E_SESSION_SAVE ) &&
+ ((eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) != AutoRecovery::E_DISABLE_AUTORECOVERY)
+ )
+ {
+ LOG_RECOVERY("... do session save ...")
+ bAllowAutoSaveReactivation = sal_False;
+ implts_doSessionSave(aParams);
+ }
+ else
+ if (
+ ((eJob & AutoRecovery::E_SESSION_QUIET_QUIT ) == AutoRecovery::E_SESSION_QUIET_QUIT ) &&
+ ((eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) != AutoRecovery::E_DISABLE_AUTORECOVERY)
+ )
+ {
+ LOG_RECOVERY("... do session quiet quit ...")
+ bAllowAutoSaveReactivation = sal_False;
+ implts_doSessionQuietQuit(aParams);
+ }
+ else
+ if (
+ ((eJob & AutoRecovery::E_SESSION_RESTORE ) == AutoRecovery::E_SESSION_RESTORE ) &&
+ ((eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) != AutoRecovery::E_DISABLE_AUTORECOVERY)
+ )
+ {
+ LOG_RECOVERY("... do session restore ...")
+ implts_doSessionRestore(aParams);
+ }
+ else
+ if (
+ ((eJob & AutoRecovery::E_ENTRY_BACKUP ) == AutoRecovery::E_ENTRY_BACKUP ) &&
+ ((eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) != AutoRecovery::E_DISABLE_AUTORECOVERY)
+ )
+ implts_backupWorkingEntry(aParams);
+ else
+ if (
+ ((eJob & AutoRecovery::E_ENTRY_CLEANUP ) == AutoRecovery::E_ENTRY_CLEANUP ) &&
+ ((eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) != AutoRecovery::E_DISABLE_AUTORECOVERY)
+ )
+ implts_cleanUpWorkingEntry(aParams);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {} // TODO better error handling
+
+ implts_informListener(eJob,
+ AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_STOP, NULL));
+
+ // SAFE -> ----------------------------------
+ aWriteLock.lock();
+ m_eJob = E_NO_JOB;
+ if (
+ (bAllowAutoSaveReactivation) &&
+ (bWasAutoSaveActive )
+ )
+ {
+ m_eJob |= AutoRecovery::E_AUTO_SAVE;
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // depends on bAllowAutoSaveReactivation implicitly by looking on m_eJob=E_AUTO_SAVE! see before ...
+ implts_updateTimer();
+
+ if (bAllowAutoSaveReactivation)
+ implts_startListening();
+}
+
+//-----------------------------------------------
+void SAL_CALL AutoRecovery::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
+ const css::util::URL& aURL )
+ throw(css::uno::RuntimeException)
+{
+ if (!xListener.is())
+ throw css::uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid listener reference.")), static_cast< css::frame::XDispatch* >(this));
+ // container is threadsafe by using a shared mutex!
+ m_lListener.addInterface(aURL.Complete, xListener);
+
+ // REENTRANT !? -> --------------------------------
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ // THREAD SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ AutoRecovery::TDocumentList::iterator pIt;
+ for( pIt = m_lDocCache.begin();
+ pIt != m_lDocCache.end() ;
+ ++pIt )
+ {
+ AutoRecovery::TDocumentInfo& rInfo = *pIt;
+ css::frame::FeatureStateEvent aEvent = AutoRecovery::implst_createFeatureStateEvent(m_eJob, OPERATION_UPDATE, &rInfo);
+
+ // <- SAFE ------------------------------
+ aReadLock.unlock();
+ xListener->statusChanged(aEvent);
+ aReadLock.lock();
+ // SAFE -> ------------------------------
+ }
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void SAL_CALL AutoRecovery::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
+ const css::util::URL& aURL )
+ throw(css::uno::RuntimeException)
+{
+ if (!xListener.is())
+ throw css::uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid listener reference.")), static_cast< css::frame::XDispatch* >(this));
+ // container is threadsafe by using a shared mutex!
+ m_lListener.removeInterface(aURL.Complete, xListener);
+}
+
+//-----------------------------------------------
+void SAL_CALL AutoRecovery::notifyEvent(const css::document::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Reference< css::frame::XModel > xDocument(aEvent.Source, css::uno::UNO_QUERY);
+
+ // new document => put it into the internal list
+ if (
+ (aEvent.EventName.equals(EVENT_ON_NEW )) ||
+ (aEvent.EventName.equals(EVENT_ON_LOAD))
+ )
+ {
+ implts_registerDocument(xDocument);
+ }
+ // document modified => set its modify state new (means modified against the original file!)
+ else
+ if (aEvent.EventName.equals(EVENT_ON_MODIFYCHANGED))
+ {
+ implts_updateModifiedState(xDocument);
+ }
+ /* at least one document starts saving process =>
+ Our application code isnt ready for multiple save requests
+ at the same time. So we have to supress our AutoSave feature
+ for the moment, till this other save requests will be finished.
+ */
+ else
+ if (
+ (aEvent.EventName.equals(EVENT_ON_SAVE )) ||
+ (aEvent.EventName.equals(EVENT_ON_SAVEAS)) ||
+ (aEvent.EventName.equals(EVENT_ON_SAVETO))
+ )
+ {
+ implts_updateDocumentUsedForSavingState(xDocument, SAVE_IN_PROGRESS);
+ }
+ // document saved => remove tmp. files - but hold config entries alive!
+ else
+ if (
+ (aEvent.EventName.equals(EVENT_ON_SAVEDONE )) ||
+ (aEvent.EventName.equals(EVENT_ON_SAVEASDONE))
+ )
+ {
+ implts_markDocumentAsSaved(xDocument);
+ implts_updateDocumentUsedForSavingState(xDocument, SAVE_FINISHED);
+ }
+ /* document saved as copy => mark it as "non used by concurrent save operation".
+ so we can try to create a backup copy if next time AutoSave is started too.
+ Dont remove temp. files or change the modified state of the document!
+ It was not realy saved to the original file ...
+ */
+ else
+ if (aEvent.EventName.equals(EVENT_ON_SAVETODONE))
+ {
+ implts_updateDocumentUsedForSavingState(xDocument, SAVE_FINISHED);
+ }
+ // If saving of a document failed by an error ... we have to save this document
+ // by ourself next time AutoSave or EmergencySave is triggered.
+ // But we can reset the state "used for other save requests". Otherwhise
+ // these documents will never be saved!
+ else
+ if (
+ (aEvent.EventName.equals(EVENT_ON_SAVEFAILED )) ||
+ (aEvent.EventName.equals(EVENT_ON_SAVEASFAILED)) ||
+ (aEvent.EventName.equals(EVENT_ON_SAVETOFAILED))
+ )
+ {
+ implts_updateDocumentUsedForSavingState(xDocument, SAVE_FINISHED);
+ }
+ // document closed => remove temp. files and configuration entries
+ else
+ if (aEvent.EventName.equals(EVENT_ON_UNLOAD))
+ {
+ implts_deregisterDocument(xDocument, sal_True); // sal_True => stop listening for disposing() !
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL AutoRecovery::changesOccurred(const css::util::ChangesEvent& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ const css::uno::Sequence< css::util::ElementChange > lChanges (aEvent.Changes);
+ const css::util::ElementChange* pChanges = lChanges.getConstArray();
+
+ sal_Int32 c = lChanges.getLength();
+ sal_Int32 i = 0;
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // Changes of the configuration must be ignored if AutoSave/Recovery was disabled for this
+ // office session. That can happen if e.g. the command line arguments "--norestore" or "--headless"
+ // was set.
+ if ((m_eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) == AutoRecovery::E_DISABLE_AUTORECOVERY)
+ return;
+
+ for (i=0; i<c; ++i)
+ {
+ ::rtl::OUString sPath;
+ pChanges[i].Accessor >>= sPath;
+
+ if (sPath.equals(CFG_ENTRY_AUTOSAVE_ENABLED))
+ {
+ sal_Bool bEnabled = sal_False;
+ if (pChanges[i].Element >>= bEnabled)
+ {
+ if (bEnabled)
+ {
+ m_eJob |= AutoRecovery::E_AUTO_SAVE;
+ m_eTimerType = AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL;
+ }
+ else
+ {
+ m_eJob &= ~AutoRecovery::E_AUTO_SAVE;
+ m_eTimerType = AutoRecovery::E_DONT_START_TIMER;
+ }
+ }
+ }
+ else
+ if (sPath.equals(CFG_ENTRY_AUTOSAVE_TIMEINTERVALL))
+ pChanges[i].Element >>= m_nAutoSaveTimeIntervall;
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // Note: This call stops the timer and starts it again.
+ // But it checks the different timer states internaly and
+ // may be supress the restart!
+ implts_updateTimer();
+}
+
+//-----------------------------------------------
+void SAL_CALL AutoRecovery::modified(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Reference< css::frame::XModel > xDocument(aEvent.Source, css::uno::UNO_QUERY);
+ if (! xDocument.is())
+ return;
+
+ implts_markDocumentModifiedAgainstLastBackup(xDocument);
+}
+
+//-----------------------------------------------
+void SAL_CALL AutoRecovery::disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (aEvent.Source == m_xNewDocBroadcaster)
+ {
+ m_xNewDocBroadcaster.clear();
+ return;
+ }
+
+ if (aEvent.Source == m_xRecoveryCFG)
+ {
+ m_xRecoveryCFG.clear();
+ return;
+ }
+
+ // dispose from one of our cached documents ?
+ // Normaly they should send a OnUnload message ...
+ // But some stacktraces shows another possible use case .-)
+ css::uno::Reference< css::frame::XModel > xDocument(aEvent.Source, css::uno::UNO_QUERY);
+ if (xDocument.is())
+ {
+ implts_deregisterDocument(xDocument, sal_False); // sal_False => dont call removeEventListener() .. because it's not needed here
+ return;
+ }
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::container::XNameAccess > AutoRecovery::implts_openConfig()
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_xRecoveryCFG.is())
+ return m_xRecoveryCFG;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // throws a RuntimeException if an error occure!
+ css::uno::Reference< css::container::XNameAccess > xCFG(
+ ::comphelper::ConfigurationHelper::openConfig(xSMGR, CFG_PACKAGE_RECOVERY, ::comphelper::ConfigurationHelper::E_STANDARD),
+ css::uno::UNO_QUERY);
+
+ sal_Int32 nMinSpaceDocSave = MIN_DISCSPACE_DOCSAVE;
+ sal_Int32 nMinSpaceConfigSave = MIN_DISCSPACE_CONFIGSAVE;
+
+ try
+ {
+ ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_AUTOSAVE,
+ CFG_ENTRY_MINSPACE_DOCSAVE,
+ ::comphelper::ConfigurationHelper::E_STANDARD) >>= nMinSpaceDocSave;
+
+ ::comphelper::ConfigurationHelper::readDirectKey(xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_AUTOSAVE,
+ CFG_ENTRY_MINSPACE_CONFIGSAVE,
+ ::comphelper::ConfigurationHelper::E_STANDARD) >>= nMinSpaceConfigSave;
+ }
+ catch(const css::uno::Exception&)
+ {
+ // These config keys are not sooooo important, that
+ // we are interested on errors here realy .-)
+ nMinSpaceDocSave = MIN_DISCSPACE_DOCSAVE;
+ nMinSpaceConfigSave = MIN_DISCSPACE_CONFIGSAVE;
+ }
+
+ // SAFE -> ----------------------------------
+ aWriteLock.lock();
+ m_xRecoveryCFG = xCFG;
+ m_nMinSpaceDocSave = nMinSpaceDocSave;
+ m_nMinSpaceConfigSave = nMinSpaceConfigSave;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return xCFG;
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_readAutoSaveConfig()
+{
+ css::uno::Reference< css::container::XHierarchicalNameAccess > xCommonRegistry(implts_openConfig(), css::uno::UNO_QUERY);
+
+ // AutoSave [bool]
+ sal_Bool bEnabled = sal_False;
+ xCommonRegistry->getByHierarchicalName(CFG_ENTRY_AUTOSAVE_ENABLED) >>= bEnabled;
+
+ // SAFE -> ------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ if (bEnabled)
+ {
+ m_eJob |= AutoRecovery::E_AUTO_SAVE;
+ m_eTimerType = AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL;
+ }
+ else
+ {
+ m_eJob &= ~AutoRecovery::E_AUTO_SAVE;
+ m_eTimerType = AutoRecovery::E_DONT_START_TIMER;
+ }
+ aWriteLock.unlock();
+ // <- SAFE ------------------------------
+
+ // AutoSaveTimeIntervall [int] in min
+ sal_Int32 nTimeIntervall = 15;
+ xCommonRegistry->getByHierarchicalName(CFG_ENTRY_AUTOSAVE_TIMEINTERVALL) >>= nTimeIntervall;
+
+ // SAFE -> ----------------------------------
+ aWriteLock.lock();
+ m_nAutoSaveTimeIntervall = nTimeIntervall;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_readConfig()
+{
+ implts_readAutoSaveConfig();
+
+ css::uno::Reference< css::container::XHierarchicalNameAccess > xCommonRegistry(implts_openConfig(), css::uno::UNO_QUERY);
+
+ // REENTRANT -> --------------------------------
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_ADD_REMOVE);
+
+ // THREADSAFE -> -------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ // reset current cache load cache
+ m_lDocCache.clear();
+ m_nIdPool = 0;
+ aWriteLock.unlock();
+ // <- THREADSAFE -------------------------------
+
+ aCacheLock.unlock();
+ // <- REENTRANT --------------------------------
+
+ css::uno::Any aValue;
+
+ // RecoveryList [set]
+ aValue = xCommonRegistry->getByHierarchicalName(CFG_ENTRY_RECOVERYLIST);
+ css::uno::Reference< css::container::XNameAccess > xList;
+ aValue >>= xList;
+ if (xList.is())
+ {
+ const css::uno::Sequence< ::rtl::OUString > lItems = xList->getElementNames();
+ const ::rtl::OUString* pItems = lItems.getConstArray();
+ sal_Int32 c = lItems.getLength();
+ sal_Int32 i = 0;
+
+ // REENTRANT -> --------------------------
+ aCacheLock.lock(LOCK_FOR_CACHE_ADD_REMOVE);
+
+ for (i=0; i<c; ++i)
+ {
+ css::uno::Reference< css::beans::XPropertySet > xItem;
+ xList->getByName(pItems[i]) >>= xItem;
+ if (!xItem.is())
+ continue;
+
+ AutoRecovery::TDocumentInfo aInfo;
+ aInfo.NewTempURL = ::rtl::OUString();
+ aInfo.Document = css::uno::Reference< css::frame::XModel >();
+ xItem->getPropertyValue(CFG_ENTRY_PROP_ORIGINALURL ) >>= aInfo.OrgURL ;
+ xItem->getPropertyValue(CFG_ENTRY_PROP_TEMPURL ) >>= aInfo.OldTempURL ;
+ xItem->getPropertyValue(CFG_ENTRY_PROP_TEMPLATEURL ) >>= aInfo.TemplateURL ;
+ xItem->getPropertyValue(CFG_ENTRY_PROP_FILTER ) >>= aInfo.RealFilter ;
+ xItem->getPropertyValue(CFG_ENTRY_PROP_DOCUMENTSTATE) >>= aInfo.DocumentState;
+ xItem->getPropertyValue(CFG_ENTRY_PROP_MODULE ) >>= aInfo.AppModule ;
+ xItem->getPropertyValue(CFG_ENTRY_PROP_TITLE ) >>= aInfo.Title ;
+ xItem->getPropertyValue(CFG_ENTRY_PROP_VIEWNAMES ) >>= aInfo.ViewNames ;
+ implts_specifyAppModuleAndFactory(aInfo);
+ implts_specifyDefaultFilterAndExtension(aInfo);
+
+ if (pItems[i].indexOf(RECOVERY_ITEM_BASE_IDENTIFIER)==0)
+ {
+ ::rtl::OUString sID = pItems[i].copy(RECOVERY_ITEM_BASE_IDENTIFIER.getLength());
+ aInfo.ID = sID.toInt32();
+ // SAFE -> ----------------------
+ aWriteLock.lock();
+ if (aInfo.ID > m_nIdPool)
+ {
+ m_nIdPool = aInfo.ID+1;
+ LOG_ASSERT(m_nIdPool>=0, "AutoRecovery::implts_readConfig()\nOverflow of IDPool detected!")
+ }
+ aWriteLock.unlock();
+ // <- SAFE ----------------------
+ }
+ #ifdef ENABLE_WARNINGS
+ else
+ LOG_WARNING("AutoRecovery::implts_readConfig()", "Who changed numbering of recovery items? Cache will be inconsistent then! I do not know, what will happen next time .-)")
+ #endif
+
+ // THREADSAFE -> --------------------------
+ aWriteLock.lock();
+ m_lDocCache.push_back(aInfo);
+ aWriteLock.unlock();
+ // <- THREADSAFE --------------------------
+ }
+
+ aCacheLock.unlock();
+ // <- REENTRANT --------------------------
+ }
+
+ implts_updateTimer();
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_specifyDefaultFilterAndExtension(AutoRecovery::TDocumentInfo& rInfo)
+{
+ if (!rInfo.AppModule.getLength())
+ {
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cant find out the default filter and its extension, if no application module is known!")),
+ static_cast< css::frame::XDispatch* >(this));
+ }
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ css::uno::Reference< css::container::XNameAccess> xCFG = m_xModuleCFG;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ try
+ {
+ if (! xCFG.is())
+ {
+ // open module config on demand and cache the update access
+ xCFG = css::uno::Reference< css::container::XNameAccess >(
+ ::comphelper::ConfigurationHelper::openConfig(xSMGR, CFG_PACKAGE_MODULES, ::comphelper::ConfigurationHelper::E_STANDARD),
+ css::uno::UNO_QUERY_THROW);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xModuleCFG = xCFG;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+ }
+
+ css::uno::Reference< css::container::XNameAccess > xModuleProps(
+ xCFG->getByName(rInfo.AppModule),
+ css::uno::UNO_QUERY_THROW);
+
+ xModuleProps->getByName(CFG_ENTRY_REALDEFAULTFILTER) >>= rInfo.DefaultFilter;
+
+ css::uno::Reference< css::container::XNameAccess > xFilterCFG(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::container::XNameAccess > xTypeCFG (xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY_THROW);
+
+ ::comphelper::SequenceAsHashMap lFilterProps (xFilterCFG->getByName(rInfo.DefaultFilter));
+ ::rtl::OUString sTypeRegistration = lFilterProps.getUnpackedValueOrDefault(FILTER_PROP_TYPE, ::rtl::OUString());
+ ::comphelper::SequenceAsHashMap lTypeProps (xTypeCFG->getByName(sTypeRegistration));
+ css::uno::Sequence< ::rtl::OUString > lExtensions = lTypeProps.getUnpackedValueOrDefault(TYPE_PROP_EXTENSIONS, css::uno::Sequence< ::rtl::OUString >());
+ if (lExtensions.getLength())
+ {
+ rInfo.Extension = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("."));
+ rInfo.Extension += lExtensions[0];
+ }
+ else
+ rInfo.Extension = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".unknown"));
+ }
+ catch(const css::uno::Exception&)
+ {
+ rInfo.DefaultFilter = ::rtl::OUString();
+ rInfo.Extension = ::rtl::OUString();
+ }
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_specifyAppModuleAndFactory(AutoRecovery::TDocumentInfo& rInfo)
+{
+ ENSURE_OR_THROW2(
+ rInfo.AppModule.getLength() || rInfo.Document.is(),
+ "Cant find out the application module nor its factory URL, if no application module (or a suitable) document is known!",
+ *this );
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::frame::XModuleManager > xManager (xSMGR->createInstance(SERVICENAME_MODULEMANAGER), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::container::XNameAccess > xModuleConfig(xManager , css::uno::UNO_QUERY_THROW);
+
+ if (!rInfo.AppModule.getLength())
+ rInfo.AppModule = xManager->identify(rInfo.Document);
+
+ ::comphelper::SequenceAsHashMap lModuleDescription(xModuleConfig->getByName(rInfo.AppModule));
+ lModuleDescription[CFG_ENTRY_PROP_EMPTYDOCUMENTURL] >>= rInfo.FactoryURL;
+ lModuleDescription[CFG_ENTRY_PROP_FACTORYSERVICE] >>= rInfo.FactoryService;
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_collectActiveViewNames( AutoRecovery::TDocumentInfo& i_rInfo )
+{
+ ENSURE_OR_THROW2( i_rInfo.Document.is(), "need at document, at the very least", *this );
+
+ i_rInfo.ViewNames.realloc(0);
+
+ // obtain list of controllers of this document
+ ::std::vector< ::rtl::OUString > aViewNames;
+ const Reference< XModel2 > xModel( i_rInfo.Document, UNO_QUERY );
+ if ( xModel.is() )
+ {
+ const Reference< XEnumeration > xEnumControllers( xModel->getControllers() );
+ while ( xEnumControllers->hasMoreElements() )
+ {
+ const Reference< XController2 > xController( xEnumControllers->nextElement(), UNO_QUERY );
+ ::rtl::OUString sViewName;
+ if ( xController.is() )
+ sViewName = xController->getViewControllerName();
+ OSL_ENSURE( sViewName.getLength(), "AutoRecovery::implts_collectActiveViewNames: (no XController2 ->) no view name -> no recovery of this view!" );
+
+ if ( sViewName.getLength() )
+ aViewNames.push_back( sViewName );
+ }
+ }
+ else
+ {
+ const Reference< XController2 > xController( xModel->getCurrentController(), UNO_QUERY );
+ ::rtl::OUString sViewName;
+ if ( xController.is() )
+ sViewName = xController->getViewControllerName();
+ OSL_ENSURE( sViewName.getLength(), "AutoRecovery::implts_collectActiveViewNames: (no XController2 ->) no view name -> no recovery of this view!" );
+
+ if ( sViewName.getLength() )
+ aViewNames.push_back( sViewName );
+ }
+
+ i_rInfo.ViewNames.realloc( aViewNames.size() );
+ ::std::copy( aViewNames.begin(), aViewNames.end(), i_rInfo.ViewNames.getArray() );
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_persistAllActiveViewNames()
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // This list will be filled with every document
+ AutoRecovery::TDocumentList::iterator pIt;
+ for ( pIt = m_lDocCache.begin();
+ pIt != m_lDocCache.end() ;
+ ++pIt )
+ {
+ implts_collectActiveViewNames( *pIt );
+ implts_flushConfigItem( *pIt );
+ }
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_flushConfigItem(const AutoRecovery::TDocumentInfo& rInfo, sal_Bool bRemoveIt)
+{
+ css::uno::Reference< css::container::XHierarchicalNameAccess > xCFG;
+
+ try
+ {
+ xCFG = css::uno::Reference< css::container::XHierarchicalNameAccess >(implts_openConfig(), css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::container::XNameAccess > xCheck;
+ xCFG->getByHierarchicalName(CFG_ENTRY_RECOVERYLIST) >>= xCheck;
+
+ css::uno::Reference< css::container::XNameContainer > xModify(xCheck, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::lang::XSingleServiceFactory > xCreate(xCheck, css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUStringBuffer sIDBuf;
+ sIDBuf.append(RECOVERY_ITEM_BASE_IDENTIFIER);
+ sIDBuf.append((sal_Int32)rInfo.ID);
+ ::rtl::OUString sID = sIDBuf.makeStringAndClear();
+
+ // remove
+ if (bRemoveIt)
+ {
+ // Catch NoSuchElementException.
+ // Its not a good idea inside multithreaded environments to call hasElement - removeElement.
+ // DO IT!
+ try
+ {
+ xModify->removeByName(sID);
+ }
+ catch(const css::container::NoSuchElementException&)
+ { return; }
+ }
+ else
+ {
+ // new/modify
+ css::uno::Reference< css::beans::XPropertySet > xSet;
+ sal_Bool bNew = (!xCheck->hasByName(sID));
+ if (bNew)
+ xSet = css::uno::Reference< css::beans::XPropertySet >(xCreate->createInstance(), css::uno::UNO_QUERY_THROW);
+ else
+ xCheck->getByName(sID) >>= xSet;
+
+ xSet->setPropertyValue(CFG_ENTRY_PROP_ORIGINALURL , css::uno::makeAny(rInfo.OrgURL ));
+ xSet->setPropertyValue(CFG_ENTRY_PROP_TEMPURL , css::uno::makeAny(rInfo.OldTempURL ));
+ xSet->setPropertyValue(CFG_ENTRY_PROP_TEMPLATEURL , css::uno::makeAny(rInfo.TemplateURL ));
+ xSet->setPropertyValue(CFG_ENTRY_PROP_FILTER , css::uno::makeAny(rInfo.RealFilter ));
+ xSet->setPropertyValue(CFG_ENTRY_PROP_DOCUMENTSTATE, css::uno::makeAny(rInfo.DocumentState));
+ xSet->setPropertyValue(CFG_ENTRY_PROP_MODULE , css::uno::makeAny(rInfo.AppModule ));
+ xSet->setPropertyValue(CFG_ENTRY_PROP_TITLE , css::uno::makeAny(rInfo.Title ));
+ xSet->setPropertyValue(CFG_ENTRY_PROP_VIEWNAMES , css::uno::makeAny(rInfo.ViewNames ));
+
+ if (bNew)
+ xModify->insertByName(sID, css::uno::makeAny(xSet));
+ }
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {} // ??? can it happen that a full disc let these set of operations fail too ???
+
+ sal_Int32 nRetry = RETRY_STORE_ON_FULL_DISC_FOREVER;
+ do
+ {
+ try
+ {
+ css::uno::Reference< css::util::XChangesBatch > xFlush(xCFG, css::uno::UNO_QUERY_THROW);
+ xFlush->commitChanges();
+
+ #ifdef TRIGGER_FULL_DISC_CHECK
+ throw css::uno::Exception();
+ #endif
+
+ nRetry = 0;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ // a) FULL DISC seams to be the problem behind => show error and retry it forever (e.g. retry=300)
+ // b) unknown problem (may be locking problem) => reset RETRY value to more usefull value(!) (e.g. retry=3)
+ // c) unknown problem (may be locking problem) + 1..2 repeating operations => throw the original exception to force generation of a stacktrace !
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ sal_Int32 nMinSpaceConfigSave = m_nMinSpaceConfigSave;
+ aReadLock.unlock();
+ // <- SAFE
+
+ if (! impl_enoughDiscSpace(nMinSpaceConfigSave))
+ AutoRecovery::impl_showFullDiscError();
+ else
+ if (nRetry > RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL)
+ nRetry = RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL;
+ else
+ if (nRetry <= GIVE_UP_RETRY)
+ throw ex; // force stacktrace to know if there exist might other reasons, why an AutoSave can fail !!!
+
+ --nRetry;
+ }
+ }
+ while(nRetry>0);
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_startListening()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ css::uno::Reference< css::util::XChangesNotifier > xCFG (m_xRecoveryCFG, css::uno::UNO_QUERY);
+ css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster = m_xNewDocBroadcaster;
+ sal_Bool bListenForDocEvents = m_bListenForDocEvents;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (
+ ( xCFG.is() ) &&
+ (! m_bListenForConfigChanges)
+ )
+ {
+ m_xRecoveryCFGListener = new WeakChangesListener(this);
+ xCFG->addChangesListener(m_xRecoveryCFGListener);
+ m_bListenForConfigChanges = sal_True;
+ }
+
+ if (!xBroadcaster.is())
+ {
+ xBroadcaster = css::uno::Reference< css::document::XEventBroadcaster >(xSMGR->createInstance(SERVICENAME_GLOBALEVENTBROADCASTER), css::uno::UNO_QUERY_THROW);
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xNewDocBroadcaster = xBroadcaster;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+ }
+
+ if (
+ ( xBroadcaster.is() ) &&
+ (! bListenForDocEvents)
+ )
+ {
+ m_xNewDocBroadcasterListener = new WeakDocumentEventListener(this);
+ xBroadcaster->addEventListener(m_xNewDocBroadcasterListener);
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ m_bListenForDocEvents = sal_True;
+ aWriteLock.unlock();
+ // <- SAFE
+ }
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_stopListening()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ // Attention: Dont reset our internal members here too.
+ // May be we must work with our configuration, but dont wish to be informed
+ // about changes any longer. Needed e.g. during EMERGENCY_SAVE!
+ css::uno::Reference< css::util::XChangesNotifier > xCFG (m_xRecoveryCFG , css::uno::UNO_QUERY);
+ css::uno::Reference< css::document::XEventBroadcaster > xGlobalEventBroadcaster(m_xNewDocBroadcaster, css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (
+ (xGlobalEventBroadcaster.is()) &&
+ (m_bListenForDocEvents )
+ )
+ {
+ xGlobalEventBroadcaster->removeEventListener(m_xNewDocBroadcasterListener);
+ m_bListenForDocEvents = sal_False;
+ }
+
+ if (
+ (xCFG.is() ) &&
+ (m_bListenForConfigChanges)
+ )
+ {
+ xCFG->removeChangesListener(m_xRecoveryCFGListener);
+ m_bListenForConfigChanges = sal_False;
+ }
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_startModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo)
+{
+ if (rInfo.ListenForModify)
+ return;
+
+ css::uno::Reference< css::util::XModifyBroadcaster > xBroadcaster(rInfo.Document, css::uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ {
+ css::uno::Reference< css::util::XModifyListener > xThis(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY);
+ xBroadcaster->addModifyListener(xThis);
+ rInfo.ListenForModify = sal_True;
+ }
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_stopModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo)
+{
+ if (! rInfo.ListenForModify)
+ return;
+
+ css::uno::Reference< css::util::XModifyBroadcaster > xBroadcaster(rInfo.Document, css::uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ {
+ css::uno::Reference< css::util::XModifyListener > xThis(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY);
+ xBroadcaster->removeModifyListener(xThis);
+ rInfo.ListenForModify = sal_False;
+ }
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_updateTimer()
+{
+ implts_stopTimer();
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (
+ (m_eJob == AutoRecovery::E_NO_JOB ) || // TODO may be superflous - E_DONT_START_TIMER should be used only
+ (m_eTimerType == AutoRecovery::E_DONT_START_TIMER)
+ )
+ return;
+
+ sal_uLong nMilliSeconds = 0;
+ if (m_eTimerType == AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL)
+ {
+ nMilliSeconds = (m_nAutoSaveTimeIntervall*60000); // [min] => 60.000 ms
+ #if OSL_DEBUG_LEVEL > 1
+ if (m_dbg_bMakeItFaster)
+ nMilliSeconds = m_nAutoSaveTimeIntervall; // [ms]
+ #endif
+ }
+ else
+ if (m_eTimerType == AutoRecovery::E_POLL_FOR_USER_IDLE)
+ {
+ nMilliSeconds = MIN_TIME_FOR_USER_IDLE;
+ #if OSL_DEBUG_LEVEL > 1
+ if (m_dbg_bMakeItFaster)
+ nMilliSeconds = 300; // let us some time, to finish this method .-)
+ #endif
+ }
+ else
+ if (m_eTimerType == AutoRecovery::E_POLL_TILL_AUTOSAVE_IS_ALLOWED)
+ nMilliSeconds = 300; // there is a minimum time frame, where the user can loose some key input data!
+
+ m_aTimer.SetTimeout(nMilliSeconds);
+ m_aTimer.Start();
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_stopTimer()
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (!m_aTimer.IsActive())
+ return;
+ m_aTimer.Stop();
+
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+IMPL_LINK(AutoRecovery, implts_timerExpired, void*, EMPTYARG)
+{
+ try
+ {
+ // This method is called by using a pointer to us.
+ // But we must be aware that we can be destroyed hardly
+ // if our uno reference will be gone!
+ // => Hold this object alive till this method finish its work.
+ css::uno::Reference< css::uno::XInterface > xSelfHold(static_cast< css::lang::XTypeProvider* >(this));
+
+ // Needed! Otherwise every reschedule request allow a new triggered timer event :-(
+ implts_stopTimer();
+
+ // The timer must be ignored if AutoSave/Recovery was disabled for this
+ // office session. That can happen if e.g. the command line arguments "--norestore" or "--headless"
+ // was set. But normaly the timer was disabled if recovery was disabled ...
+ // But so we are more "safe" .-)
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ if ((m_eJob & AutoRecovery::E_DISABLE_AUTORECOVERY) == AutoRecovery::E_DISABLE_AUTORECOVERY)
+ return 0;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // check some "states", where its not allowed (better: not a good idea) to
+ // start an AutoSave. (e.g. if the user makes drag & drop ...)
+ // Then we poll till this "disallowed" state is gone.
+ sal_Bool bAutoSaveNotAllowed = Application::IsUICaptured();
+ if (bAutoSaveNotAllowed)
+ {
+ // SAFE -> ------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_eTimerType = AutoRecovery::E_POLL_TILL_AUTOSAVE_IS_ALLOWED;
+ aWriteLock.unlock();
+ // <- SAFE ------------------------------
+ implts_updateTimer();
+ return 0;
+ }
+
+ // analyze timer type.
+ // If we poll for an user idle period, may be we must
+ // do nothing here and start the timer again.
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_eTimerType == AutoRecovery::E_POLL_FOR_USER_IDLE)
+ {
+ sal_Bool bUserIdle = (Application::GetLastInputInterval()>MIN_TIME_FOR_USER_IDLE);
+ if (!bUserIdle)
+ {
+ implts_updateTimer();
+ return 0;
+ }
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ implts_informListener(AutoRecovery::E_AUTO_SAVE,
+ AutoRecovery::implst_createFeatureStateEvent(AutoRecovery::E_AUTO_SAVE, OPERATION_START, NULL));
+
+ // force save of all currently open documents
+ // The called method returns an info, if and how this
+ // timer must be restarted.
+ sal_Bool bAllowUserIdleLoop = sal_True;
+ AutoRecovery::ETimerType eSuggestedTimer = implts_saveDocs(bAllowUserIdleLoop, sal_False);
+
+ // If timer isnt used for "short callbacks" (means polling
+ // for special states) ... reset the handle state of all
+ // cache items. Such handle state indicates, that a document
+ // was already saved during the THIS(!) AutoSave session.
+ // Of course NEXT AutoSave session must be started without
+ // any "handle" state ...
+ if (
+ (eSuggestedTimer == AutoRecovery::E_DONT_START_TIMER ) ||
+ (eSuggestedTimer == AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL)
+ )
+ {
+ implts_resetHandleStates(sal_False);
+ }
+
+ implts_informListener(AutoRecovery::E_AUTO_SAVE,
+ AutoRecovery::implst_createFeatureStateEvent(AutoRecovery::E_AUTO_SAVE, OPERATION_STOP, NULL));
+
+ // restart timer - because it was disabled before ...
+ // SAFE -> ----------------------------------
+ aWriteLock.lock();
+ m_eTimerType = eSuggestedTimer;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ implts_updateTimer();
+ }
+ catch(const css::uno::Exception&)
+ {
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------
+IMPL_LINK(AutoRecovery, implts_asyncDispatch, void*, EMPTYARG)
+{
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ DispatchParams aParams = m_aDispatchParams;
+ css::uno::Reference< css::uno::XInterface > xHoldRefForMethodAlive = aParams.m_xHoldRefForAsyncOpAlive;
+ m_aDispatchParams.forget(); // clears all members ... including the ref-hold object .-)
+ aWriteLock.unlock();
+ // <- SAFE
+
+ implts_dispatch(aParams);
+ return 0;
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_registerDocument(const css::uno::Reference< css::frame::XModel >& xDocument)
+{
+ // ignore corrupted events, where no document is given ... Runtime Error ?!
+ if (!xDocument.is())
+ return;
+
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ // notification for already existing document !
+ // Can happen if events came in asynchronous on recovery time.
+ // Then our cache was filled from the configuration ... but now we get some
+ // asynchronous events from the global event broadcaster. We must be sure that
+ // we dont add the same document more then once.
+ AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
+ if (pIt != m_lDocCache.end())
+ {
+ // Normaly nothing must be done for this "late" notification.
+ // But may be the modified state was changed inbetween.
+ // Check it ...
+ implts_updateModifiedState(xDocument);
+ return;
+ }
+
+ aCacheLock.unlock();
+
+ ::comphelper::MediaDescriptor lDescriptor(xDocument->getArgs());
+
+ // check if this document must be ignored for recovery !
+ // Some use cases dont wish support for AutoSave/Recovery ... as e.g. OLE-Server / ActiveX Control etcpp.
+ sal_Bool bNoAutoSave = lDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_NOAUTOSAVE(), (sal_Bool)(sal_False));
+ if (bNoAutoSave)
+ return;
+
+ // Check if doc is well known on the desktop. Otherwhise ignore it!
+ // Other frames mostly are used from external programs - e.g. the bean ...
+ css::uno::Reference< css::frame::XController > xController = xDocument->getCurrentController();
+ if (!xController.is())
+ return;
+
+ css::uno::Reference< css::frame::XFrame > xFrame = xController->getFrame();
+ css::uno::Reference< css::frame::XDesktop > xDesktop (xFrame->getCreator(), css::uno::UNO_QUERY);
+ if (!xDesktop.is())
+ return;
+
+ // if the document doesn't support the XDocumentRecovery interface, we're not interested in it.
+ Reference< XDocumentRecovery > xDocRecovery( xDocument, UNO_QUERY );
+ if ( !xDocRecovery.is() )
+ return;
+
+ // get all needed informations of this document
+ // We need it to update our cache or to locate already existing elements there!
+ AutoRecovery::TDocumentInfo aNew;
+ aNew.Document = xDocument;
+
+ // TODO replace getLocation() with getURL() ... its a workaround currently only!
+ css::uno::Reference< css::frame::XStorable > xDoc(aNew.Document, css::uno::UNO_QUERY_THROW);
+ aNew.OrgURL = xDoc->getLocation();
+
+ css::uno::Reference< css::frame::XTitle > xTitle(aNew.Document, css::uno::UNO_QUERY_THROW);
+ aNew.Title = xTitle->getTitle ();
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // classify the used application module, which is used by this document.
+ implts_specifyAppModuleAndFactory(aNew);
+
+ // Hack! Check for "illegal office documents" ... as e.g. the Basic IDE
+ // Its not realy a full featured office document. It doesnt provide an URL, any filter, a factory URL etcpp.
+ // TODO file bug to Basci IDE developers. They must remove the office document API from its service.
+ if (
+ (!aNew.OrgURL.getLength() ) &&
+ (!aNew.FactoryURL.getLength())
+ )
+ {
+ OSL_FAIL( "AutoRecovery::implts_registerDocument: this should not happen anymore!" );
+ // nowadays, the Basic IDE should already die on the "supports XDocumentRecovery" check. And no other known
+ // document type fits in here ...
+ return;
+ }
+
+ // By the way - get some information about the default format for saving!
+ // and save an information about the real used filter by this document.
+ // We save this document with DefaultFilter ... and load it with the RealFilter.
+ implts_specifyDefaultFilterAndExtension(aNew);
+ aNew.RealFilter = lDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME() , ::rtl::OUString());
+
+ // Further we must know, if this document base on a template.
+ // Then we must load it in a different way.
+ css::uno::Reference< css::document::XDocumentPropertiesSupplier > xSupplier(aNew.Document, css::uno::UNO_QUERY);
+ if (xSupplier.is()) // optional interface!
+ {
+ css::uno::Reference< css::document::XDocumentProperties > xDocProps(xSupplier->getDocumentProperties(), css::uno::UNO_QUERY_THROW);
+ aNew.TemplateURL = xDocProps->getTemplateURL();
+ }
+
+ css::uno::Reference< css::util::XModifiable > xModifyCheck(xDocument, css::uno::UNO_QUERY_THROW);
+ if (xModifyCheck->isModified())
+ {
+ aNew.DocumentState |= AutoRecovery::E_MODIFIED;
+ }
+
+ aCacheLock.lock(LOCK_FOR_CACHE_ADD_REMOVE);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // create a new cache entry ... this document isn't known.
+ ++m_nIdPool;
+ aNew.ID = m_nIdPool;
+ LOG_ASSERT(m_nIdPool>=0, "AutoRecovery::implts_registerDocument()\nOverflow of ID pool detected.")
+ m_lDocCache.push_back(aNew);
+
+ AutoRecovery::TDocumentList::iterator pIt1 = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
+ AutoRecovery::TDocumentInfo& rInfo = *pIt1;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ implts_flushConfigItem(rInfo);
+ implts_startModifyListeningOnDoc(rInfo);
+
+ aCacheLock.unlock();
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_deregisterDocument(const css::uno::Reference< css::frame::XModel >& xDocument ,
+ sal_Bool bStopListening)
+{
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // Attention: Dont leave SAFE section, if you work with pIt!
+ // Because it points directly into the m_lDocCache list ...
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
+ if (pIt == m_lDocCache.end())
+ return; // unknown document => not a runtime error! Because we register only a few documents. see registration ...
+
+ AutoRecovery::TDocumentInfo aInfo = *pIt;
+
+ aCacheLock.unlock();
+
+ // Sometimes we close documents by ourself.
+ // And these documents cant be deregistered.
+ // Otherwhise we loos our configuration data ... but need it !
+ // see SessionSave !
+ if (aInfo.IgnoreClosing)
+ return;
+
+ CacheLockGuard aCacheLock2(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_ADD_REMOVE);
+ pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
+ if (pIt != m_lDocCache.end())
+ m_lDocCache.erase(pIt);
+ pIt = m_lDocCache.end(); // otherwhise its not specified what pIt means!
+ aCacheLock2.unlock();
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ /* This method is called within disposing() of the document too. But there it's not a good idea to
+ deregister us as listener. Furter it make no sense - because the broadcaster dies.
+ So we supress deregistration in such case ...
+ */
+ if (bStopListening)
+ implts_stopModifyListeningOnDoc(aInfo);
+
+ AutoRecovery::st_impl_removeFile(aInfo.OldTempURL);
+ AutoRecovery::st_impl_removeFile(aInfo.NewTempURL);
+ implts_flushConfigItem(aInfo, sal_True); // sal_True => remove it from config
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_markDocumentModifiedAgainstLastBackup(const css::uno::Reference< css::frame::XModel >& xDocument)
+{
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
+ if (pIt != m_lDocCache.end())
+ {
+ AutoRecovery::TDocumentInfo& rInfo = *pIt;
+
+ /* Now we know, that this document was modified again and must be saved next time.
+ But we dont need this information for every e.g. key input of the user.
+ So we stop listening here.
+ But if the document was saved as temp. file we start listening for this event again.
+ */
+ implts_stopModifyListeningOnDoc(rInfo);
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_updateModifiedState(const css::uno::Reference< css::frame::XModel >& xDocument)
+{
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
+ if (pIt != m_lDocCache.end())
+ {
+ AutoRecovery::TDocumentInfo& rInfo = *pIt;
+
+ // use sal_True as fallback ... so we recognize every document on EmergencySave/AutoRecovery!
+ sal_Bool bModified = sal_True;
+ css::uno::Reference< css::util::XModifiable > xModify(xDocument, css::uno::UNO_QUERY);
+ if (xModify.is())
+ bModified = xModify->isModified();
+ if (bModified)
+ {
+ rInfo.DocumentState |= AutoRecovery::E_MODIFIED;
+ }
+ else
+ {
+ rInfo.DocumentState &= ~AutoRecovery::E_MODIFIED;
+ }
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_updateDocumentUsedForSavingState(const css::uno::Reference< css::frame::XModel >& xDocument ,
+ sal_Bool bSaveInProgress)
+{
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
+ if (pIt == m_lDocCache.end())
+ return;
+ AutoRecovery::TDocumentInfo& rInfo = *pIt;
+ rInfo.UsedForSaving = bSaveInProgress;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_markDocumentAsSaved(const css::uno::Reference< css::frame::XModel >& xDocument)
+{
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
+ if (pIt == m_lDocCache.end())
+ return;
+ AutoRecovery::TDocumentInfo& rInfo = *pIt;
+
+ rInfo.DocumentState = AutoRecovery::E_UNKNOWN;
+ // TODO replace getLocation() with getURL() ... its a workaround currently only!
+ css::uno::Reference< css::frame::XStorable > xDoc(rInfo.Document, css::uno::UNO_QUERY);
+ rInfo.OrgURL = xDoc->getLocation();
+
+ ::rtl::OUString sRemoveURL1 = rInfo.OldTempURL;
+ ::rtl::OUString sRemoveURL2 = rInfo.NewTempURL;
+ rInfo.OldTempURL = ::rtl::OUString();
+ rInfo.NewTempURL = ::rtl::OUString();
+
+ ::comphelper::MediaDescriptor lDescriptor(rInfo.Document->getArgs());
+ rInfo.RealFilter = lDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString());
+
+ css::uno::Reference< css::frame::XTitle > xDocTitle(xDocument, css::uno::UNO_QUERY);
+ if (xDocTitle.is ())
+ rInfo.Title = xDocTitle->getTitle ();
+ else
+ {
+ rInfo.Title = lDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TITLE() , ::rtl::OUString());
+ if (!rInfo.Title.getLength())
+ rInfo.Title = lDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_DOCUMENTTITLE(), ::rtl::OUString());
+ }
+
+ rInfo.UsedForSaving = sal_False;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ implts_flushConfigItem(rInfo);
+
+ aCacheLock.unlock();
+
+ AutoRecovery::st_impl_removeFile(sRemoveURL1);
+ AutoRecovery::st_impl_removeFile(sRemoveURL2);
+}
+
+//-----------------------------------------------
+AutoRecovery::TDocumentList::iterator AutoRecovery::impl_searchDocument( AutoRecovery::TDocumentList& rList ,
+ const css::uno::Reference< css::frame::XModel >& xDocument)
+{
+ AutoRecovery::TDocumentList::iterator pIt;
+ for ( pIt = rList.begin();
+ pIt != rList.end() ;
+ ++pIt )
+ {
+ const AutoRecovery::TDocumentInfo& rInfo = *pIt;
+ if (rInfo.Document == xDocument)
+ break;
+ }
+ return pIt;
+}
+
+//-----------------------------------------------
+namespace
+{
+ void lcl_changeVisibility( const css::uno::Reference< css::frame::XFramesSupplier >& i_rFrames, sal_Bool i_bVisible )
+ {
+ css::uno::Reference< css::container::XIndexAccess > xFramesContainer( i_rFrames->getFrames(), css::uno::UNO_QUERY );
+ const sal_Int32 count = xFramesContainer->getCount();
+
+ Any aElement;
+ for ( sal_Int32 i=0; i < count; ++i )
+ {
+ aElement = xFramesContainer->getByIndex(i);
+ // check for sub frames
+ css::uno::Reference< css::frame::XFramesSupplier > xFramesSupp( aElement, css::uno::UNO_QUERY );
+ if ( xFramesSupp.is() )
+ lcl_changeVisibility( xFramesSupp, i_bVisible );
+
+ css::uno::Reference< css::frame::XFrame > xFrame( aElement, css::uno::UNO_QUERY );
+ if ( !xFrame.is() )
+ continue;
+
+ css::uno::Reference< css::awt::XWindow > xWindow( xFrame->getContainerWindow(), UNO_SET_THROW );
+ xWindow->setVisible( i_bVisible );
+ }
+ }
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_changeAllDocVisibility(sal_Bool bVisible)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::frame::XFramesSupplier > xDesktop(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
+ lcl_changeVisibility( xDesktop, bVisible );
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+/* Currently the document is not closed in case of crash,
+ so the lock file must be removed explicitly
+*/
+void lc_removeLockFile(AutoRecovery::TDocumentInfo& rInfo)
+{
+ if ( rInfo.Document.is() )
+ {
+ try
+ {
+ css::uno::Reference< css::frame::XStorable > xStore(rInfo.Document, css::uno::UNO_QUERY_THROW);
+ ::rtl::OUString aURL = xStore->getLocation();
+ if ( aURL.getLength() )
+ {
+ ::svt::DocumentLockFile aLockFile( aURL );
+ aLockFile.RemoveFile();
+ }
+ }
+ catch( const css::uno::Exception& )
+ {}
+ }
+}
+
+
+//-----------------------------------------------
+void AutoRecovery::implts_prepareSessionShutdown()
+{
+ LOG_RECOVERY("AutoRecovery::implts_prepareSessionShutdown() starts ...")
+
+ // a) reset modified documents (of course the must be saved before this method is called!)
+ // b) close it without showing any UI!
+
+ // SAFE ->
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ AutoRecovery::TDocumentList::iterator pIt;
+ for ( pIt = m_lDocCache.begin();
+ pIt != m_lDocCache.end() ;
+ ++pIt )
+ {
+ AutoRecovery::TDocumentInfo& rInfo = *pIt;
+
+ // WORKAROUND... Since the documents are not closed the lock file must be removed explicitly
+ // it is not done on documents saving since shutdown can be cancelled
+ lc_removeLockFile( rInfo );
+
+ // Prevent us from deregistration of these documents.
+ // Because we close these documents by ourself (see XClosable below) ...
+ // it's fact, that we reach our deregistration method. There we
+ // must not(!) update our configuration ... Otherwhise all
+ // session data are lost !!!
+ rInfo.IgnoreClosing = sal_True;
+
+ // reset modified flag of these documents (ignoring the notification about it!)
+ // Otherwise a message box is shown on closing these models.
+ implts_stopModifyListeningOnDoc(rInfo);
+
+ // if the session save is still running the documents should not be thrown away,
+ // actually that would be a bad sign, that means that the SessionManager tryes
+ // to kill the session before the saving is ready
+ if ((m_eJob & AutoRecovery::E_SESSION_SAVE) != AutoRecovery::E_SESSION_SAVE)
+ {
+ css::uno::Reference< css::util::XModifiable > xModify(rInfo.Document, css::uno::UNO_QUERY);
+ if (xModify.is())
+ xModify->setModified(sal_False);
+
+ // close the model.
+ css::uno::Reference< css::util::XCloseable > xClose(rInfo.Document, css::uno::UNO_QUERY);
+ if (xClose.is())
+ {
+ try
+ {
+ xClose->close(sal_False);
+ }
+ /*
+ catch(const css::lang::DisposedException&)
+ {
+ // closed ... disposed ... always the same .-)
+ }
+ */
+ catch(const css::uno::Exception&)
+ {
+ // At least it's only a try to close these documents before anybody else it does.
+ // So it seams to be possible to ignore any error here .-)
+ }
+
+ rInfo.Document.clear();
+ }
+ }
+ }
+
+ aCacheLock.unlock();
+ // <- SAFE
+}
+
+//-----------------------------------------------
+/* TODO WORKAROUND:
+
+ #i64599#
+
+ Normaly the MediaDescriptor argument NoAutoSave indicates,
+ that a document must be ignored for AutoSave and Recovery.
+ But sometimes XModel->getArgs() does not contained this information
+ if implts_registerDocument() was called.
+ So we have to check a second time, if this property is set ....
+ Best place doing so is to check it immeditaly before saving
+ and supressingd saving the document then.
+ Of course removing the corresponding cache entry isnt an option.
+ Because it would disturb iteration over the cache !
+ So we ignore such documents only ...
+ Hopefully next time they are not inserted in our cache.
+*/
+sal_Bool lc_checkIfSaveForbiddenByArguments(AutoRecovery::TDocumentInfo& rInfo)
+{
+ if (! rInfo.Document.is())
+ return sal_True;
+
+ ::comphelper::MediaDescriptor lDescriptor(rInfo.Document->getArgs());
+ sal_Bool bNoAutoSave = lDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_NOAUTOSAVE(), (sal_Bool)(sal_False));
+
+ return bNoAutoSave;
+}
+
+//-----------------------------------------------
+AutoRecovery::ETimerType AutoRecovery::implts_saveDocs( sal_Bool bAllowUserIdleLoop,
+ sal_Bool bRemoveLockFiles,
+ const DispatchParams* pParams )
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::task::XStatusIndicator > xExternalProgress;
+ if (pParams)
+ xExternalProgress = pParams->m_xProgress;
+
+ css::uno::Reference< css::frame::XFramesSupplier > xDesktop (xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
+ ::rtl::OUString sBackupPath (SvtPathOptions().GetBackupPath());
+
+ css::uno::Reference< css::frame::XController > xActiveController;
+ css::uno::Reference< css::frame::XModel > xActiveModel ;
+ css::uno::Reference< css::frame::XFrame > xActiveFrame = xDesktop->getActiveFrame();
+ if (xActiveFrame.is())
+ xActiveController = xActiveFrame->getController();
+ if (xActiveController.is())
+ xActiveModel = xActiveController->getModel();
+
+ // Set the default timer action for our calli.
+ // Default = NORMAL_AUTOSAVE
+ // We return a suggestion for an active timer only.
+ // It will be ignored if the timer was disabled by the user ...
+ // Further this state can be set to USER_IDLE only later in this method.
+ // Its not allowed to reset such state then. Because we must know, if
+ // there exists POSTPONED documents. see below ...
+ AutoRecovery::ETimerType eTimer = AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL;
+
+ sal_Int32 eJob = m_eJob;
+
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ // This list will be filled with every document
+ // which should be saved as last one. E.g. if it was used
+ // already for an UI save operation => crashed ... and
+ // now we try to save it again ... which can fail again ( of course .-) ).
+ ::std::vector< AutoRecovery::TDocumentList::iterator > lDangerousDocs;
+
+ AutoRecovery::TDocumentList::iterator pIt;
+ for ( pIt = m_lDocCache.begin();
+ pIt != m_lDocCache.end() ;
+ ++pIt )
+ {
+ AutoRecovery::TDocumentInfo aInfo = *pIt;
+
+ // WORKAROUND... Since the documents are not closed the lock file must be removed explicitly
+ if ( bRemoveLockFiles )
+ lc_removeLockFile( aInfo );
+
+ // WORKAROUND ... see comment of this method
+ if (lc_checkIfSaveForbiddenByArguments(aInfo))
+ continue;
+
+ // already auto saved during this session :-)
+ // This state must be reset for all documents
+ // if timer is started with normnal AutoSaveTimerIntervall!
+ if ((aInfo.DocumentState & AutoRecovery::E_HANDLED) == AutoRecovery::E_HANDLED)
+ continue;
+
+ // Not modified documents are not saved.
+ // We safe an information about the URL only!
+ Reference< XDocumentRecovery > xDocRecover( aInfo.Document, UNO_QUERY_THROW );
+ if ( !xDocRecover->wasModifiedSinceLastSave() )
+ {
+ aInfo.DocumentState |= AutoRecovery::E_HANDLED;
+ continue;
+ }
+
+ // check if this document is still used by a concurrent save operation
+ // e.g. if the user tried to save via UI.
+ // Handle it in the following way:
+ // i) For an AutoSave ... ignore this document! It will be saved and next time we will (hopefully)
+ // get a notification about the state of this operation.
+ // And if a document was saved by the user we can remove our temp. file. But that will be done inside
+ // our callback for SaveDone notification.
+ // ii) For a CrashSave ... add it to the list of dangerous documents and
+ // save it after all other documents was saved successfully. That decrease
+ // the chance for a crash inside a crash.
+ // On the other side it's not neccessary for documents, which are not modified.
+ // They can be handled normaly - means we patch the corresponding configuration entry only.
+ // iii) For a SessionSave ... ignore it! There is no time to wait for this save operation.
+ // Because the WindowManager will kill the process if it doesnt react immediatly.
+ // On the other side we cant risk a concurrent save request ... because we know
+ // that it will produce a crash.
+
+ // Attention: Because eJob is used as a flag field, you have to check for the worst case first.
+ // E.g. a CrashSave can overwrite an AutoSave. So you have to check for a CrashSave before an AutoSave!
+ if (aInfo.UsedForSaving)
+ {
+ if ((eJob & AutoRecovery::E_EMERGENCY_SAVE) == AutoRecovery::E_EMERGENCY_SAVE)
+ {
+ lDangerousDocs.push_back(pIt);
+ continue;
+ }
+ else
+ if ((eJob & AutoRecovery::E_SESSION_SAVE) == AutoRecovery::E_SESSION_SAVE)
+ {
+ continue;
+ }
+ else
+ if ((eJob & AutoRecovery::E_AUTO_SAVE) == AutoRecovery::E_AUTO_SAVE)
+ {
+ eTimer = AutoRecovery::E_POLL_TILL_AUTOSAVE_IS_ALLOWED;
+ aInfo.DocumentState |= AutoRecovery::E_POSTPONED;
+ continue;
+ }
+ }
+
+ // a) Document was not postponed - and is active now. => postpone it (restart timer, restart loop)
+ // b) Document was not postponed - and is not active now. => save it
+ // c) Document was postponed - and is not active now. => save it
+ // d) Document was postponed - and is active now. => save it (because user idle was checked already)
+ sal_Bool bActive = (xActiveModel == aInfo.Document);
+ sal_Bool bWasPostponed = ((aInfo.DocumentState & AutoRecovery::E_POSTPONED) == AutoRecovery::E_POSTPONED);
+
+ if (
+ ! bWasPostponed &&
+ bActive
+ )
+ {
+ aInfo.DocumentState |= AutoRecovery::E_POSTPONED;
+ *pIt = aInfo;
+ // postponed documents will be saved if this method is called again!
+ // That can be done by an outside started timer => E_POLL_FOR_USER_IDLE (if normal AutoSave is active)
+ // or it must be done directly without starting any timer => E_CALL_ME_BACK (if Emergency- or SessionSave is active and must be finished ASAP!)
+ eTimer = AutoRecovery::E_POLL_FOR_USER_IDLE;
+ if (!bAllowUserIdleLoop)
+ eTimer = AutoRecovery::E_CALL_ME_BACK;
+ continue;
+ }
+
+ // b, c, d)
+ // <- SAFE --------------------------
+ aWriteLock.unlock();
+ // changing of aInfo and flushing it is done inside implts_saveOneDoc!
+ implts_saveOneDoc(sBackupPath, aInfo, xExternalProgress);
+ implts_informListener(eJob, AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &aInfo));
+ aWriteLock.lock();
+ // SAFE -> --------------------------
+
+ *pIt = aInfo;
+ }
+
+ // Did we have some "dangerous candidates" ?
+ // Try to save it ... but may be it will fail !
+ ::std::vector< AutoRecovery::TDocumentList::iterator >::iterator pIt2;
+ for ( pIt2 = lDangerousDocs.begin();
+ pIt2 != lDangerousDocs.end() ;
+ ++pIt2 )
+ {
+ pIt = *pIt2;
+ AutoRecovery::TDocumentInfo aInfo = *pIt;
+
+ // <- SAFE --------------------------
+ aWriteLock.unlock();
+ // changing of aInfo and flushing it is done inside implts_saveOneDoc!
+ implts_saveOneDoc(sBackupPath, aInfo, xExternalProgress);
+ implts_informListener(eJob, AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &aInfo));
+ aWriteLock.lock();
+ // SAFE -> --------------------------
+
+ *pIt = aInfo;
+ }
+
+ return eTimer;
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_saveOneDoc(const ::rtl::OUString& sBackupPath ,
+ AutoRecovery::TDocumentInfo& rInfo ,
+ const css::uno::Reference< css::task::XStatusIndicator >& xExternalProgress)
+{
+ // no document? => can occure if we loaded our configuration with files,
+ // which couldnt be recovered successfully. In such case we have all needed informations
+ // excepting the real document instance!
+
+ // TODO: search right place, where such "dead files" can be removed from the configuration!
+ if (!rInfo.Document.is())
+ return;
+
+ ::comphelper::MediaDescriptor lOldArgs(rInfo.Document->getArgs());
+ implts_generateNewTempURL(sBackupPath, lOldArgs, rInfo);
+
+ // if the document was loaded with a password, it should be
+ // stored with password
+ ::comphelper::MediaDescriptor lNewArgs;
+ ::rtl::OUString sPassword = lOldArgs.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PASSWORD(), ::rtl::OUString());
+ if (sPassword.getLength())
+ lNewArgs[::comphelper::MediaDescriptor::PROP_PASSWORD()] <<= sPassword;
+
+ // Further it must be saved using the default file format of that application.
+ // Otherwhise we will some data lost.
+ if (rInfo.DefaultFilter.getLength())
+ lNewArgs[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= rInfo.DefaultFilter;
+
+ // prepare frame/document/mediadescriptor in a way, that it uses OUR progress .-)
+ if (xExternalProgress.is())
+ lNewArgs[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xExternalProgress;
+ impl_establishProgress(rInfo, lNewArgs, css::uno::Reference< css::frame::XFrame >());
+
+ // #i66598# use special handling of property "DocumentBaseURL" (it must be an empty string!)
+ // for make hyperlinks working
+ lNewArgs[::comphelper::MediaDescriptor::PROP_DOCUMENTBASEURL()] <<= ::rtl::OUString();
+
+ // try to save this document as a new temp file everytimes.
+ // Mark AutoSave state as "INCOMPLETE" if it failed.
+ // Because the last temp file is to old and does not include all changes.
+ Reference< XDocumentRecovery > xDocRecover(rInfo.Document, css::uno::UNO_QUERY_THROW);
+
+ // safe the state about "trying to save"
+ // ... we need it for recovery if e.g. a crash occures inside next line!
+ rInfo.DocumentState |= AutoRecovery::E_TRY_SAVE;
+ implts_flushConfigItem(rInfo);
+
+ sal_Int32 nRetry = RETRY_STORE_ON_FULL_DISC_FOREVER;
+ sal_Bool bError = sal_False;
+ do
+ {
+ try
+ {
+ xDocRecover->storeToRecoveryFile( rInfo.NewTempURL, lNewArgs.getAsConstPropertyValueList() );
+
+ #ifdef TRIGGER_FULL_DISC_CHECK
+ throw css::uno::Exception();
+ #endif
+
+ bError = sal_False;
+ nRetry = 0;
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ bError = sal_True;
+
+ // a) FULL DISC seams to be the problem behind => show error and retry it forever (e.g. retry=300)
+ // b) unknown problem (may be locking problem) => reset RETRY value to more usefull value(!) (e.g. retry=3)
+ // c) unknown problem (may be locking problem) + 1..2 repeating operations => throw the original exception to force generation of a stacktrace !
+
+ // SAFE ->
+ ReadGuard aReadLock2(m_aLock);
+ sal_Int32 nMinSpaceDocSave = m_nMinSpaceDocSave;
+ aReadLock2.unlock();
+ // <- SAFE
+
+ if (! impl_enoughDiscSpace(nMinSpaceDocSave))
+ AutoRecovery::impl_showFullDiscError();
+ else
+ if (nRetry > RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL)
+ nRetry = RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL;
+ else
+ if (nRetry <= GIVE_UP_RETRY)
+ throw ex; // force stacktrace to know if there exist might other reasons, why an AutoSave can fail !!!
+
+ --nRetry;
+ }
+ }
+ while(nRetry>0);
+
+ if (! bError)
+ {
+ // safe the state about success
+ // ... you know the reason: to know it on recovery time if next line crash .-)
+ rInfo.DocumentState &= ~AutoRecovery::E_TRY_SAVE;
+ rInfo.DocumentState |= AutoRecovery::E_HANDLED;
+ rInfo.DocumentState |= AutoRecovery::E_SUCCEDED;
+ }
+ else
+ {
+ // safe the state about error ...
+ rInfo.NewTempURL = ::rtl::OUString();
+ rInfo.DocumentState &= ~AutoRecovery::E_TRY_SAVE;
+ rInfo.DocumentState |= AutoRecovery::E_HANDLED;
+ rInfo.DocumentState |= AutoRecovery::E_INCOMPLETE;
+ }
+
+ // make sure the progress isnt referred any longer
+ impl_forgetProgress(rInfo, lNewArgs, css::uno::Reference< css::frame::XFrame >());
+
+ // try to remove the old temp file.
+ // Ignore any error here. We have a new temp file, which is up to date.
+ // The only thing is: we fill the disk with temp files, if we cant remove old ones :-)
+ ::rtl::OUString sRemoveFile = rInfo.OldTempURL;
+ rInfo.OldTempURL = rInfo.NewTempURL;
+ rInfo.NewTempURL = ::rtl::OUString();
+
+ implts_flushConfigItem(rInfo);
+
+ // We must know if the user modifies the document again ...
+ implts_startModifyListeningOnDoc(rInfo);
+
+ AutoRecovery::st_impl_removeFile(sRemoveFile);
+}
+
+//-----------------------------------------------
+AutoRecovery::ETimerType AutoRecovery::implts_openDocs(const DispatchParams& aParams)
+{
+ AutoRecovery::ETimerType eTimer = AutoRecovery::E_DONT_START_TIMER;
+
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ sal_Int32 eJob = m_eJob;
+ AutoRecovery::TDocumentList::iterator pIt;
+ for ( pIt = m_lDocCache.begin();
+ pIt != m_lDocCache.end() ;
+ ++pIt )
+ {
+ AutoRecovery::TDocumentInfo& rInfo = *pIt;
+
+ // Such documents are already loaded by the last loop.
+ // Dont check E_SUCCEDED here! Its may be the final state of an AutoSave
+ // operation before!!!
+ if ((rInfo.DocumentState & AutoRecovery::E_HANDLED) == AutoRecovery::E_HANDLED)
+ continue;
+
+ // a1,b1,c1,d2,e2,f2)
+ if ((rInfo.DocumentState & AutoRecovery::E_DAMAGED) == AutoRecovery::E_DAMAGED)
+ {
+ // dont forget to inform listener! May be this document was
+ // damaged on last saving time ...
+ // Then our listener need this notification.
+ // If it was damaged during last "try to open" ...
+ // it will be notified more then once. SH.. HAPPENS ...
+ // <- SAFE --------------------------
+ aWriteLock.unlock();
+ implts_informListener(eJob,
+ AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &rInfo));
+ aWriteLock.lock();
+ // SAFE -> --------------------------
+ continue;
+ }
+
+ ::comphelper::MediaDescriptor lDescriptor;
+
+ // its an UI feature - so the "USER" itself must be set as referer
+ lDescriptor[::comphelper::MediaDescriptor::PROP_REFERRER()] <<= REFERRER_USER;
+ lDescriptor[::comphelper::MediaDescriptor::PROP_SALVAGEDFILE()] <<= ::rtl::OUString();
+
+ // recovered documents are loaded hidden, and shown all at once, later
+ lDescriptor[::comphelper::MediaDescriptor::PROP_HIDDEN()] <<= true;
+
+ if (aParams.m_xProgress.is())
+ lDescriptor[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= aParams.m_xProgress;
+
+ sal_Bool bBackupWasTried = (
+ ((rInfo.DocumentState & AutoRecovery::E_TRY_LOAD_BACKUP ) == AutoRecovery::E_TRY_LOAD_BACKUP) || // temp. state!
+ ((rInfo.DocumentState & AutoRecovery::E_INCOMPLETE ) == AutoRecovery::E_INCOMPLETE ) // transport TRY_LOAD_BACKUP from last loop to this new one!
+ );
+ sal_Bool bOriginalWasTried = ((rInfo.DocumentState & AutoRecovery::E_TRY_LOAD_ORIGINAL) == AutoRecovery::E_TRY_LOAD_ORIGINAL);
+
+ if (bBackupWasTried)
+ {
+ if (!bOriginalWasTried)
+ {
+ rInfo.DocumentState |= AutoRecovery::E_INCOMPLETE;
+ // try original URL ... ! dont continue with next item here ...
+ }
+ else
+ {
+ rInfo.DocumentState |= AutoRecovery::E_DAMAGED;
+ continue;
+ }
+ }
+
+ ::rtl::OUString sLoadOriginalURL;
+ ::rtl::OUString sLoadBackupURL ;
+
+ if (!bBackupWasTried)
+ sLoadBackupURL = rInfo.OldTempURL;
+
+ if (rInfo.OrgURL.getLength())
+ {
+ sLoadOriginalURL = rInfo.OrgURL;
+ }
+ else
+ if (rInfo.TemplateURL.getLength())
+ {
+ sLoadOriginalURL = rInfo.TemplateURL;
+ lDescriptor[::comphelper::MediaDescriptor::PROP_ASTEMPLATE()] <<= sal_True;
+ lDescriptor[::comphelper::MediaDescriptor::PROP_TEMPLATENAME()] <<= rInfo.TemplateURL;
+ }
+ else
+ if (rInfo.FactoryURL.getLength())
+ {
+ sLoadOriginalURL = rInfo.FactoryURL;
+ lDescriptor[::comphelper::MediaDescriptor::PROP_ASTEMPLATE()] <<= sal_True;
+ }
+
+ // A "Salvaged" item must exists every time. The core can make something special then for recovery.
+ // Of course it should be the real file name of the original file, in case we load the temp. backup here.
+ ::rtl::OUString sURL;
+ if (sLoadBackupURL.getLength())
+ {
+ sURL = sLoadBackupURL;
+ rInfo.DocumentState |= AutoRecovery::E_TRY_LOAD_BACKUP;
+ lDescriptor[::comphelper::MediaDescriptor::PROP_SALVAGEDFILE()] <<= sLoadOriginalURL;
+ }
+ else
+ if (sLoadOriginalURL.getLength())
+ {
+ sURL = sLoadOriginalURL;
+ rInfo.DocumentState |= AutoRecovery::E_TRY_LOAD_ORIGINAL;
+ }
+ else
+ continue; // TODO ERROR!
+
+ LoadEnv::initializeUIDefaults( m_xSMGR, lDescriptor, true, NULL );
+
+ // <- SAFE ------------------------------
+ aWriteLock.unlock();
+
+ implts_flushConfigItem(rInfo);
+ implts_informListener(eJob,
+ AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &rInfo));
+
+ try
+ {
+ implts_openOneDoc(sURL, lDescriptor, rInfo);
+ }
+ catch(const css::uno::Exception&)
+ {
+ rInfo.DocumentState &= ~AutoRecovery::E_TRY_LOAD_BACKUP;
+ rInfo.DocumentState &= ~AutoRecovery::E_TRY_LOAD_ORIGINAL;
+ if (sLoadBackupURL.getLength())
+ {
+ rInfo.DocumentState |= AutoRecovery::E_INCOMPLETE;
+ eTimer = AutoRecovery::E_CALL_ME_BACK;
+ }
+ else
+ {
+ rInfo.DocumentState |= AutoRecovery::E_HANDLED;
+ rInfo.DocumentState |= AutoRecovery::E_DAMAGED;
+ }
+
+ implts_flushConfigItem(rInfo, sal_True);
+ implts_informListener(eJob,
+ AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &rInfo));
+
+ // SAFE -> ------------------------------
+ // Needed for next loop!
+ aWriteLock.lock();
+ continue;
+ }
+
+ if (rInfo.RealFilter.getLength())
+ {
+ ::comphelper::MediaDescriptor lPatchDescriptor(rInfo.Document->getArgs());
+ lPatchDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= rInfo.RealFilter;
+ rInfo.Document->attachResource(rInfo.Document->getURL(), lPatchDescriptor.getAsConstPropertyValueList());
+ // do *not* use sURL here. In case this points to the recovery file, it has already been passed
+ // to recoverFromFile. Also, passing it here is logically wrong, as attachResource is intended
+ // to take the logical file URL.
+ }
+
+ css::uno::Reference< css::util::XModifiable > xModify(rInfo.Document, css::uno::UNO_QUERY);
+ if ( xModify.is() )
+ {
+ sal_Bool bModified = ((rInfo.DocumentState & AutoRecovery::E_MODIFIED) == AutoRecovery::E_MODIFIED);
+ xModify->setModified(bModified);
+ }
+
+ rInfo.DocumentState &= ~AutoRecovery::E_TRY_LOAD_BACKUP;
+ rInfo.DocumentState &= ~AutoRecovery::E_TRY_LOAD_ORIGINAL;
+ rInfo.DocumentState |= AutoRecovery::E_HANDLED;
+ rInfo.DocumentState |= AutoRecovery::E_SUCCEDED;
+
+ implts_flushConfigItem(rInfo);
+ implts_informListener(eJob,
+ AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &rInfo));
+
+ /* Normaly we listen as XModifyListener on a document to know if a document was changed
+ since our last AutoSave. And we deregister us in case we know this state.
+ But directly after one document as recovered ... we must start listening.
+ Otherwhise the first "modify" doesnt reach us. Because we ourself called setModified()
+ on the document via API. And currently we dont listen for any events (not at the GlobalEventBroadcaster
+ nor at any document!).
+ */
+ implts_startModifyListeningOnDoc(rInfo);
+
+ // SAFE -> ------------------------------
+ // Needed for next loop. Dont unlock it again!
+ aWriteLock.lock();
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return eTimer;
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_openOneDoc(const ::rtl::OUString& sURL ,
+ ::comphelper::MediaDescriptor& lDescriptor,
+ AutoRecovery::TDocumentInfo& rInfo )
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::frame::XFrame > xDesktop( xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW );
+
+ ::std::vector< Reference< XComponent > > aCleanup;
+ try
+ {
+ // create a new document of the desired type
+ Reference< XModel2 > xModel( xSMGR->createInstance( rInfo.FactoryService ), UNO_QUERY_THROW );
+ aCleanup.push_back( xModel.get() );
+
+ // put the filter name into the descriptor - we're not going to involve any type detection, so
+ // the document might be lost without the FilterName property
+ lDescriptor[ ::comphelper::MediaDescriptor::PROP_FILTERNAME() ] <<= rInfo.RealFilter;
+
+ if ( sURL == rInfo.FactoryURL )
+ {
+ // if the document was a new, unmodified document, then there's nothing to recover, just to init
+ ENSURE_OR_THROW( ( rInfo.DocumentState & AutoRecovery::E_MODIFIED ) == 0,
+ "unexpected document state" );
+ Reference< XLoadable > xModelLoad( xModel, UNO_QUERY_THROW );
+ xModelLoad->initNew();
+
+ // TODO: remove load-process specific arguments from the descriptor, e.g. the status indicator
+ xModel->attachResource( sURL, lDescriptor.getAsConstPropertyValueList() );
+ }
+ else
+ {
+ // let it recover itself
+ Reference< XDocumentRecovery > xDocRecover( xModel, UNO_QUERY_THROW );
+ xDocRecover->recoverFromFile(
+ sURL,
+ lDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_SALVAGEDFILE(), ::rtl::OUString() ),
+ lDescriptor.getAsConstPropertyValueList()
+ );
+
+ // No attachResource needed here. By definition (of XDocumentRecovery), the implementation is responsible
+ // for completely initializing the model, which includes attachResource (or equivalent), if required.
+ }
+
+ // re-create all the views
+ ::std::vector< ::rtl::OUString > aViewsToRestore( rInfo.ViewNames.getLength() );
+ if ( rInfo.ViewNames.getLength() )
+ ::std::copy( rInfo.ViewNames.getConstArray(), rInfo.ViewNames.getConstArray() + rInfo.ViewNames.getLength(), aViewsToRestore.begin() );
+ // if we don't have views for whatever reason, then create a default-view, at least
+ if ( aViewsToRestore.empty() )
+ aViewsToRestore.push_back( ::rtl::OUString() );
+
+ for ( ::std::vector< ::rtl::OUString >::const_iterator viewName = aViewsToRestore.begin();
+ viewName != aViewsToRestore.end();
+ ++viewName
+ )
+ {
+ // create a frame
+ Reference< XFrame > xTargetFrame = xDesktop->findFrame( SPECIALTARGET_BLANK, 0 );
+ aCleanup.push_back( xTargetFrame.get() );
+
+ // create a view to the document
+ Reference< XController2 > xController;
+ if ( viewName->getLength() )
+ {
+ xController.set( xModel->createViewController( *viewName, Sequence< PropertyValue >(), xTargetFrame ), UNO_SET_THROW );
+ }
+ else
+ {
+ xController.set( xModel->createDefaultViewController( xTargetFrame ), UNO_SET_THROW );
+ }
+
+ // introduce model/view/controller to each other
+ xController->attachModel( xModel.get() );
+ xModel->connectController( xController.get() );
+ xTargetFrame->setComponent( xController->getComponentWindow(), xController.get() );
+ xController->attachFrame( xTargetFrame );
+ xModel->setCurrentController( xController.get() );
+ }
+
+ rInfo.Document = xModel.get();
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ {
+ Any aCaughtException( ::cppu::getCaughtException() );
+
+ // clean up
+ for ( ::std::vector< Reference< XComponent > >::const_iterator component = aCleanup.begin();
+ component != aCleanup.end();
+ ++component
+ )
+ {
+ css::uno::Reference< css::util::XCloseable > xClose( *component, css::uno::UNO_QUERY );
+ if ( xClose.is() )
+ xClose->close( sal_True );
+ else
+ (*component)->dispose();
+ }
+
+ // re-throw
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("Recovery of \"");
+ sMsg.append (sURL );
+ sMsg.appendAscii("\" failed." );
+
+ throw css::lang::WrappedTargetException(
+ sMsg.makeStringAndClear(),
+ static_cast< css::frame::XDispatch* >(this),
+ aCaughtException
+ );
+ }
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_generateNewTempURL(const ::rtl::OUString& sBackupPath ,
+ ::comphelper::MediaDescriptor& /*rMediaDescriptor*/,
+ AutoRecovery::TDocumentInfo& rInfo )
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // specify URL for saving (which points to a temp file inside backup directory)
+ // and define an unique name, so we can locate it later.
+ // This unique name must solve an optimization problem too!
+ // In case we are asked to save unmodified documents too - and one of them
+ // is an empty one (because it was new created using e.g. an URL private:factory/...)
+ // we should not save it realy. Then we put the information about such "empty document"
+ // into the configuration and dont create any recovery file on disk.
+ // We use the title of the document to make it unique.
+ ::rtl::OUStringBuffer sUniqueName;
+ if (rInfo.OrgURL.getLength())
+ {
+ css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
+ css::util::URL aURL;
+ aURL.Complete = rInfo.OrgURL;
+ xParser->parseStrict(aURL);
+ sUniqueName.append(aURL.Name);
+ }
+ else
+ if (rInfo.FactoryURL.getLength())
+ sUniqueName.appendAscii("untitled");
+ sUniqueName.appendAscii("_");
+
+ // TODO: Must we strip some illegal signes - if we use the title?
+
+ String sName (sUniqueName.makeStringAndClear());
+ String sExtension(rInfo.Extension );
+ String sPath (sBackupPath );
+ ::utl::TempFile aTempFile(sName, &sExtension, &sPath);
+
+ rInfo.NewTempURL = aTempFile.GetURL();
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_informListener( sal_Int32 eJob ,
+ const css::frame::FeatureStateEvent& aEvent)
+{
+ // Helper shares mutex with us -> threadsafe!
+ ::cppu::OInterfaceContainerHelper* pListenerForURL = 0;
+ ::rtl::OUString sJob = AutoRecovery::implst_getJobDescription(eJob);
+
+ // inform listener, which are registered for any URLs(!)
+ pListenerForURL = m_lListener.getContainer(sJob);
+ if(pListenerForURL != 0)
+ {
+ ::cppu::OInterfaceIteratorHelper pIt(*pListenerForURL);
+ while(pIt.hasMoreElements())
+ {
+ try
+ {
+ css::uno::Reference< css::frame::XStatusListener > xListener(((css::frame::XStatusListener*)pIt.next()), css::uno::UNO_QUERY);
+ xListener->statusChanged(aEvent);
+ }
+ catch(const css::uno::RuntimeException&)
+ { pIt.remove(); }
+ }
+ }
+}
+
+//-----------------------------------------------
+::rtl::OUString AutoRecovery::implst_getJobDescription(sal_Int32 eJob)
+{
+ // describe the current running operation
+ ::rtl::OUStringBuffer sFeature(256);
+ sFeature.append(CMD_PROTOCOL);
+
+ // Attention: Because "eJob" is used as a flag field the order of checking these
+ // flags is importent. We must preferr job with higher priorities!
+ // E.g. EmergencySave has an higher prio then AutoSave ...
+ // On the other side there exist a well defined order between two different jobs.
+ // e.g. PrepareEmergencySave must be done before EmergencySave is started of course.
+
+ if ((eJob & AutoRecovery::E_PREPARE_EMERGENCY_SAVE) == AutoRecovery::E_PREPARE_EMERGENCY_SAVE)
+ sFeature.append(CMD_DO_PREPARE_EMERGENCY_SAVE);
+ else
+ if ((eJob & AutoRecovery::E_EMERGENCY_SAVE) == AutoRecovery::E_EMERGENCY_SAVE)
+ sFeature.append(CMD_DO_EMERGENCY_SAVE);
+ else
+ if ((eJob & AutoRecovery::E_RECOVERY) == AutoRecovery::E_RECOVERY)
+ sFeature.append(CMD_DO_RECOVERY);
+ else
+ if ((eJob & AutoRecovery::E_SESSION_SAVE) == AutoRecovery::E_SESSION_SAVE)
+ sFeature.append(CMD_DO_SESSION_SAVE);
+ else
+ if ((eJob & AutoRecovery::E_SESSION_QUIET_QUIT) == AutoRecovery::E_SESSION_QUIET_QUIT)
+ sFeature.append(CMD_DO_SESSION_QUIET_QUIT);
+ else
+ if ((eJob & AutoRecovery::E_SESSION_RESTORE) == AutoRecovery::E_SESSION_RESTORE)
+ sFeature.append(CMD_DO_SESSION_RESTORE);
+ else
+ if ((eJob & AutoRecovery::E_ENTRY_BACKUP) == AutoRecovery::E_ENTRY_BACKUP)
+ sFeature.append(CMD_DO_ENTRY_BACKUP);
+ else
+ if ((eJob & AutoRecovery::E_ENTRY_CLEANUP) == AutoRecovery::E_ENTRY_CLEANUP)
+ sFeature.append(CMD_DO_ENTRY_CLEANUP);
+ else
+ if ((eJob & AutoRecovery::E_AUTO_SAVE) == AutoRecovery::E_AUTO_SAVE)
+ sFeature.append(CMD_DO_AUTO_SAVE);
+ #ifdef ENABLE_WARNINGS
+ else if ( eJob != AutoRecovery::E_NO_JOB )
+ LOG_WARNING("AutoRecovery::implst_getJobDescription()", "Invalid job identifier detected.")
+ #endif
+
+ return sFeature.makeStringAndClear();
+}
+
+//-----------------------------------------------
+sal_Int32 AutoRecovery::implst_classifyJob(const css::util::URL& aURL)
+{
+ if (aURL.Protocol.equals(CMD_PROTOCOL))
+ {
+ if (aURL.Path.equals(CMD_DO_PREPARE_EMERGENCY_SAVE))
+ return AutoRecovery::E_PREPARE_EMERGENCY_SAVE;
+ else
+ if (aURL.Path.equals(CMD_DO_EMERGENCY_SAVE))
+ return AutoRecovery::E_EMERGENCY_SAVE;
+ else
+ if (aURL.Path.equals(CMD_DO_RECOVERY))
+ return AutoRecovery::E_RECOVERY;
+ else
+ if (aURL.Path.equals(CMD_DO_ENTRY_BACKUP))
+ return AutoRecovery::E_ENTRY_BACKUP;
+ else
+ if (aURL.Path.equals(CMD_DO_ENTRY_CLEANUP))
+ return AutoRecovery::E_ENTRY_CLEANUP;
+ else
+ if (aURL.Path.equals(CMD_DO_SESSION_SAVE))
+ return AutoRecovery::E_SESSION_SAVE;
+ else
+ if (aURL.Path.equals(CMD_DO_SESSION_QUIET_QUIT))
+ return AutoRecovery::E_SESSION_QUIET_QUIT;
+ else
+ if (aURL.Path.equals(CMD_DO_SESSION_RESTORE))
+ return AutoRecovery::E_SESSION_RESTORE;
+ else
+ if (aURL.Path.equals(CMD_DO_DISABLE_RECOVERY))
+ return AutoRecovery::E_DISABLE_AUTORECOVERY;
+ else
+ if (aURL.Path.equals(CMD_DO_SET_AUTOSAVE_STATE))
+ return AutoRecovery::E_SET_AUTOSAVE_STATE;
+ }
+
+ LOG_WARNING("AutoRecovery::implts_classifyJob()", "Invalid URL (protocol).")
+ return AutoRecovery::E_NO_JOB;
+}
+
+//-----------------------------------------------
+css::frame::FeatureStateEvent AutoRecovery::implst_createFeatureStateEvent( sal_Int32 eJob ,
+ const ::rtl::OUString& sEventType,
+ AutoRecovery::TDocumentInfo* pInfo )
+{
+ css::frame::FeatureStateEvent aEvent;
+ aEvent.FeatureURL.Complete = AutoRecovery::implst_getJobDescription(eJob);
+ aEvent.FeatureDescriptor = sEventType;
+
+ if (sEventType.equals(OPERATION_UPDATE) && pInfo)
+ {
+ // pack rInfo for transport via UNO
+ ::comphelper::NamedValueCollection aInfo;
+ aInfo.put( CFG_ENTRY_PROP_ID, pInfo->ID );
+ aInfo.put( CFG_ENTRY_PROP_ORIGINALURL, pInfo->OrgURL );
+ aInfo.put( CFG_ENTRY_PROP_FACTORYURL, pInfo->FactoryURL );
+ aInfo.put( CFG_ENTRY_PROP_TEMPLATEURL, pInfo->TemplateURL );
+ aInfo.put( CFG_ENTRY_PROP_TEMPURL, pInfo->OldTempURL.getLength() ? pInfo->OldTempURL : pInfo->NewTempURL );
+ aInfo.put( CFG_ENTRY_PROP_MODULE, pInfo->AppModule );
+ aInfo.put( CFG_ENTRY_PROP_TITLE, pInfo->Title );
+ aInfo.put( CFG_ENTRY_PROP_VIEWNAMES, pInfo->ViewNames );
+ aInfo.put( CFG_ENTRY_PROP_DOCUMENTSTATE, pInfo->DocumentState );
+
+ aEvent.State <<= aInfo.getPropertyValues();
+ }
+
+ return aEvent;
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_resetHandleStates(sal_Bool /*bLoadCache*/)
+{
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ // SAFE -> ------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ AutoRecovery::TDocumentList::iterator pIt;
+ for ( pIt = m_lDocCache.begin();
+ pIt != m_lDocCache.end() ;
+ ++pIt )
+ {
+ AutoRecovery::TDocumentInfo& rInfo = *pIt;
+ rInfo.DocumentState &= ~AutoRecovery::E_HANDLED ;
+ rInfo.DocumentState &= ~AutoRecovery::E_POSTPONED;
+
+ // SAFE -> ------------------------------
+ aWriteLock.unlock();
+ implts_flushConfigItem(rInfo);
+ aWriteLock.lock();
+ // <- SAFE ------------------------------
+ }
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_prepareEmergencySave()
+{
+ // Be sure to know all open documents realy .-)
+ implts_verifyCacheAgainstDesktopDocumentList();
+
+ // hide all docs, so the user cant disturb our emergency save .-)
+ implts_changeAllDocVisibility(sal_False);
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_doEmergencySave(const DispatchParams& aParams)
+{
+ // Write a hint "we chrashed" into the configuration, so
+ // the error report tool is started too in case no recovery
+ // documents exists and was saved.
+ ::comphelper::ConfigurationHelper::writeDirectKey(
+ m_xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_RECOVERYINFO,
+ CFG_ENTRY_CRASHED,
+ css::uno::makeAny(sal_True),
+ ::comphelper::ConfigurationHelper::E_STANDARD);
+
+ // for all docs, store their current view/names in the configurtion
+ implts_persistAllActiveViewNames();
+
+ // The called method for saving documents runs
+ // during normal AutoSave more then once. Because
+ // it postpone active documents and save it later.
+ // That is normaly done by recalling it from a timer.
+ // Here we must do it immediatly!
+ // Of course this method returns the right state -
+ // because it knows, that we are running in ERMERGENCY SAVE mode .-)
+
+ sal_Bool bAllowUserIdleLoop = sal_False; // not allowed to change that .-)
+ AutoRecovery::ETimerType eSuggestedTimer = AutoRecovery::E_DONT_START_TIMER;
+ do
+ {
+ eSuggestedTimer = implts_saveDocs(bAllowUserIdleLoop, sal_True, &aParams);
+ }
+ while(eSuggestedTimer == AutoRecovery::E_CALL_ME_BACK);
+
+ // reset the handle state of all
+ // cache items. Such handle state indicates, that a document
+ // was already saved during the THIS(!) EmergencySave session.
+ // Of course following recovery session must be started without
+ // any "handle" state ...
+ implts_resetHandleStates(sal_False);
+
+ // flush config cached back to disc.
+ impl_flushALLConfigChanges();
+
+ // try to make sure next time office will be started user wont be
+ // notified about any other might be running office instance
+ // remove ".lock" file from disc !
+ AutoRecovery::st_impl_removeLockFile();
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_doRecovery(const DispatchParams& aParams)
+{
+ AutoRecovery::ETimerType eSuggestedTimer = AutoRecovery::E_DONT_START_TIMER;
+ do
+ {
+ eSuggestedTimer = implts_openDocs(aParams);
+ }
+ while(eSuggestedTimer == AutoRecovery::E_CALL_ME_BACK);
+
+ // reset the handle state of all
+ // cache items. Such handle state indicates, that a document
+ // was already saved during the THIS(!) Recovery session.
+ // Of course a may be following EmergencySave session must be started without
+ // any "handle" state ...
+ implts_resetHandleStates(sal_True);
+
+ // Reset the configuration hint "we was crashed"!
+ ::comphelper::ConfigurationHelper::writeDirectKey(
+ m_xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_RECOVERYINFO,
+ CFG_ENTRY_CRASHED,
+ css::uno::makeAny(sal_False),
+ ::comphelper::ConfigurationHelper::E_STANDARD);
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_doSessionSave(const DispatchParams& aParams)
+{
+ LOG_RECOVERY("AutoRecovery::implts_doSessionSave()")
+
+ // Be sure to know all open documents realy .-)
+ implts_verifyCacheAgainstDesktopDocumentList();
+
+ // for all docs, store their current view/names in the configurtion
+ implts_persistAllActiveViewNames();
+
+ // The called method for saving documents runs
+ // during normal AutoSave more then once. Because
+ // it postpone active documents and save it later.
+ // That is normaly done by recalling it from a timer.
+ // Here we must do it immediatly!
+ // Of course this method returns the right state -
+ // because it knows, that we are running in SESSION SAVE mode .-)
+
+ sal_Bool bAllowUserIdleLoop = sal_False; // not allowed to change that .-)
+ AutoRecovery::ETimerType eSuggestedTimer = AutoRecovery::E_DONT_START_TIMER;
+ do
+ {
+ // do not remove lock files of the documents, it will be done on session quit
+ eSuggestedTimer = implts_saveDocs(bAllowUserIdleLoop, sal_False, &aParams);
+ }
+ while(eSuggestedTimer == AutoRecovery::E_CALL_ME_BACK);
+
+ // reset the handle state of all
+ // cache items. Such handle state indicates, that a document
+ // was already saved during the THIS(!) save session.
+ // Of course following restore session must be started without
+ // any "handle" state ...
+ implts_resetHandleStates(sal_False);
+
+ // flush config cached back to disc.
+ impl_flushALLConfigChanges();
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_doSessionQuietQuit(const DispatchParams& /*aParams*/)
+{
+ LOG_RECOVERY("AutoRecovery::implts_doSessionQuietQuit()")
+
+ // try to make sure next time office will be started user wont be
+ // notified about any other might be running office instance
+ // remove ".lock" file from disc !
+ // it is done as a first action for session save since Gnome sessions
+ // do not provide enough time for shutdown, and the dialog looks to be
+ // confusing for the user
+ AutoRecovery::st_impl_removeLockFile();
+
+ // reset all modified documents, so the dont show any UI on closing ...
+ // and close all documents, so we can shutdown the OS!
+ implts_prepareSessionShutdown();
+
+ // Write a hint for "stored session data" into the configuration, so
+ // the on next startup we know what's happen last time
+ ::comphelper::ConfigurationHelper::writeDirectKey(
+ m_xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_RECOVERYINFO,
+ CFG_ENTRY_SESSIONDATA,
+ css::uno::makeAny(sal_True),
+ ::comphelper::ConfigurationHelper::E_STANDARD);
+
+ // flush config cached back to disc.
+ impl_flushALLConfigChanges();
+}
+
+
+//-----------------------------------------------
+void AutoRecovery::implts_doSessionRestore(const DispatchParams& aParams)
+{
+ LOG_RECOVERY("AutoRecovery::implts_doSessionRestore() ...")
+
+ AutoRecovery::ETimerType eSuggestedTimer = AutoRecovery::E_DONT_START_TIMER;
+ do
+ {
+ eSuggestedTimer = implts_openDocs(aParams);
+ }
+ while(eSuggestedTimer == AutoRecovery::E_CALL_ME_BACK);
+
+ // reset the handle state of all
+ // cache items. Such handle state indicates, that a document
+ // was already saved during the THIS(!) Restore session.
+ // Of course a may be following save session must be started without
+ // any "handle" state ...
+ implts_resetHandleStates(sal_True);
+
+ // make all opened documents visible
+ implts_changeAllDocVisibility(sal_True);
+
+ // Reset the configuration hint for "session save"!
+ LOG_RECOVERY("... reset config key 'SessionData'")
+ ::comphelper::ConfigurationHelper::writeDirectKey(
+ m_xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_RECOVERYINFO,
+ CFG_ENTRY_SESSIONDATA,
+ css::uno::makeAny(sal_False),
+ ::comphelper::ConfigurationHelper::E_STANDARD);
+
+ LOG_RECOVERY("... AutoRecovery::implts_doSessionRestore()")
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_backupWorkingEntry(const DispatchParams& aParams)
+{
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_USE);
+
+ AutoRecovery::TDocumentList::iterator pIt;
+ for ( pIt = m_lDocCache.begin();
+ pIt != m_lDocCache.end() ;
+ ++pIt )
+ {
+ const AutoRecovery::TDocumentInfo& rInfo = *pIt;
+ if (rInfo.ID != aParams.m_nWorkingEntryID)
+ continue;
+
+ ::rtl::OUString sSourceURL;
+ // Prefer temp file. It contains the changes against the original document!
+ if (rInfo.OldTempURL.getLength())
+ sSourceURL = rInfo.OldTempURL;
+ else
+ if (rInfo.NewTempURL.getLength())
+ sSourceURL = rInfo.NewTempURL;
+ else
+ if (rInfo.OrgURL.getLength())
+ sSourceURL = rInfo.OrgURL;
+ else
+ continue; // nothing real to save! An unmodified but new created document.
+
+ INetURLObject aParser(sSourceURL);
+ // AutoRecovery::EFailureSafeResult eResult =
+ implts_copyFile(sSourceURL, aParams.m_sSavePath, aParser.getName());
+
+ // TODO: Check eResult and react for errors (InteractionHandler!?)
+ // Currently we ignore it ...
+ // DONT UPDATE THE CACHE OR REMOVE ANY TEMP. FILES FROM DISK.
+ // That has to be forced from outside explicitly.
+ // See implts_cleanUpWorkingEntry() for further details.
+ }
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_cleanUpWorkingEntry(const DispatchParams& aParams)
+{
+ CacheLockGuard aCacheLock(this, m_aLock, m_nDocCacheLock, LOCK_FOR_CACHE_ADD_REMOVE);
+
+ AutoRecovery::TDocumentList::iterator pIt;
+ for ( pIt = m_lDocCache.begin();
+ pIt != m_lDocCache.end() ;
+ ++pIt )
+ {
+ AutoRecovery::TDocumentInfo& rInfo = *pIt;
+ if (rInfo.ID != aParams.m_nWorkingEntryID)
+ continue;
+
+ AutoRecovery::st_impl_removeFile(rInfo.OldTempURL);
+ AutoRecovery::st_impl_removeFile(rInfo.NewTempURL);
+ implts_flushConfigItem(rInfo, sal_True); // sal_True => remove it from xml config!
+
+ m_lDocCache.erase(pIt);
+ break; /// !!! pIt is not defined any longer ... further this function has finished it's work
+ }
+}
+
+//-----------------------------------------------
+AutoRecovery::EFailureSafeResult AutoRecovery::implts_copyFile(const ::rtl::OUString& sSource ,
+ const ::rtl::OUString& sTargetPath,
+ const ::rtl::OUString& sTargetName)
+{
+ // create content for the parent folder and call transfer on that content with the source content
+ // and the destination file name as parameters
+
+ css::uno::Reference< css::ucb::XCommandEnvironment > xEnvironment;
+
+ ::ucbhelper::Content aSourceContent;
+ ::ucbhelper::Content aTargetContent;
+
+ try
+ {
+ aTargetContent = ::ucbhelper::Content(sTargetPath, xEnvironment);
+ }
+ catch(const css::uno::Exception&)
+ { return AutoRecovery::E_WRONG_TARGET_PATH; }
+
+ sal_Int32 nNameClash;
+ nNameClash = css::ucb::NameClash::RENAME;
+
+ try
+ {
+ ::ucbhelper::Content::create(sSource, xEnvironment, aSourceContent);
+ aTargetContent.transferContent(aSourceContent, ::ucbhelper::InsertOperation_COPY, sTargetName, nNameClash);
+ }
+ catch(const css::uno::Exception&)
+ { return AutoRecovery::E_ORIGINAL_FILE_MISSING; }
+
+ return AutoRecovery::E_COPIED;
+}
+
+//-----------------------------------------------
+sal_Bool SAL_CALL AutoRecovery::convertFastPropertyValue( css::uno::Any& /*aConvertedValue*/,
+ css::uno::Any& /*aOldValue*/ ,
+ sal_Int32 /*nHandle*/ ,
+ const css::uno::Any& /*aValue*/ )
+ throw(css::lang::IllegalArgumentException)
+{
+ // not needed currently
+ return sal_False;
+}
+
+//-----------------------------------------------
+void SAL_CALL AutoRecovery::setFastPropertyValue_NoBroadcast( sal_Int32 /*nHandle*/,
+ const css::uno::Any& /*aValue*/ )
+ throw(css::uno::Exception)
+{
+ // not needed currently
+}
+
+//-----------------------------------------------
+void SAL_CALL AutoRecovery::getFastPropertyValue(css::uno::Any& aValue ,
+ sal_Int32 nHandle) const
+{
+ switch(nHandle)
+ {
+ case AUTORECOVERY_PROPHANDLE_EXISTS_RECOVERYDATA :
+ {
+ sal_Bool bSessionData = sal_False;
+ ::comphelper::ConfigurationHelper::readDirectKey(
+ m_xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_RECOVERYINFO,
+ CFG_ENTRY_SESSIONDATA,
+ ::comphelper::ConfigurationHelper::E_READONLY) >>= bSessionData;
+
+ sal_Bool bRecoveryData = ((sal_Bool)(m_lDocCache.size()>0));
+
+ // exists session data ... => then we cant say, that these
+ // data are valid for recovery. So we have to return sal_False then!
+ if (bSessionData)
+ bRecoveryData = sal_False;
+
+ aValue <<= bRecoveryData;
+ }
+ break;
+
+ case AUTORECOVERY_PROPHANDLE_CRASHED :
+ aValue = ::comphelper::ConfigurationHelper::readDirectKey(
+ m_xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_RECOVERYINFO,
+ CFG_ENTRY_CRASHED,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ break;
+
+ case AUTORECOVERY_PROPHANDLE_EXISTS_SESSIONDATA :
+ aValue = ::comphelper::ConfigurationHelper::readDirectKey(
+ m_xSMGR,
+ CFG_PACKAGE_RECOVERY,
+ CFG_PATH_RECOVERYINFO,
+ CFG_ENTRY_SESSIONDATA,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ break;
+ }
+}
+
+//-----------------------------------------------
+const css::uno::Sequence< css::beans::Property > impl_getStaticPropertyDescriptor()
+{
+ static const css::beans::Property pPropertys[] =
+ {
+ css::beans::Property( AUTORECOVERY_PROPNAME_CRASHED , AUTORECOVERY_PROPHANDLE_CRASHED , ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
+ css::beans::Property( AUTORECOVERY_PROPNAME_EXISTS_RECOVERYDATA, AUTORECOVERY_PROPHANDLE_EXISTS_RECOVERYDATA, ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
+ css::beans::Property( AUTORECOVERY_PROPNAME_EXISTS_SESSIONDATA , AUTORECOVERY_PROPHANDLE_EXISTS_SESSIONDATA , ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
+ };
+ static const css::uno::Sequence< css::beans::Property > lPropertyDescriptor(pPropertys, AUTORECOVERY_PROPCOUNT);
+ return lPropertyDescriptor;
+}
+
+//-----------------------------------------------
+::cppu::IPropertyArrayHelper& SAL_CALL AutoRecovery::getInfoHelper()
+{
+ static ::cppu::OPropertyArrayHelper* pInfoHelper = 0;
+ if(!pInfoHelper)
+ {
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ if(!pInfoHelper)
+ {
+ static ::cppu::OPropertyArrayHelper aInfoHelper(impl_getStaticPropertyDescriptor(), sal_True);
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return (*pInfoHelper);
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL AutoRecovery::getPropertySetInfo()
+ throw(css::uno::RuntimeException)
+{
+ static css::uno::Reference< css::beans::XPropertySetInfo >* pInfo = 0;
+ if(!pInfo)
+ {
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ if(!pInfo)
+ {
+ static css::uno::Reference< css::beans::XPropertySetInfo > xInfo(createPropertySetInfo(getInfoHelper()));
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+//-----------------------------------------------
+void AutoRecovery::implts_verifyCacheAgainstDesktopDocumentList()
+{
+ LOG_RECOVERY("AutoRecovery::implts_verifyCacheAgainstDesktopDocumentList() ...")
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ try
+ {
+ css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
+ xSMGR->createInstance(SERVICENAME_DESKTOP),
+ css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::container::XIndexAccess > xContainer(
+ xDesktop->getFrames(),
+ css::uno::UNO_QUERY_THROW);
+
+ sal_Int32 i = 0;
+ sal_Int32 c = xContainer->getCount();
+
+ for (i=0; i<c; ++i)
+ {
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ try
+ {
+ xContainer->getByIndex(i) >>= xFrame;
+ if (!xFrame.is())
+ continue;
+ }
+ // can happen in multithreaded environments, that frames was removed from the container during this loop runs!
+ // Ignore it.
+ catch(const css::lang::IndexOutOfBoundsException&)
+ { continue; }
+
+ // We are interested on visible documents only.
+ // Note: It's n optional interface .-(
+ css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(
+ xFrame->getContainerWindow(),
+ css::uno::UNO_QUERY);
+ if (
+ (!xVisibleCheck.is() ) ||
+ (!xVisibleCheck->isVisible())
+ )
+ {
+ continue;
+ }
+
+ // extract the model from the frame.
+ // Ignore "view only" frames, which does not have a model.
+ css::uno::Reference< css::frame::XController > xController;
+ css::uno::Reference< css::frame::XModel > xModel;
+
+ xController = xFrame->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+ if (!xModel.is())
+ continue;
+
+ // insert model into cache ...
+ // If the model is already well known inside cache
+ // it's information set will be updated by asking the
+ // model again for it's new states.
+ implts_registerDocument(xModel);
+ }
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+
+ LOG_RECOVERY("... AutoRecovery::implts_verifyCacheAgainstDesktopDocumentList()")
+}
+
+//-----------------------------------------------
+sal_Bool AutoRecovery::impl_enoughDiscSpace(sal_Int32 nRequiredSpace)
+{
+ #ifdef SIMULATE_FULL_DISC
+ return sal_False;
+ #endif
+
+ // In case an error occures and we are not able to retrieve the needed information
+ // it's better to "disable" the feature ShowErrorOnFullDisc !
+ // Otherwhise we start a confusing process of error handling ...
+
+ sal_uInt64 nFreeSpace = SAL_MAX_UINT64;
+
+ ::rtl::OUString sBackupPath(SvtPathOptions().GetBackupPath());
+ ::osl::VolumeInfo aInfo (VolumeInfoMask_FreeSpace);
+ ::osl::FileBase::RC aRC = ::osl::Directory::getVolumeInfo(sBackupPath, aInfo);
+
+ if (
+ (aInfo.isValid(VolumeInfoMask_FreeSpace)) &&
+ (aRC == ::osl::FileBase::E_None )
+ )
+ {
+ nFreeSpace = aInfo.getFreeSpace();
+ }
+
+ sal_uInt64 nFreeMB = (nFreeSpace/1048576);
+ return (nFreeMB >= (sal_uInt64)nRequiredSpace);
+}
+
+//-----------------------------------------------
+void AutoRecovery::impl_showFullDiscError()
+{
+ static String PLACEHOLDER_PATH = String::CreateFromAscii("%PATH");
+
+ String sBtn(FwkResId(STR_FULL_DISC_RETRY_BUTTON));
+ String sMsg(FwkResId(STR_FULL_DISC_MSG ));
+
+ String sBackupURL(SvtPathOptions().GetBackupPath());
+ INetURLObject aConverter(sBackupURL);
+ sal_Unicode aDelimiter;
+ String sBackupPath = aConverter.getFSysPath(INetURLObject::FSYS_DETECT, &aDelimiter);
+ if (sBackupPath.Len()<1)
+ sBackupPath = sBackupURL;
+ sMsg.SearchAndReplace(PLACEHOLDER_PATH, sBackupPath);
+
+ ErrorBox dlgError(0, WB_OK, sMsg);
+ dlgError.SetButtonText(dlgError.GetButtonId(0), sBtn);
+ dlgError.Execute();
+}
+
+//-----------------------------------------------
+void AutoRecovery::impl_establishProgress(const AutoRecovery::TDocumentInfo& rInfo ,
+ ::comphelper::MediaDescriptor& rArgs ,
+ const css::uno::Reference< css::frame::XFrame >& xNewFrame)
+{
+ // external well known frame must be preferred (because it was created by ourself
+ // for loading documents into this frame)!
+ // But if no frame exists ... we can try to locate it using any frame bound to the provided
+ // document. Of course we must live without any frame in case the document does not exists at this
+ // point. But this state shouldnt occure. In such case xNewFrame should be valid ... hopefully .-)
+ css::uno::Reference< css::frame::XFrame > xFrame = xNewFrame;
+ if (
+ (!xFrame.is() ) &&
+ (rInfo.Document.is())
+ )
+ {
+ css::uno::Reference< css::frame::XController > xController = rInfo.Document->getCurrentController();
+ if (xController.is())
+ xFrame = xController->getFrame();
+ }
+
+ // Any outside progress must be used ...
+ // Only if there is no progress, we can create our own one.
+ css::uno::Reference< css::task::XStatusIndicator > xInternalProgress;
+ css::uno::Reference< css::task::XStatusIndicator > xExternalProgress = rArgs.getUnpackedValueOrDefault(
+ ::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(),
+ css::uno::Reference< css::task::XStatusIndicator >() );
+
+ // Normaly a progress is set from outside (e.g. by the CrashSave/Recovery dialog, which uses our dispatch API).
+ // But for a normal auto save we dont have such "external progress"... because this function is triggered by our own timer then.
+ // In such case we must create our own progress !
+ if (
+ (! xExternalProgress.is()) &&
+ (xFrame.is() )
+ )
+ {
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xFrame, css::uno::UNO_QUERY);
+ if (xProgressFactory.is())
+ xInternalProgress = xProgressFactory->createStatusIndicator();
+ }
+
+ // HACK
+ // An external provided progress (most given by the CrashSave/Recovery dialog)
+ // must be preferred. But we know that some application filters query it's own progress instance
+ // at the frame method Frame::createStatusIndicator().
+ // So we use a two step mechanism:
+ // 1) we set the progress inside the MediaDescriptor, which will be provided to the filter
+ // 2) and we set a special Frame property, which overwrites the normal behaviour of Frame::createStatusIndicator .-)
+ // But we supress 2) in case we uses an internal progress. Because then it doesnt matter
+ // if our applications make it wrong. In such case the internal progress resists at the same frame
+ // and there is no need to forward progress activities to e.g. an outside dialog .-)
+ if (
+ (xExternalProgress.is()) &&
+ (xFrame.is() )
+ )
+ {
+ css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY);
+ if (xFrameProps.is())
+ xFrameProps->setPropertyValue(FRAME_PROPNAME_INDICATORINTERCEPTION, css::uno::makeAny(xExternalProgress));
+ }
+
+ // But inside the MediaDescriptor we must set our own create progress ...
+ // in case there is not already anothe rprogress set.
+ rArgs.createItemIfMissing(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), xInternalProgress);
+}
+
+//-----------------------------------------------
+void AutoRecovery::impl_forgetProgress(const AutoRecovery::TDocumentInfo& rInfo ,
+ ::comphelper::MediaDescriptor& rArgs ,
+ const css::uno::Reference< css::frame::XFrame >& xNewFrame)
+{
+ // external well known frame must be preferred (because it was created by ourself
+ // for loading documents into this frame)!
+ // But if no frame exists ... we can try to locate it using any frame bound to the provided
+ // document. Of course we must live without any frame in case the document does not exists at this
+ // point. But this state shouldnt occure. In such case xNewFrame should be valid ... hopefully .-)
+ css::uno::Reference< css::frame::XFrame > xFrame = xNewFrame;
+ if (
+ (!xFrame.is() ) &&
+ (rInfo.Document.is())
+ )
+ {
+ css::uno::Reference< css::frame::XController > xController = rInfo.Document->getCurrentController();
+ if (xController.is())
+ xFrame = xController->getFrame();
+ }
+
+ // stop progress interception on corresponding frame.
+ css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY);
+ if (xFrameProps.is())
+ xFrameProps->setPropertyValue(FRAME_PROPNAME_INDICATORINTERCEPTION, css::uno::makeAny(css::uno::Reference< css::task::XStatusIndicator >()));
+
+ // forget progress inside list of arguments.
+ ::comphelper::MediaDescriptor::iterator pArg = rArgs.find(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR());
+ if (pArg != rArgs.end())
+ {
+ rArgs.erase(pArg);
+ pArg = rArgs.end();
+ }
+}
+
+//-----------------------------------------------
+void AutoRecovery::impl_flushALLConfigChanges()
+{
+ try
+ {
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::uno::XInterface > xRecoveryCfg(m_xRecoveryCFG, css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ // <- SAFE
+
+ if (xRecoveryCfg.is())
+ ::comphelper::ConfigurationHelper::flush(xRecoveryCfg);
+
+ // SOLAR SAFE ->
+ SolarMutexGuard aGuard;
+ ::utl::ConfigManager& rCfgMgr = ::utl::ConfigManager::GetConfigManager();
+ rCfgMgr.StoreConfigItems();
+ }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+//-----------------------------------------------
+void AutoRecovery::st_impl_removeFile(const ::rtl::OUString& sURL)
+{
+ if ( ! sURL.getLength())
+ return;
+
+ try
+ {
+ ::ucbhelper::Content aContent = ::ucbhelper::Content(sURL, css::uno::Reference< css::ucb::XCommandEnvironment >());
+ aContent.executeCommand(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("delete")), css::uno::makeAny(sal_True));
+ }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+//-----------------------------------------------
+void AutoRecovery::st_impl_removeLockFile()
+{
+ try
+ {
+ ::rtl::OUString sUserURL;
+ ::utl::Bootstrap::locateUserInstallation( sUserURL );
+
+ ::rtl::OUStringBuffer sLockURLBuf;
+ sLockURLBuf.append (sUserURL);
+ sLockURLBuf.appendAscii("/.lock");
+ ::rtl::OUString sLockURL = sLockURLBuf.makeStringAndClear();
+
+ AutoRecovery::st_impl_removeFile(sLockURL);
+ }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/backingcomp.cxx b/framework/source/services/backingcomp.cxx
new file mode 100644
index 000000000000..05eb6852c1ba
--- /dev/null
+++ b/framework/source/services/backingcomp.cxx
@@ -0,0 +1,868 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "services/backingcomp.hxx"
+
+#include "backingwindow.hxx"
+
+//_______________________________________________
+// own includes
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <classes/droptargetlistener.hxx>
+#include <framework/acceleratorinfo.hxx>
+#include <targets.h>
+#include <properties.h>
+#include <services.h>
+
+#include <helpid.hrc>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XDataTransferProviderAccess.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+
+//_______________________________________________
+// other includes
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/factory.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/keycod.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <svl/solar.hrc>
+#include <svl/urihelper.hxx>
+#include <osl/file.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <unotools/bootstrap.hxx>
+
+namespace framework
+{
+
+//_______________________________________________
+
+//_______________________________________________
+
+BackingComp::BackingComp( const css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR )
+ : ThreadHelpBase (&Application::GetSolarMutex() )
+ , m_xSMGR (xSMGR )
+{
+}
+
+//_______________________________________________
+
+BackingComp::~BackingComp()
+{
+}
+
+//_______________________________________________
+
+/** return information about supported interfaces.
+
+ Some interfaces are supported by his class directly, but some other ones are
+ used by aggregation. An instance of this class must provide some window interfaces.
+ But it must represent a VCL window behind such interfaces too! So we use an internal
+ saved window member to ask it for it's interfaces and return it. But we must be aware then,
+ that it can be destroyed from outside too ...
+
+ @param aType
+ describe the required interface type
+
+ @return An Any holding the instance, which provides the queried interface.
+ Note: There exist two possible results ... this instance itself and her window member!
+ */
+
+css::uno::Any SAL_CALL BackingComp::queryInterface( /*IN*/ const css::uno::Type& aType )
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Any aResult;
+
+ // first look for own supported interfaces
+ aResult = ::cppu::queryInterface(
+ aType,
+ static_cast< css::lang::XTypeProvider* >(this),
+ static_cast< css::lang::XServiceInfo* >(this),
+ static_cast< css::lang::XInitialization* >(this),
+ static_cast< css::frame::XController* >(this),
+ static_cast< css::lang::XComponent* >(this),
+ static_cast< css::lang::XEventListener* >(this),
+ static_cast< css::awt::XKeyListener* >(static_cast< css::lang::XEventListener* >(this)));
+
+ // then look for supported window interfaces
+ // Note: They exist only, if this instance was initialized
+ // with a valid window reference. It's aggregation on demand ...
+ if (!aResult.hasValue())
+ {
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ if (m_xWindow.is())
+ aResult = m_xWindow->queryInterface(aType);
+ aReadLock.unlock();
+ /* } SAFE */
+ }
+
+ // look for XWeak and XInterface
+ if (!aResult.hasValue())
+ aResult = OWeakObject::queryInterface(aType);
+
+ return aResult;
+}
+
+//_______________________________________________
+
+/** increase ref count of this instance.
+ */
+
+void SAL_CALL BackingComp::acquire()
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+//_______________________________________________
+
+/** decrease ref count of this instance.
+ */
+
+void SAL_CALL BackingComp::release()
+ throw()
+{
+ OWeakObject::release();
+}
+
+//_______________________________________________
+
+/** return collection about all supported interfaces.
+
+ Optimize this method !
+ We initialize a static variable only one time.
+ And we don't must use a mutex at every call!
+ For the first call; pTypeCollection is NULL -
+ for the second call pTypeCollection is different from NULL!
+
+ @return A list of all supported interface types.
+*/
+
+css::uno::Sequence< css::uno::Type > SAL_CALL BackingComp::getTypes()
+ throw(css::uno::RuntimeException)
+{
+ static ::cppu::OTypeCollection* pTypeCollection = NULL;
+ if (!pTypeCollection)
+ {
+ /* GLOBAL SAFE { */
+ ::osl::MutexGuard aGlobalLock(::osl::Mutex::getGlobalMutex());
+ // Control these pointer again ... it can be, that another instance will be faster then this one!
+ if (!pTypeCollection)
+ {
+ /* LOCAL SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XTypeProvider > xProvider(m_xWindow, css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ /* } LOCAL SAFE */
+
+ css::uno::Sequence< css::uno::Type > lWindowTypes;
+ if (xProvider.is())
+ lWindowTypes = xProvider->getTypes();
+
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XInitialization >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XTypeProvider >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XServiceInfo >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::frame::XController >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XComponent >*)NULL ),
+ lWindowTypes);
+
+ pTypeCollection = &aTypeCollection;
+ }
+ /* } GLOBAL SAFE */
+ }
+ return pTypeCollection->getTypes();
+}
+
+//_______________________________________________
+
+/** create one unique Id for all instances of this class.
+
+ Optimize this method
+ We initialize a static variable only one time. And we don't must use a mutex at every call!
+ For the first call; pID is NULL - for the second call pID is different from NULL!
+
+ @return A byte array, which represent the unique id.
+*/
+
+css::uno::Sequence< sal_Int8 > SAL_CALL BackingComp::getImplementationId()
+ throw(css::uno::RuntimeException)
+{
+ static ::cppu::OImplementationId* pID = NULL;
+ if (!pID)
+ {
+ /* GLOBAL SAFE { */
+ ::osl::MutexGuard aLock(::osl::Mutex::getGlobalMutex());
+ // Control these pointer again ... it can be, that another instance will be faster then this one!
+ if (!pID)
+ {
+ static ::cppu::OImplementationId aID(sal_False);
+ pID = &aID;
+ }
+ /* } GLOBAL SAFE */
+ }
+ return pID->getImplementationId();
+}
+
+//_______________________________________________
+
+/** returns a static implementation name for this UNO service.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticImplementationName()
+ @see IMPLEMENTATIONNAME
+
+ @return The implementation name of this class.
+*/
+
+::rtl::OUString SAL_CALL BackingComp::getImplementationName()
+ throw(css::uno::RuntimeException)
+{
+ return impl_getStaticImplementationName();
+}
+
+//_______________________________________________
+
+/** returns information about supported services.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return <TRUE/> if the queried service is supported;
+ <br><FALSE/> otherwise.
+*/
+
+sal_Bool SAL_CALL BackingComp::supportsService( /*IN*/ const ::rtl::OUString& sServiceName )
+ throw(css::uno::RuntimeException)
+{
+ return (
+ sServiceName.equals(SERVICENAME_STARTMODULE ) ||
+ sServiceName.equals(SERVICENAME_FRAMECONTROLLER)
+ );
+}
+
+//_______________________________________________
+
+/** returns collection of supported services.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return A list of all supported uno service names.
+*/
+
+css::uno::Sequence< ::rtl::OUString > SAL_CALL BackingComp::getSupportedServiceNames()
+ throw(css::uno::RuntimeException)
+{
+ return impl_getStaticSupportedServiceNames();
+}
+
+//_______________________________________________
+
+/** returns static implementation name.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return The implementation name of this class.
+*/
+
+::rtl::OUString BackingComp::impl_getStaticImplementationName()
+{
+ return IMPLEMENTATIONNAME_STARTMODULE;
+}
+
+//_______________________________________________
+
+/** returns static list of supported service names.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return A list of all supported uno service names.
+*/
+
+css::uno::Sequence< ::rtl::OUString > BackingComp::impl_getStaticSupportedServiceNames()
+{
+ css::uno::Sequence< ::rtl::OUString > lNames(1);
+ lNames[0] = SERVICENAME_STARTMODULE;
+ return lNames;
+}
+
+//_______________________________________________
+
+/** returns a new instance of this class.
+
+ This factory method is registered inside the UNO runtime
+ and will be called for every createInstance() request from outside,
+ which wish to use this service.
+
+ @param xSMGR
+ reference to the uno service manager, which call us
+ We use it too, to set it at the new created instance.
+
+ @return A new instance as uno reference.
+*/
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL BackingComp::impl_createInstance( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ throw(css::uno::Exception)
+{
+ BackingComp* pObject = new BackingComp(xSMGR);
+ return css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(pObject), css::uno::UNO_QUERY);
+}
+
+//_______________________________________________
+
+/** returns a new factory instance for instances of this class.
+
+ It uses a helper class of the cppuhelper project as factory.
+ It will be initialized with all neccessary informations and
+ will be able afterwards to create instance of this class.
+ This factory call us back inside our method impl_createInstance().
+ So we can create and initialize ourself. Only filtering of creation
+ requests will be done by this factory.
+
+ @param xSMGR
+ reference to the uno service manager, which call us
+
+ @return A new instance of our factory.
+*/
+
+css::uno::Reference< css::lang::XSingleServiceFactory > BackingComp::impl_createFactory( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+{
+ css::uno::Reference< css::lang::XSingleServiceFactory > xReturn(
+ cppu::createSingleFactory(
+ xSMGR,
+ BackingComp::impl_getStaticImplementationName(),
+ BackingComp::impl_createInstance,
+ BackingComp::impl_getStaticSupportedServiceNames()));
+ return xReturn;
+}
+
+//_______________________________________________
+
+/**
+ attach this component to a target frame.
+
+ We has to use the container window of this frame as parent window of our own component window.
+ But it's not allowed to work with it realy. May another component used it too.
+ Currently we need it only to create our child component window and support it's
+ interfaces inside our queryInterface() method. The user of us must have e.g. the
+ XWindow interface of it to be able to call setComponent(xWindow,xController) at the
+ frame!
+
+ May he will do the following things:
+
+ <listing>
+ XController xBackingComp = (XController)UnoRuntime.queryInterface(
+ XController.class,
+ xSMGR.createInstance(SERVICENAME_STARTMODULE));
+
+ // at this time XWindow isn't present at this instance!
+ XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
+ XWindow.class,
+ xBackingComp);
+
+ // attach controller to the frame
+ // We will use it's container window, to create
+ // the component window. From now we offer the window interfaces!
+ xBackingComp.attachFrame(xFrame);
+
+ XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
+ XWindow.class,
+ xBackingComp);
+
+ // Our user can set us at the frame as new component
+ xFrame.setComponent(xBackingWin, xBackingComp);
+
+ // But that had no effect to our view state.
+ // We must be started to create our UI elements like e.g. menu, title, background ...
+ XInitialization xBackingInit = (XInitialization)UnoRuntime.queryInterface(
+ XInitialization.class,
+ xBackingComp);
+
+ xBackingInit.initialize(lArgs);
+ </listing>
+
+ @param xFrame
+ reference to our new target frame
+
+ @throw com::sun::star::uno::RuntimeException
+ if the given frame reference is wrong or component window couldn't be created
+ successfully.
+ We throw it too, if we already attached to a frame. Because we don't support
+ reparenting of our component window on demand!
+*/
+
+void SAL_CALL BackingComp::attachFrame( /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame )
+ throw (css::uno::RuntimeException)
+{
+ /* SAFE */
+ WriteGuard aWriteLock(m_aLock);
+
+ // check some required states
+ if (m_xFrame.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("already attached")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ if (!xFrame.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("invalid frame reference")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ if (!m_xWindow.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("instance seams to be not or wrong initialized")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ // safe the frame reference
+ m_xFrame = xFrame;
+
+ // establish drag&drop mode
+ ::framework::DropTargetListener* pDropListener = new ::framework::DropTargetListener(m_xSMGR, m_xFrame);
+ m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >(static_cast< ::cppu::OWeakObject* >(pDropListener), css::uno::UNO_QUERY);
+
+ css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer(m_xSMGR->createInstance(SERVICENAME_VCLTOOLKIT), css::uno::UNO_QUERY);
+ if (xTransfer.is())
+ {
+ css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget(m_xWindow);
+ if (xDropTarget.is())
+ {
+ xDropTarget->addDropTargetListener(m_xDropTargetListener);
+ xDropTarget->setActive(sal_True);
+ }
+ }
+
+ // initialize the component and it's parent window
+ css::uno::Reference< css::awt::XWindow > xParentWindow = xFrame->getContainerWindow();
+ WorkWindow* pParent = (WorkWindow*)VCLUnoHelper::GetWindow(xParentWindow);
+ Window* pWindow = VCLUnoHelper::GetWindow(m_xWindow);
+
+ // disable full screen mode of the frame!
+ if (pParent && pParent->IsFullScreenMode())
+ {
+ pParent->ShowFullScreenMode(sal_False);
+ pParent->SetMenuBarMode(MENUBAR_MODE_NORMAL);
+ }
+
+ // create the menu bar for the backing component
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ xLayoutManager->lock();
+ xLayoutManager->createElement( DECLARE_ASCII( "private:resource/menubar/menubar" ));
+ xLayoutManager->unlock();
+ }
+
+ if (pWindow)
+ {
+ // set help ID for our canvas
+ pWindow->SetHelpId(HID_BACKINGWINDOW);
+ }
+
+ // inform BackingWindow about frame
+ BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow );
+ if( pBack )
+ pBack->setOwningFrame( m_xFrame );
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ This component does not know any model. It will be represented by a window and
+ it's controller only.
+
+ return <FALSE/> everytime.
+ */
+
+sal_Bool SAL_CALL BackingComp::attachModel( /*IN*/ const css::uno::Reference< css::frame::XModel >& )
+ throw (css::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ This component does not know any model. It will be represented by a window and
+ it's controller only.
+
+ return An empty reference every time.
+ */
+
+css::uno::Reference< css::frame::XModel > SAL_CALL BackingComp::getModel()
+ throw (css::uno::RuntimeException)
+{
+ return css::uno::Reference< css::frame::XModel >();
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ return An empty value.
+ */
+
+css::uno::Any SAL_CALL BackingComp::getViewData()
+ throw (css::uno::RuntimeException)
+{
+ return css::uno::Any();
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ @param aData
+ not used.
+ */
+
+void SAL_CALL BackingComp::restoreViewData( /*IN*/ const css::uno::Any& )
+ throw (css::uno::RuntimeException)
+{
+}
+
+//_______________________________________________
+
+/** returns the attached frame for this component.
+
+ @see attachFrame()
+
+ @return The internaly saved frame reference.
+ Can be null, if attachFrame() was not called before.
+ */
+
+css::uno::Reference< css::frame::XFrame > SAL_CALL BackingComp::getFrame()
+ throw (css::uno::RuntimeException)
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ return m_xFrame;
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** ask controller for it's current working state.
+
+ If somehwere whish to close this component, it must suspend the controller before.
+ That will be a chance for it to disagree with that AND show any UI for a possible
+ UI user.
+
+ @param bSuspend
+ If its set to sal_True this controller should be suspended.
+ sal_False will resuspend it.
+
+ @return sal_True if the request could be finished successfully; sal_False otherwise.
+ */
+
+sal_Bool SAL_CALL BackingComp::suspend( /*IN*/ sal_Bool )
+ throw (css::uno::RuntimeException)
+{
+ /* FIXME ... implemented by using default :-( */
+ return sal_True;
+}
+
+//_______________________________________________
+
+/** callback from our window member.
+
+ Our internal saved window wish to die. It will be disposed from outside (may be the frame)
+ and inform us. We must release its reference only here. Of course we check the given reference
+ here and reject callback from unknown sources.
+
+ Note: deregistration as listener isnt neccessary here. The broadcaster do it automaticly.
+
+ @param aEvent
+ describe the broadcaster of this callback
+
+ @throw ::com::sun::star::uno::RuntimeException
+ if the broadcaster doesn't represent the expected window reference.
+*/
+
+void SAL_CALL BackingComp::disposing( /*IN*/ const css::lang::EventObject& aEvent )
+ throw(css::uno::RuntimeException)
+{
+ // Attention: dont free m_pAccExec here! see comments inside dtor and
+ // keyPressed() for further details.
+
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ if (!aEvent.Source.is() || aEvent.Source!=m_xWindow || !m_xWindow.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unexpected source or called twice")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ m_xWindow = css::uno::Reference< css::awt::XWindow >();
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** kill this instance.
+
+ It can be called from our owner frame only. But there is no possibility to check the calli.
+ We have to release all our internal used ressources and die. From this point we can throw
+ DisposedExceptions for every further interface request ... but current implementation doesn`t do so ...
+
+*/
+
+void SAL_CALL BackingComp::dispose()
+ throw(css::uno::RuntimeException)
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ // kill the menu
+ css::util::URL aURL;
+ aURL.Complete = DECLARE_ASCII(".uno:close");
+ css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
+ if (xParser.is())
+ xParser->parseStrict(aURL);
+
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider(m_xFrame, css::uno::UNO_QUERY);
+ if (xProvider.is())
+ {
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, SPECIALTARGET_MENUBAR, 0);
+ if (xDispatch.is())
+ xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue>());
+ }
+
+ // deregister drag&drop helper
+ if (m_xDropTargetListener.is())
+ {
+ css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer(m_xSMGR->createInstance(SERVICENAME_VCLTOOLKIT), css::uno::UNO_QUERY);
+ if (xTransfer.is())
+ {
+ css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget(m_xWindow);
+ if (xDropTarget.is())
+ {
+ xDropTarget->removeDropTargetListener(m_xDropTargetListener);
+ xDropTarget->setActive(sal_False);
+ }
+ }
+ m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >();
+ }
+
+ // stop listening at the window
+ if (m_xWindow.is())
+ {
+ css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ {
+ css::uno::Reference< css::lang::XEventListener > xEventThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ xBroadcaster->removeEventListener(xEventThis);
+ }
+ css::uno::Reference< css::awt::XKeyListener > xKeyThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ m_xWindow->removeKeyListener(xKeyThis);
+ m_xWindow = css::uno::Reference< css::awt::XWindow >();
+ }
+
+ // forget all other used references
+ m_xFrame = css::uno::Reference< css::frame::XFrame >();
+ m_xSMGR = css::uno::Reference< css::lang::XMultiServiceFactory >();
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ @param xListener
+ not used.
+
+ @throw ::com::sun::star::uno::RuntimeException
+ because the listener expect to be holded alive by this container.
+ We must inform it about this unsupported feature.
+ */
+
+void SAL_CALL BackingComp::addEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
+ throw(css::uno::RuntimeException)
+{
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("not supported")),
+ static_cast< ::cppu::OWeakObject* >(this));
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ Because registration is not supported too, we must do nothing here. Nobody can call this method realy.
+
+ @param xListener
+ not used.
+ */
+
+void SAL_CALL BackingComp::removeEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
+ throw(css::uno::RuntimeException)
+{
+}
+
+//_______________________________________________
+
+/**
+ force initialiation for this component.
+
+ Inside attachFrame() we created our component window. But it was not allowed there, to
+ initialitze it. E.g. the menu must be set at the container window of the frame, which
+ is our parent window. But may at that time another component used it.
+ That's why our creator has to inform us, when it's time to initialize us realy.
+ Currently only calling of this method must be done. But further implementatoins
+ can use special in parameter to configure this initialization ...
+
+ @param lArgs
+ currently not used
+
+ @throw com::sun::star::uno::RuntimeException
+ if some ressources are missing
+ Means if may be attachedFrame() wasn't called before.
+ */
+
+void SAL_CALL BackingComp::initialize( /*IN*/ const css::uno::Sequence< css::uno::Any >& lArgs )
+ throw(css::uno::Exception, css::uno::RuntimeException)
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_xWindow.is())
+ throw css::uno::Exception(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("already initialized")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ css::uno::Reference< css::awt::XWindow > xParentWindow;
+ if (
+ (lArgs.getLength()!=1 ) ||
+ (!(lArgs[0] >>= xParentWindow)) ||
+ (!xParentWindow.is() )
+ )
+ {
+ throw css::uno::Exception(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("wrong or corrupt argument list")),
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ // create the component window
+ Window* pParent = VCLUnoHelper::GetWindow(xParentWindow);
+ Window* pWindow = new BackingWindow(pParent);
+ m_xWindow = VCLUnoHelper::GetInterface(pWindow);
+
+ if (!m_xWindow.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("couldn't create component window")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ // start listening for window disposing
+ // It's set at our owner frame as component window later too. So it will may be disposed there ...
+ css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->addEventListener(static_cast< css::lang::XEventListener* >(this));
+
+ m_xWindow->setVisible(sal_True);
+
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/**
+ */
+
+void SAL_CALL BackingComp::keyPressed( /*IN*/ const css::awt::KeyEvent& )
+ throw(css::uno::RuntimeException)
+{
+}
+
+//_______________________________________________
+
+/**
+ */
+
+void SAL_CALL BackingComp::keyReleased( /*IN*/ const css::awt::KeyEvent& )
+ throw(css::uno::RuntimeException)
+{
+ /* Attention
+ Please use keyPressed() instead of this method. Otherwhise it would be possible, that
+ - a key input may be first switch to the backing mode
+ - and this component register itself as key listener too
+ - and it's first event will be a keyRealeased() for the already well known event, which switched to the backing mode!
+ So it will be handled twice! document => backing mode => exit app ...
+ */
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/backingwindow.cxx b/framework/source/services/backingwindow.cxx
new file mode 100644
index 000000000000..14f6dc954588
--- /dev/null
+++ b/framework/source/services/backingwindow.cxx
@@ -0,0 +1,1121 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "backingwindow.hxx"
+#include "classes/resource.hrc"
+#include "framework.hrc"
+#include "classes/fwkresid.hxx"
+#include <services.h>
+
+#include <sal/macros.h>
+
+#include "vcl/metric.hxx"
+#include "vcl/mnemonic.hxx"
+#include "vcl/menu.hxx"
+#include "vcl/svapp.hxx"
+
+#include "tools/urlobj.hxx"
+
+#include "unotools/dynamicmenuoptions.hxx"
+#include "unotools/historyoptions.hxx"
+#include "svtools/imagemgr.hxx"
+#include "svtools/svtools.hrc"
+#include "svtools/langhelp.hxx"
+
+#include "comphelper/processfactory.hxx"
+#include "comphelper/sequenceashashmap.hxx"
+#include "comphelper/configurationhelper.hxx"
+
+#include "cppuhelper/implbase1.hxx"
+
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "osl/file.h"
+
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/system/XSystemShellExecute.hpp"
+#include "com/sun/star/system/SystemShellExecuteFlags.hpp"
+#include "com/sun/star/task/XJobExecutor.hpp"
+#include "com/sun/star/util/XStringWidth.hpp"
+
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+using namespace framework;
+
+#define WRITER_URL "private:factory/swriter"
+#define CALC_URL "private:factory/scalc"
+#define IMPRESS_WIZARD_URL "private:factory/simpress?slot=6686"
+#define DRAW_URL "private:factory/sdraw"
+#define BASE_URL "private:factory/sdatabase?Interactive"
+#define MATH_URL "private:factory/smath"
+#define TEMPLATE_URL "slot:5500"
+#define OPEN_URL ".uno:Open"
+
+DecoToolBox::DecoToolBox( Window* pParent, WinBits nStyle ) :
+ ToolBox( pParent, nStyle )
+{
+ SetBackground();
+ SetPaintTransparent( sal_True );
+}
+
+void DecoToolBox::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( rDCEvt.GetFlags() & SETTINGS_STYLE )
+ {
+ calcMinSize();
+ SetBackground();
+ SetPaintTransparent( sal_True );
+ }
+}
+
+void DecoToolBox::calcMinSize()
+{
+ ToolBox aTbx( GetParent() );
+ sal_uInt16 nItems = GetItemCount();
+ for( sal_uInt16 i = 0; i < nItems; i++ )
+ {
+ sal_uInt16 nId = GetItemId( i );
+ aTbx.InsertItem( nId, GetItemImage( nId ) );
+ }
+ aTbx.SetOutStyle( TOOLBOX_STYLE_FLAT );
+ maMinSize = aTbx.CalcWindowSizePixel();
+}
+
+Size DecoToolBox::getMinSize()
+{
+ return maMinSize;
+}
+
+class RecentFilesStringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
+{
+ public:
+ RecentFilesStringLength() {}
+ virtual ~RecentFilesStringLength() {}
+
+ // XStringWidth
+ sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
+ throw (::com::sun::star::uno::RuntimeException)
+ {
+ return aString.getLength();
+ }
+};
+
+#define STC_BUTTON_STYLE (WB_LEFT | WB_VCENTER | WB_FLATBUTTON | WB_BEVELBUTTON)
+
+BackingWindow::BackingWindow( Window* i_pParent ) :
+ Window( i_pParent, FwkResId( DLG_BACKING ) ),
+ maWelcome( this, WB_LEFT ),
+ maProduct( this, WB_LEFT ),
+ maWriterButton( this, STC_BUTTON_STYLE ),
+ maCalcButton( this, STC_BUTTON_STYLE ),
+ maImpressButton( this, STC_BUTTON_STYLE ),
+ maOpenButton( this, STC_BUTTON_STYLE ),
+ maDrawButton( this, STC_BUTTON_STYLE ),
+ maDBButton( this, STC_BUTTON_STYLE ),
+ maMathButton( this, STC_BUTTON_STYLE ),
+ maTemplateButton( this, STC_BUTTON_STYLE ),
+ maToolbox( this, WB_DIALOGCONTROL ),
+ maWelcomeString( FwkResId( STR_BACKING_WELCOME ) ),
+ maProductString( FwkResId( STR_BACKING_WELCOMEPRODUCT ) ),
+ maOpenString( FwkResId( STR_BACKING_FILE ) ),
+ maTemplateString( FwkResId( STR_BACKING_TEMPLATE ) ),
+ maButtonImageSize( 10, 10 ),
+ mbInitControls( false ),
+ mnLayoutStyle( 0 ),
+ mpAccExec( NULL ),
+ mnBtnPos( 120 ),
+ mnBtnTop( 150 ),
+ mpRecentMenu( NULL )
+{
+ mnColumnWidth[0] = mnColumnWidth[1] = 0;
+ mnTextColumnWidth[0] = mnTextColumnWidth[1] = 0;
+
+ try
+ {
+ Reference<lang::XMultiServiceFactory> xConfig( comphelper::getProcessServiceFactory()->createInstance(SERVICENAME_CFGPROVIDER),UNO_QUERY);
+ if( xConfig.is() )
+ {
+ Sequence<Any> args(1);
+ PropertyValue val(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("nodepath") ),
+ 0,
+ Any(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Common/Help/StartCenter"))),
+ PropertyState_DIRECT_VALUE);
+ args.getArray()[0] <<= val;
+ Reference<container::XNameAccess> xNameAccess(xConfig->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,args), UNO_QUERY);
+ if( xNameAccess.is() )
+ {
+ //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
+ Any value( xNameAccess->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartCenterLayoutStyle"))) );
+ mnLayoutStyle = value.get<sal_Int32>();
+ }
+ }
+ }
+ catch (Exception& )
+ {
+ }
+
+ String aExtHelpText( FwkResId( STR_BACKING_EXTHELP ) );
+ String aInfoHelpText( FwkResId( STR_BACKING_INFOHELP ) );
+ String aTplRepHelpText( FwkResId( STR_BACKING_TPLREP ) );
+
+ // clean up resource stack
+ FreeResource();
+
+ maWelcome.SetPaintTransparent( sal_True );
+ maProduct.SetPaintTransparent( sal_True );
+ EnableChildTransparentMode();
+
+ SetStyle( GetStyle() | WB_DIALOGCONTROL );
+
+ // force tab cycling in toolbox
+ maToolbox.SetStyle( maToolbox.GetStyle() | WB_FORCETABCYCLE );
+
+ // insert toolbox items
+ maToolbox.InsertItem( nItemId_TplRep, Image() );
+ maToolbox.SetItemText( nItemId_TplRep, aTplRepHelpText );
+ maToolbox.SetQuickHelpText( nItemId_TplRep, aTplRepHelpText );
+ maToolbox.SetItemCommand( nItemId_TplRep, String( RTL_CONSTASCII_USTRINGPARAM( ".HelpId:StartCenter:TemplateRepository" ) ) );
+ maToolbox.ShowItem( nItemId_TplRep );
+
+ maToolbox.InsertItem( nItemId_Extensions, Image() );
+ maToolbox.SetQuickHelpText( nItemId_Extensions, aExtHelpText );
+ maToolbox.SetItemText( nItemId_Extensions, aExtHelpText );
+ maToolbox.SetItemCommand( nItemId_Extensions, String( RTL_CONSTASCII_USTRINGPARAM( ".HelpId:StartCenter:Extensions" ) ) );
+ maToolbox.ShowItem( nItemId_Extensions );
+
+ maToolbox.InsertItem( nItemId_Info, Image() );
+ maToolbox.SetItemText( nItemId_Info, aInfoHelpText );
+ maToolbox.SetQuickHelpText( nItemId_Info, aInfoHelpText );
+ maToolbox.SetItemCommand( nItemId_Info, String( RTL_CONSTASCII_USTRINGPARAM( ".HelpId:StartCenter:Info" ) ) );
+ maToolbox.ShowItem( nItemId_Info );
+
+ // get dispatch provider
+ mxDesktop = Reference<XDesktop>( comphelper::getProcessServiceFactory()->createInstance(SERVICENAME_DESKTOP ),UNO_QUERY );
+ if( mxDesktop.is() )
+ mxDesktopDispatchProvider = Reference< XDispatchProvider >( mxDesktop, UNO_QUERY );
+
+ maWriterButton.SetHelpId( ".HelpId:StartCenter:WriterButton" );
+ maCalcButton.SetHelpId( ".HelpId:StartCenter:CalcButton" );
+ maImpressButton.SetHelpId( ".HelpId:StartCenter:ImpressButton" );
+ maDrawButton.SetHelpId( ".HelpId:StartCenter:DrawButton" );
+ maDBButton.SetHelpId( ".HelpId:StartCenter:DBButton" );
+ maMathButton.SetHelpId( ".HelpId:StartCenter:MathButton" );
+ maTemplateButton.SetHelpId( ".HelpId:StartCenter:TemplateButton" );
+ maOpenButton.SetHelpId( ".HelpId:StartCenter:OpenButton" );
+ maToolbox.SetHelpId( ".HelpId:StartCenter:Toolbox" );
+
+ // init background
+ initBackground();
+
+ // add some breathing space for the images
+ maButtonImageSize.Width() += 12;
+ maButtonImageSize.Height() += 12;
+
+}
+
+
+BackingWindow::~BackingWindow()
+{
+ delete mpRecentMenu;
+ delete mpAccExec;
+}
+
+void BackingWindow::GetFocus()
+{
+ if( IsVisible() )
+ maWriterButton.GrabFocus();
+ Window::GetFocus();
+}
+
+class ImageContainerRes : public Resource
+{
+ public:
+ ImageContainerRes( const ResId& i_rId ) : Resource( i_rId ) {}
+ ~ImageContainerRes() { FreeResource(); }
+};
+
+void BackingWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( rDCEvt.GetFlags() & SETTINGS_STYLE )
+ {
+ initBackground();
+ Invalidate();
+ }
+}
+
+void BackingWindow::prepareRecentFileMenu()
+{
+ if( ! mpRecentMenu )
+ mpRecentMenu = new PopupMenu();
+ mpRecentMenu->Clear();
+ maRecentFiles.clear();
+
+ // get recent file list and dispatch arguments
+ Sequence< Sequence< PropertyValue > > aHistoryList( SvtHistoryOptions().GetList( ePICKLIST ) );
+
+ sal_Int32 nPickListMenuItems = ( aHistoryList.getLength() > 99 ) ? 99 : aHistoryList.getLength();
+
+ if( ( nPickListMenuItems > 0 ) )
+ {
+ maRecentFiles.reserve( nPickListMenuItems );
+ for ( sal_Int32 i = 0; i < nPickListMenuItems; i++ )
+ {
+ Sequence< PropertyValue >& rPickListEntry = aHistoryList[i];
+ rtl::OUString aURL, aFilter, aFilterOpt, aTitle;
+
+ for ( sal_Int32 j = 0; j < rPickListEntry.getLength(); j++ )
+ {
+ const Any& a = rPickListEntry[j].Value;
+
+ if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_URL )
+ a >>= aURL;
+ else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_FILTER )
+ {
+ a >>= aFilter;
+ sal_Int32 nPos = aFilter.indexOf( '|' );
+ if ( nPos >= 0 )
+ {
+ if ( nPos < ( aFilter.getLength() - 1 ) )
+ aFilterOpt = aFilter.copy( nPos+1 );
+ aFilter = aFilter.copy( 0, nPos-1 );
+ }
+ }
+ else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_TITLE )
+ a >>= aTitle;
+ }
+ maRecentFiles.push_back( LoadRecentFile() );
+ maRecentFiles.back().aTargetURL = aURL;
+
+ sal_Int32 nArgs = aFilterOpt.getLength() ? 4 : 3;
+ Sequence< PropertyValue >& rArgsList( maRecentFiles.back().aArgSeq );
+ rArgsList.realloc( nArgs );
+
+ nArgs--;
+ rArgsList[nArgs].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
+ rArgsList[nArgs].Value = makeAny( aFilter );
+
+ if( aFilterOpt.getLength() )
+ {
+ nArgs--;
+ rArgsList[nArgs].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterOptions" ));
+ rArgsList[nArgs].Value = makeAny( aFilterOpt );
+ }
+
+ // documents in the picklist will never be opened as templates
+ nArgs--;
+ rArgsList[nArgs].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AsTemplate" ));
+ rArgsList[nArgs].Value = makeAny( (sal_Bool) sal_False );
+
+ nArgs--;
+ rArgsList[nArgs].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
+ rArgsList[nArgs].Value = makeAny( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:user" ) ) );
+
+ // and finally create an entry in the popupmenu
+ rtl::OUString aMenuTitle;
+ INetURLObject aURLObj( aURL );
+
+ if ( aURLObj.GetProtocol() == INET_PROT_FILE )
+ {
+ // Do handle file URL differently => convert it to a system
+ // path and abbreviate it with a special function:
+ String aFileSystemPath( aURLObj.getFSysPath( INetURLObject::FSYS_DETECT ) );
+
+ rtl::OUString aSystemPath( aFileSystemPath );
+ rtl::OUString aCompactedSystemPath;
+
+ oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, NULL );
+ if ( !nError )
+ aMenuTitle = String( aCompactedSystemPath );
+ else
+ aMenuTitle = aSystemPath;
+ }
+ else
+ {
+ // Use INetURLObject to abbreviate all other URLs
+ Reference< util::XStringWidth > xStringLength( new RecentFilesStringLength() );
+ aMenuTitle = aURLObj.getAbbreviated( xStringLength, 46, INetURLObject::DECODE_UNAMBIGUOUS );
+ }
+ rtl::OUStringBuffer aBuf( aMenuTitle.getLength() + 5 );
+ if( i < 9 )
+ {
+ aBuf.append( sal_Unicode( '~' ) );
+ aBuf.append( i+1 );
+ }
+ else if( i == 9 )
+ aBuf.appendAscii( "1~0" );
+ else
+ aBuf.append( i+1 );
+ aBuf.appendAscii( ": " );
+ aBuf.append( aMenuTitle );
+ mpRecentMenu->InsertItem( static_cast<sal_uInt16>(i+1), aBuf.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ String aNoDoc( FwkResId( STR_NODOCUMENT ) );
+ mpRecentMenu->InsertItem( 0xffff, aNoDoc );
+ }
+ maOpenButton.SetPopupMenu( mpRecentMenu );
+}
+
+void BackingWindow::initBackground()
+{
+ SetBackground();
+
+ bool bDark = GetSettings().GetStyleSettings().GetHighContrastMode();
+ if( bDark )
+ maWelcomeTextColor = maLabelTextColor = Color( COL_WHITE );
+ else if( mnLayoutStyle == 1 )
+ maWelcomeTextColor = maLabelTextColor = Color( COL_BLACK );
+ else
+ maWelcomeTextColor = maLabelTextColor = Color( 0x26, 0x35, 0x42 );
+
+ Color aTextBGColor( bDark ? COL_BLACK : COL_WHITE );
+
+ // select image set
+ ImageContainerRes aRes( FwkResId( RES_BACKING_IMAGES ) );
+
+ // scale middle segment
+ Size aMiddleSize;
+ if( !! maBackgroundMiddle )
+ aMiddleSize = maBackgroundMiddle.GetSizePixel();
+ // load middle segment
+
+ Application::LoadBrandBitmap ("shell/backing_space", maBackgroundMiddle);
+
+ // and scale it to previous size
+ if( aMiddleSize.Width() && aMiddleSize.Height() )
+ maBackgroundMiddle.Scale( aMiddleSize );
+
+ if( GetSettings().GetLayoutRTL() )
+ {
+ // replace images by RTL versions
+ Application::LoadBrandBitmap ("shell/backing_rtl_right", maBackgroundLeft);
+ Application::LoadBrandBitmap ("shell/backing_rtl_left", maBackgroundRight);
+ }
+ else
+ {
+ Application::LoadBrandBitmap ("shell/backing_left", maBackgroundLeft);
+ Application::LoadBrandBitmap ("shell/backing_right", maBackgroundRight);
+ }
+ maToolbox.SetItemImage( nItemId_Extensions, BitmapEx( FwkResId( BMP_BACKING_EXT ) ) );
+ maToolbox.SetItemImage( nItemId_Info, BitmapEx( FwkResId( BMP_BACKING_INFO ) ) );
+ maToolbox.SetItemImage( nItemId_TplRep, BitmapEx( FwkResId( BMP_BACKING_TPLREP ) ) );
+
+ maWelcome.SetControlForeground( maWelcomeTextColor );
+ maWelcome.SetBackground();
+ maProduct.SetControlForeground( maWelcomeTextColor );
+ maProduct.SetBackground();
+
+ if( mnLayoutStyle == 1 )
+ {
+ if( Application::GetSettings().GetLayoutRTL() )
+ mnBtnPos = maBackgroundRight.GetSizePixel().Width() + 40;
+ else
+ mnBtnPos = maBackgroundLeft.GetSizePixel().Width() + 40;
+ }
+
+ // get icon images from fwk resource and set them on the appropriate buttons
+ loadImage( FwkResId( BMP_BACKING_WRITER ), maWriterButton );
+ loadImage( FwkResId( BMP_BACKING_CALC ), maCalcButton );
+ loadImage( FwkResId( BMP_BACKING_IMPRESS ), maImpressButton );
+ loadImage( FwkResId( BMP_BACKING_DRAW ), maDrawButton );
+ loadImage( FwkResId( BMP_BACKING_DATABASE ), maDBButton );
+ loadImage( FwkResId( BMP_BACKING_FORMULA ), maMathButton );
+ loadImage( FwkResId( BMP_BACKING_OPENFILE ), maOpenButton );
+ loadImage( FwkResId( BMP_BACKING_OPENTEMPLATE ), maTemplateButton );
+
+ maOpenButton.SetMenuMode( MENUBUTTON_MENUMODE_TIMED );
+ maOpenButton.SetSelectHdl( LINK( this, BackingWindow, SelectHdl ) );
+ maOpenButton.SetActivateHdl( LINK( this, BackingWindow, ActivateHdl ) );
+}
+
+void BackingWindow::initControls()
+{
+ if( mbInitControls )
+ return;
+
+ mbInitControls = true;
+
+ // calculate dialog size
+ // begin with background bitmap
+ maControlRect = Rectangle( Point(), maBackgroundLeft.GetSizePixel() );
+ maControlRect.Left() += nShadowLeft;
+ maControlRect.Right() -= nShadowRight;
+ maControlRect.Top() += nShadowTop;
+ maControlRect.Bottom() -= nShadowBottom;
+
+ long nYPos = 0;
+ // set bigger welcome string
+ maWelcome.SetText( maWelcomeString );
+ maTextFont = GetSettings().GetStyleSettings().GetLabelFont();
+ maTextFont.SetSize( Size( 0, 18 ) );
+ maTextFont.SetWeight( WEIGHT_BOLD );
+ maWelcome.SetFont( maTextFont );
+ // get metric to get correct width factor and adjust
+ long nW = (maWelcome.GetFontMetric().GetWidth()*95)/100;
+ maTextFont.SetSize( Size( nW, 18 ) );
+
+ maWelcome.SetFont( maTextFont );
+ maWelcome.SetControlFont( maTextFont );
+ maWelcomeSize = Size( maWelcome.GetTextWidth( maWelcomeString ), maWelcome.GetTextHeight() );
+ maWelcomeSize.Width() = (maWelcomeSize.Width() * 20)/19;
+
+ nYPos += (maWelcomeSize.Height()*3)/2;
+
+ if( maControlRect.GetWidth() < mnBtnPos + maWelcomeSize.Width() + 20 )
+ maControlRect.Right() = maControlRect.Left() + maWelcomeSize.Width() + mnBtnPos + 20;
+
+ nYPos += maWelcomeSize.Height();
+
+ // set product string
+ maTextFont.SetSize( Size( 0, 30 ) );
+ maProduct.SetFont( maTextFont );
+
+ // get metric to get correct width factor and adjust
+ nW = (maProduct.GetFontMetric().GetWidth()*95)/100;
+ maTextFont.SetSize( Size( nW, 28 ) );
+
+ maProduct.SetFont( maTextFont );
+ maProduct.SetControlFont( maTextFont );
+ maProduct.SetText( maProductString );
+ maProductSize = Size( maProduct.GetTextWidth( maProductString ), maProduct.GetTextHeight() );
+ maProductSize.Width() = (maProductSize.Width() * 20)/19;
+
+ if( maControlRect.GetWidth() < maProductSize.Width() + mnBtnPos + 10 )
+ maControlRect.Right() = maControlRect.Left() + maProductSize.Width() + mnBtnPos + 10;
+
+ if( mnLayoutStyle == 1 )
+ {
+ maWelcome.Show();
+ maProduct.Show();
+ }
+
+ nYPos += (maProductSize.Height()*3)/2;
+
+ // set a slighly larger font than normal labels on the texts
+ maTextFont.SetSize( Size( 0, 11 ) );
+ maTextFont.SetWeight( WEIGHT_NORMAL );
+
+ // collect the URLs of the entries in the File/New menu
+ SvtModuleOptions aModuleOptions;
+ std::set< rtl::OUString > aFileNewAppsAvailable;
+ SvtDynamicMenuOptions aOpt;
+ Sequence < Sequence < PropertyValue > > aNewMenu = aOpt.GetMenu( E_NEWMENU );
+ const rtl::OUString sURLKey( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
+
+ const Sequence< PropertyValue >* pNewMenu = aNewMenu.getConstArray();
+ const Sequence< PropertyValue >* pNewMenuEnd = aNewMenu.getConstArray() + aNewMenu.getLength();
+ for ( ; pNewMenu != pNewMenuEnd; ++pNewMenu )
+ {
+ comphelper::SequenceAsHashMap aEntryItems( *pNewMenu );
+ rtl::OUString sURL( aEntryItems.getUnpackedValueOrDefault( sURLKey, rtl::OUString() ) );
+ if ( sURL.getLength() )
+ aFileNewAppsAvailable.insert( sURL );
+ }
+
+ // create mnemonics on the fly, preregister the mnemonics of the menu
+ MnemonicGenerator aMnemns;
+ maTemplateString = MnemonicGenerator::EraseAllMnemonicChars( maTemplateString );
+ maOpenString = MnemonicGenerator::EraseAllMnemonicChars( maOpenString );
+
+ SystemWindow* pSysWin = GetSystemWindow();
+ if( pSysWin )
+ {
+ MenuBar* pMBar = pSysWin->GetMenuBar();
+ if( pMBar )
+ {
+ for( sal_uInt16 i = 0; i < pMBar->GetItemCount(); i++ )
+ {
+ sal_uInt16 nItemId = pMBar->GetItemId( i );
+ String aItemText( pMBar->GetItemText( nItemId ) );
+ if( aItemText.Len() )
+ aMnemns.RegisterMnemonic( aItemText );
+ }
+ }
+ }
+
+ // layout the buttons
+ layoutButton( WRITER_URL, 0, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SWRITER,
+ maWriterButton, aMnemns );
+ layoutButton( DRAW_URL, 1, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SDRAW,
+ maDrawButton, aMnemns );
+ nYPos += maButtonImageSize.Height() + 10;
+ layoutButton( CALC_URL, 0, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SCALC,
+ maCalcButton, aMnemns );
+ layoutButton( BASE_URL, 1, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SDATABASE,
+ maDBButton, aMnemns );
+ nYPos += maButtonImageSize.Height() + 10;
+ layoutButton( IMPRESS_WIZARD_URL, 0, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SIMPRESS,
+ maImpressButton, aMnemns );
+ layoutButton( MATH_URL, 1, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SMATH,
+ maMathButton, aMnemns );
+
+ nYPos += 3*maButtonImageSize.Height() / 2;
+
+ layoutButton( NULL, 0, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SWRITER,
+ maOpenButton, aMnemns, maOpenString );
+ layoutButton( NULL, 1, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SWRITER,
+ maTemplateButton, aMnemns, maTemplateString );
+ nYPos += 10;
+
+ DBG_ASSERT( nYPos < maControlRect.GetHeight(), "misformatting !" );
+ if( mnColumnWidth[0] + mnColumnWidth[1] + mnBtnPos + 20 > maControlRect.GetWidth() )
+ maControlRect.Right() = maControlRect.Left() + mnColumnWidth[0] + mnColumnWidth[1] + mnBtnPos + 20;
+
+ mnTextColumnWidth[0] = mnColumnWidth[0];
+ mnTextColumnWidth[1] = mnColumnWidth[1];
+
+ if( mnTextColumnWidth[1] > mnTextColumnWidth[0] )
+ {
+ mnColumnWidth[0] = mnColumnWidth[1];
+ mnTextColumnWidth[0] = mnTextColumnWidth[1];
+ }
+ else
+ {
+ mnColumnWidth[1] = mnColumnWidth[0];
+ mnTextColumnWidth[1] = mnTextColumnWidth[0];
+ }
+ if( maControlRect.GetWidth() < maControlRect.GetHeight() * 3 / 2 )
+ {
+ maControlRect.Right() = maControlRect.Left() + maControlRect.GetHeight() * 3 / 2;
+ long nDelta = (maControlRect.GetWidth() - mnBtnPos - mnColumnWidth[1] - mnColumnWidth[0] - 20);
+ mnColumnWidth[0] += nDelta/2;
+ mnColumnWidth[1] += nDelta/2;
+ }
+
+ maToolbox.SetSelectHdl( LINK( this, BackingWindow, ToolboxHdl ) );
+ if( mnLayoutStyle == 0 )
+ maToolbox.Show();
+
+ // scale middle map to formatted width
+ Size aMiddleSegmentSize( maControlRect.GetSize().Width() + nShadowLeft + nShadowRight,
+ maBackgroundMiddle.GetSizePixel().Height() );
+
+ long nLW = maBackgroundLeft.GetSizePixel().Width();
+ long nRW = maBackgroundRight.GetSizePixel().Width();
+ if( aMiddleSegmentSize.Width() > nLW + nRW )
+ {
+ aMiddleSegmentSize.Width() -= nLW;
+ aMiddleSegmentSize.Width() -= nRW;
+ maBackgroundMiddle.Scale( aMiddleSegmentSize );
+ }
+ else
+ maBackgroundMiddle = BitmapEx();
+
+ Resize();
+
+ maWriterButton.GrabFocus();
+}
+
+void BackingWindow::loadImage( const ResId& i_rId, PushButton& i_rButton )
+{
+ BitmapEx aBmp( i_rId );
+ Size aImgSize( aBmp.GetSizePixel() );
+ if( aImgSize.Width() > maButtonImageSize.Width() )
+ maButtonImageSize.Width() = aImgSize.Width();
+ if( aImgSize.Height() > maButtonImageSize.Height() )
+ maButtonImageSize.Height() = aImgSize.Height();
+ i_rButton.SetModeImage( aBmp );
+}
+
+void BackingWindow::layoutButton(
+ const char* i_pURL, int nColumn,
+ const std::set<rtl::OUString>& i_rURLS,
+ SvtModuleOptions& i_rOpt, SvtModuleOptions::EModule i_eMod,
+ PushButton& i_rBtn,
+ MnemonicGenerator& i_rMnemns,
+ const String& i_rStr
+ )
+{
+ rtl::OUString aURL( i_pURL ? rtl::OUString::createFromAscii( i_pURL ) : rtl::OUString() );
+ // setup button
+ i_rBtn.SetPaintTransparent( sal_True );
+ i_rBtn.SetClickHdl( LINK( this, BackingWindow, ClickHdl ) );
+ if( i_pURL && (! i_rOpt.IsModuleInstalled( i_eMod ) || i_rURLS.find( aURL ) == i_rURLS.end()) )
+ {
+ i_rBtn.Enable( sal_False );
+ }
+
+ // setup text
+ i_rBtn.SetFont( maTextFont );
+ i_rBtn.SetControlFont( maTextFont );
+ String aText( i_rStr.Len() ? i_rStr : SvFileInformationManager::GetDescription( INetURLObject( aURL ) ) );
+ i_rMnemns.CreateMnemonic( aText );
+ i_rBtn.SetText( aText );
+
+ long nTextWidth = i_rBtn.GetTextWidth( i_rBtn.GetText() );
+
+ nTextWidth += maButtonImageSize.Width() + 8; // add some fuzz to be on the safe side
+ if( nColumn >= 0 && nColumn < static_cast<int>(SAL_N_ELEMENTS(mnColumnWidth)) )
+ {
+ if( nTextWidth > mnColumnWidth[nColumn] )
+ mnColumnWidth[nColumn] = nTextWidth;
+ }
+
+ i_rBtn.SetImageAlign( IMAGEALIGN_LEFT );
+ // show the controls
+ i_rBtn.Show();
+}
+
+void BackingWindow::Paint( const Rectangle& )
+{
+ Wallpaper aBack( GetSettings().GetStyleSettings().GetWorkspaceGradient() );
+ Region aClip( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) );
+ Rectangle aBmpRect(maControlRect);
+ aBmpRect.Left() -= nShadowLeft;
+ aBmpRect.Top() -= nShadowTop;
+ aBmpRect.Right() += nShadowRight;
+ aBmpRect.Bottom() += nShadowBottom;
+ aClip.Exclude( aBmpRect );
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( aClip );
+ DrawWallpaper( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ), aBack );
+ Pop();
+
+ VirtualDevice aDev( *this );
+ aDev.EnableRTL( IsRTLEnabled() );
+ aDev.SetOutputSizePixel( aBmpRect.GetSize() );
+ Point aOffset( Point( 0, 0 ) - aBmpRect.TopLeft() );
+ aDev.DrawWallpaper( Rectangle( aOffset, GetOutputSizePixel() ), aBack );
+
+ // draw bitmap
+ Point aTL( 0, 0 );
+ aDev.DrawBitmapEx( aTL, maBackgroundLeft );
+ aTL.X() += maBackgroundLeft.GetSizePixel().Width();
+ if( !!maBackgroundMiddle )
+ {
+ aDev.DrawBitmapEx( aTL, maBackgroundMiddle );
+ aTL.X() += maBackgroundMiddle.GetSizePixel().Width();
+ }
+ aDev.DrawBitmapEx( aTL, maBackgroundRight );
+
+ DrawOutDev( aBmpRect.TopLeft(), aBmpRect.GetSize(),
+ Point( 0, 0 ), aBmpRect.GetSize(),
+ aDev );
+}
+
+long BackingWindow::Notify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ if( ! mpAccExec )
+ {
+ mpAccExec = svt::AcceleratorExecute::createAcceleratorHelper();
+ mpAccExec->init( comphelper::getProcessServiceFactory(), mxFrame);
+ }
+
+ const KeyEvent* pEvt = rNEvt.GetKeyEvent();
+ const KeyCode& rKeyCode(pEvt->GetKeyCode());
+ if( pEvt && mpAccExec->execute(rKeyCode) )
+ return 1;
+ // #i110344# extrawurst: specialized arrow key control
+ if( rKeyCode.GetModifier() == 0 )
+ {
+ if( rKeyCode.GetCode() == KEY_RIGHT )
+ {
+ if( maWriterButton.HasFocus() )
+ maDrawButton.GrabFocus();
+ else if( maCalcButton.HasFocus() )
+ maDBButton.GrabFocus();
+ else if( maImpressButton.HasFocus() )
+ maMathButton.GrabFocus();
+ else if( maOpenButton.HasFocus() )
+ maTemplateButton.GrabFocus();
+ return 1;
+ }
+ else if( rKeyCode.GetCode() == KEY_LEFT )
+ {
+ if( maDrawButton.HasFocus() )
+ maWriterButton.GrabFocus();
+ else if( maDBButton.HasFocus() )
+ maCalcButton.GrabFocus();
+ else if( maMathButton.HasFocus() )
+ maImpressButton.GrabFocus();
+ else if( maTemplateButton.HasFocus() )
+ maOpenButton.GrabFocus();
+ return 1;
+ }
+ else if( rKeyCode.GetCode() == KEY_UP )
+ {
+ // first column
+ if( maOpenButton.HasFocus() )
+ maImpressButton.GrabFocus();
+ else if( maImpressButton.HasFocus() )
+ maCalcButton.GrabFocus();
+ else if( maCalcButton.HasFocus() )
+ maWriterButton.GrabFocus();
+ // second column
+ else if( maTemplateButton.HasFocus() )
+ maMathButton.GrabFocus();
+ else if( maMathButton.HasFocus() )
+ maDBButton.GrabFocus();
+ else if( maDBButton.HasFocus() )
+ maDrawButton.GrabFocus();
+ return 1;
+ }
+ else if( rKeyCode.GetCode() == KEY_DOWN )
+ {
+ // first column
+ if( maWriterButton.HasFocus() )
+ maCalcButton.GrabFocus();
+ else if( maCalcButton.HasFocus() )
+ maImpressButton.GrabFocus();
+ else if( maImpressButton.HasFocus() )
+ maOpenButton.GrabFocus();
+ // second column
+ else if( maDrawButton.HasFocus() )
+ maDBButton.GrabFocus();
+ else if( maDBButton.HasFocus() )
+ maMathButton.GrabFocus();
+ else if( maMathButton.HasFocus() )
+ maTemplateButton.GrabFocus();
+ return 1;
+ }
+ }
+ }
+ return Window::Notify( rNEvt );
+}
+
+void BackingWindow::setOwningFrame( const com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& xFrame )
+{
+ mxFrame = xFrame;
+ if( ! mbInitControls )
+ initControls();
+}
+
+void BackingWindow::Resize()
+{
+ Size aWindowSize( GetSizePixel() );
+ Size aControlSize = maControlRect.GetSize();
+ maControlRect = Rectangle( Point( (aWindowSize.Width() - aControlSize.Width()) / 2,
+ (aWindowSize.Height() - aControlSize.Height()) / 2 ),
+ aControlSize );
+
+ maToolbox.calcMinSize();
+ Size aTBSize( maToolbox.getMinSize() );
+ Point aTBPos( maControlRect.Left() + mnBtnPos,
+ maControlRect.Bottom() - aTBSize.Height() - 10 );
+ if( Application::GetSettings().GetLayoutRTL() )
+ aTBPos.X() = maControlRect.Right() - aTBSize.Width() - mnBtnPos;
+ maToolbox.SetPosSizePixel( aTBPos, aTBSize );
+
+ // #i93631# squeeze controls so they fit into the box
+ // this can be necessary due to application font height which has small deviations
+ // from the size set
+ const long nWDelta = maWelcomeSize.Height();
+ const long nW2Delta = (maWelcomeSize.Height()*3)/2;
+ const long nPDelta = (maProductSize.Height()*3)/2;
+ const long nBDelta = maButtonImageSize.Height() + 10;
+ const long nB2Delta = 3*maButtonImageSize.Height()/2;
+ const long nLastDelta = maButtonImageSize.Height();
+ long nDiff = 0;
+ while( ( maControlRect.Top() +
+ (nWDelta - nDiff) +
+ (nW2Delta- nDiff) +
+ (nPDelta - nDiff) +
+ 3 * (nBDelta - nDiff) +
+ (nB2Delta- nDiff) +
+ nLastDelta
+ ) > aTBPos.Y() )
+ {
+ nDiff++;
+ }
+
+ long nYPos = maControlRect.Top();
+ nYPos += nW2Delta - nDiff;
+ maWelcome.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ),
+ Size( maControlRect.GetWidth() - mnBtnPos - 5, (maWelcomeSize.Height()*20)/19 ) );
+ nYPos += nWDelta - nDiff;
+ maProduct.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( maControlRect.GetWidth() - mnBtnPos - 5, (maProductSize.Height()*20)/19 ) );
+ nYPos += nPDelta - nDiff;
+
+ nYPos += nWDelta/2 - nDiff;
+
+ if( mnLayoutStyle != 1 )
+ nYPos = maControlRect.Top() + mnBtnTop;
+
+ maWriterButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) );
+ maDrawButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) );
+ nYPos += nBDelta - nDiff;
+ maCalcButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) );
+ maDBButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) );
+ nYPos += nBDelta - nDiff;
+ maImpressButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) );
+ maMathButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) );
+
+ nYPos += nB2Delta - nDiff;
+ maOpenButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos, nYPos ), Size( mnTextColumnWidth[0], maButtonImageSize.Height() ) );
+ maTemplateButton.SetPosSizePixel( Point( maControlRect.Left() + mnBtnPos + mnColumnWidth[0], nYPos ), Size( mnTextColumnWidth[1], maButtonImageSize.Height() ) );
+}
+
+IMPL_LINK( BackingWindow, ToolboxHdl, void*, EMPTYARG )
+{
+ const char* pNodePath = NULL;
+ const char* pNode = NULL;
+
+ switch( maToolbox.GetCurItemId() )
+ {
+ case nItemId_Extensions:
+ pNodePath = "/org.openoffice.Office.Common/Help/StartCenter";
+ pNode = "AddFeatureURL";
+ break;
+ case nItemId_Reg:
+ try
+ {
+ // create the Desktop component which can load components
+ Reference < lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ if( xFactory.is() )
+ {
+ Reference< task::XJobExecutor > xProductRegistration(
+ xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.setup.ProductRegistration" ) ) ),
+ UNO_QUERY_THROW );
+
+ // tell it that the user wants to register
+ xProductRegistration->trigger( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RegistrationRequired" ) ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ }
+ break;
+ case nItemId_Info:
+ pNodePath = "/org.openoffice.Office.Common/Help/StartCenter";
+ pNode = "InfoURL";
+ break;
+ case nItemId_TplRep:
+ pNodePath = "/org.openoffice.Office.Common/Help/StartCenter";
+ pNode = "TemplateRepositoryURL";
+ break;
+ default:
+ break;
+ }
+ if( pNodePath && pNode )
+ {
+ try
+ {
+ Reference<lang::XMultiServiceFactory> xConfig( comphelper::getProcessServiceFactory()->createInstance(SERVICENAME_CFGPROVIDER),UNO_QUERY);
+ if( xConfig.is() )
+ {
+ Sequence<Any> args(1);
+ PropertyValue val(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("nodepath") ),
+ 0,
+ Any(rtl::OUString::createFromAscii(pNodePath)),
+ PropertyState_DIRECT_VALUE);
+ args.getArray()[0] <<= val;
+ Reference<container::XNameAccess> xNameAccess(xConfig->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,args), UNO_QUERY);
+ if( xNameAccess.is() )
+ {
+ rtl::OUString sURL;
+ //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
+ Any value( xNameAccess->getByName(rtl::OUString::createFromAscii(pNode)) );
+ sURL = value.get<rtl::OUString> ();
+ localizeWebserviceURI(sURL);
+
+ Reference< com::sun::star::system::XSystemShellExecute > xSystemShellExecute(
+ comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.system.SystemShellExecute" ) ) ),
+ UNO_QUERY_THROW);
+ //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException
+ xSystemShellExecute->execute( sURL, rtl::OUString(), com::sun::star::system::SystemShellExecuteFlags::DEFAULTS);
+ }
+ }
+ }
+ catch (Exception& )
+ {
+ }
+ }
+
+ return 0;
+}
+
+IMPL_LINK( BackingWindow, ClickHdl, Button*, pButton )
+{
+ // dispatch the appropriate URL and end the dialog
+ if( pButton == &maWriterButton )
+ dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(WRITER_URL) ) );
+ else if( pButton == &maCalcButton )
+ dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(CALC_URL) ) );
+ else if( pButton == &maImpressButton )
+ dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(IMPRESS_WIZARD_URL) ) );
+ else if( pButton == &maDrawButton )
+ dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(DRAW_URL) ) );
+ else if( pButton == &maDBButton )
+ dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(BASE_URL) ) );
+ else if( pButton == &maMathButton )
+ dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(MATH_URL) ) );
+ else if( pButton == &maOpenButton )
+ {
+ Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY );
+
+ Sequence< com::sun::star::beans::PropertyValue > aArgs(1);
+ PropertyValue* pArg = aArgs.getArray();
+ pArg[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer"));
+ pArg[0].Value <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:user"));
+
+ dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(OPEN_URL) ), rtl::OUString(), xFrame, aArgs );
+ }
+ else if( pButton == &maTemplateButton )
+ {
+ Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY );
+
+ Sequence< com::sun::star::beans::PropertyValue > aArgs(1);
+ PropertyValue* pArg = aArgs.getArray();
+ pArg[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer"));
+ pArg[0].Value <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:user"));
+
+ dispatchURL( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(TEMPLATE_URL) ), rtl::OUString(), xFrame, aArgs );
+ }
+ return 0;
+}
+
+IMPL_LINK( BackingWindow, SelectHdl, Button*, pButton )
+{
+ if( pButton == &maOpenButton )
+ {
+ sal_Int32 nItem = sal_Int32(maOpenButton.GetCurItemId())-1;
+ if( nItem >= 0 && nItem < sal_Int32(maRecentFiles.size()) )
+ {
+ Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY );
+ dispatchURL( maRecentFiles[nItem].aTargetURL, rtl::OUString(), xFrame, maRecentFiles[nItem].aArgSeq );
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK( BackingWindow, ActivateHdl, Button*, pButton )
+{
+ if( pButton == &maOpenButton )
+ prepareRecentFileMenu();
+ return 0;
+}
+
+struct ImplDelayedDispatch
+{
+ Reference< XDispatch > xDispatch;
+ com::sun::star::util::URL aDispatchURL;
+ Sequence< PropertyValue > aArgs;
+
+ ImplDelayedDispatch( const Reference< XDispatch >& i_xDispatch,
+ const com::sun::star::util::URL& i_rURL,
+ const Sequence< PropertyValue >& i_rArgs )
+ : xDispatch( i_xDispatch ),
+ aDispatchURL( i_rURL ),
+ aArgs( i_rArgs )
+ {
+ }
+ ~ImplDelayedDispatch() {}
+};
+
+static long implDispatchDelayed( void*, void* pArg )
+{
+ struct ImplDelayedDispatch* pDispatch = reinterpret_cast<ImplDelayedDispatch*>(pArg);
+ try
+ {
+ pDispatch->xDispatch->dispatch( pDispatch->aDispatchURL, pDispatch->aArgs );
+ }
+ catch( Exception )
+ {
+ }
+
+ // clean up
+ delete pDispatch;
+
+ return 0;
+}
+
+void BackingWindow::dispatchURL( const rtl::OUString& i_rURL,
+ const rtl::OUString& rTarget,
+ const Reference< XDispatchProvider >& i_xProv,
+ const Sequence< PropertyValue >& i_rArgs )
+{
+ // if no special dispatch provider is given, get the desktop
+ Reference< XDispatchProvider > xProvider( i_xProv.is() ? i_xProv : mxDesktopDispatchProvider );
+
+ // check for dispatch provider
+ if( !xProvider.is())
+ return;
+
+ // get an URL transformer to clean up the URL
+ com::sun::star::util::URL aDispatchURL;
+ aDispatchURL.Complete = i_rURL;
+
+ Reference < com::sun::star::util::XURLTransformer > xURLTransformer(
+ comphelper::getProcessServiceFactory()->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ),
+ com::sun::star::uno::UNO_QUERY );
+ if ( xURLTransformer.is() )
+ {
+ try
+ {
+ // clean up the URL
+ xURLTransformer->parseStrict( aDispatchURL );
+ // get a Dispatch for the URL and target
+ Reference< XDispatch > xDispatch(
+ xProvider->queryDispatch( aDispatchURL, rTarget, 0 )
+ );
+ // dispatch the URL
+ if ( xDispatch.is() )
+ {
+ ImplDelayedDispatch* pDisp = new ImplDelayedDispatch( xDispatch, aDispatchURL, i_rArgs );
+ sal_uLong nEventId = 0;
+ if( ! Application::PostUserEvent( nEventId, Link( NULL, implDispatchDelayed ), pDisp ) )
+ delete pDisp; // event could not be posted for unknown reason, at least don't leak
+ }
+ }
+ catch ( com::sun::star::uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/backingwindow.hxx b/framework/source/services/backingwindow.hxx
new file mode 100644
index 000000000000..5eebccb80c5f
--- /dev/null
+++ b/framework/source/services/backingwindow.hxx
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef FRAMEWORK_BACKINGWINDOW_HXX
+#define FRAMEWORK_BACKINGWINDOW_HXX
+
+#include "rtl/ustring.hxx"
+
+#include "vcl/button.hxx"
+#include "vcl/menubtn.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/bitmapex.hxx"
+#include "vcl/toolbox.hxx"
+
+#include "unotools/moduleoptions.hxx"
+#include "svtools/acceleratorexecute.hxx"
+
+#include "com/sun/star/frame/XDispatchProvider.hpp"
+#include "com/sun/star/frame/XDesktop.hpp"
+#include "com/sun/star/frame/XFrame.hpp"
+#include "com/sun/star/frame/XTerminateListener.hpp"
+#include "com/sun/star/document/XEventListener.hpp"
+#include "com/sun/star/document/XEventBroadcaster.hpp"
+#include "com/sun/star/util/XURLTransformer.hpp"
+#include "com/sun/star/ui/dialogs/XFilePicker.hpp"
+#include "com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp"
+#include "com/sun/star/ui/dialogs/XFilterManager.hpp"
+#include "com/sun/star/ui/dialogs/XFolderPicker.hpp"
+#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+
+#include <set>
+
+class MnemonicGenerator;
+
+namespace framework
+{
+ // To get the transparent mouse-over look, the closer is actually a toolbox
+ // overload DataChange to handle style changes correctly
+ class DecoToolBox : public ToolBox
+ {
+ Size maMinSize;
+
+ using Window::ImplInit;
+ public:
+ DecoToolBox( Window* pParent, WinBits nStyle = 0 );
+ DecoToolBox( Window* pParent, const ResId& rResId );
+
+ void DataChanged( const DataChangedEvent& rDCEvt );
+
+ void calcMinSize();
+ Size getMinSize();
+ };
+
+ class BackingWindow : public Window
+ {
+ struct LoadRecentFile
+ {
+ rtl::OUString aTargetURL;
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aArgSeq;
+ };
+
+ com::sun::star::uno::Reference<com::sun::star::frame::XDesktop> mxDesktop;
+ com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider > mxDesktopDispatchProvider;
+ com::sun::star::uno::Reference<com::sun::star::frame::XFrame> mxFrame;
+ com::sun::star::uno::Reference<com::sun::star::document::XEventBroadcaster> mxBroadcaster;
+
+ FixedText maWelcome;
+ Size maWelcomeSize;
+ FixedText maProduct;
+ Size maProductSize;
+ ImageButton maWriterButton;
+ ImageButton maCalcButton;
+ ImageButton maImpressButton;
+ MenuButton maOpenButton;
+ ImageButton maDrawButton;
+ ImageButton maDBButton;
+ ImageButton maMathButton;
+ ImageButton maTemplateButton;
+
+ DecoToolBox maToolbox;
+
+ BitmapEx maBackgroundLeft;
+ BitmapEx maBackgroundMiddle;
+ BitmapEx maBackgroundRight;
+
+ String maWelcomeString;
+ String maProductString;
+ String maCreateString;
+ String maOpenString;
+ String maTemplateString;
+
+ Font maTextFont;
+ Rectangle maControlRect;
+
+ long mnColumnWidth[2];
+ long mnTextColumnWidth[2];
+ Color maLabelTextColor;
+ Color maWelcomeTextColor;
+
+ Size maButtonImageSize;
+
+ bool mbInitControls;
+ sal_Int32 mnLayoutStyle;
+ svt::AcceleratorExecute* mpAccExec;
+ long mnBtnPos;
+ long mnBtnTop;
+
+ PopupMenu* mpRecentMenu;
+ std::vector< LoadRecentFile > maRecentFiles;
+
+ static const int nItemId_Extensions = 1;
+ static const int nItemId_Reg = 2;
+ static const int nItemId_Info = 3;
+ static const int nItemId_TplRep = 4;
+ static const int nShadowTop = 32;
+ static const int nShadowLeft = 35;
+ static const int nShadowRight = 45;
+ static const int nShadowBottom = 50;
+
+ void loadImage( const ResId& i_rId, PushButton& i_rButton );
+
+ void layoutButton( const char* i_pURL, int nColumn, const std::set<rtl::OUString>& i_rURLS,
+ SvtModuleOptions& i_rOpt, SvtModuleOptions::EModule i_eMod,
+ PushButton& i_rBtn,
+ MnemonicGenerator& i_rMnemonicGen,
+ const String& i_rStr = String()
+ );
+
+ void dispatchURL( const rtl::OUString& i_rURL,
+ const rtl::OUString& i_rTarget = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ),
+ const com::sun::star::uno::Reference< com::sun::star::frame::XDispatchProvider >& i_xProv = com::sun::star::uno::Reference< com::sun::star::frame::XDispatchProvider >(),
+ const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& = com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >()
+ );
+
+ DECL_LINK( ClickHdl, Button* );
+ DECL_LINK( SelectHdl, Button* );
+ DECL_LINK( ActivateHdl, Button* );
+ DECL_LINK( ToolboxHdl, void* );
+
+ void initControls();
+ void initBackground();
+ void prepareRecentFileMenu();
+ public:
+ BackingWindow( Window* pParent );
+ ~BackingWindow();
+
+ virtual void Paint( const Rectangle& rRect );
+ virtual void Resize();
+ virtual long Notify( NotifyEvent& rNEvt );
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+ virtual void GetFocus();
+
+ void setOwningFrame( const com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& xFrame );
+ };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/desktop.cxx b/framework/source/services/desktop.cxx
new file mode 100644
index 000000000000..60ebf97da0e8
--- /dev/null
+++ b/framework/source/services/desktop.cxx
@@ -0,0 +1,2036 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <loadenv/loadenv.hxx>
+
+#include <loadenv/targethelper.hxx>
+
+#include <services/desktop.hxx>
+#include <helper/ocomponentaccess.hxx>
+#include <dispatch/dispatchprovider.hxx>
+
+#include <dispatch/interceptionhelper.hxx>
+#include <classes/taskcreator.hxx>
+#include <threadhelp/transactionguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <services.h>
+#include <general.h>
+#include <properties.h>
+
+#include <classes/resource.hrc>
+#include <classes/fwkresid.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/awt/XToolkit.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/awt/WindowDescriptor.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/document/XInteractionFilterSelect.hpp>
+#include <com/sun/star/document/AmbigousFilterRequest.hpp>
+#include <com/sun/star/task/ErrorCodeRequest.hpp>
+#include <com/sun/star/ucb/InteractiveIOException.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+#include <com/sun/star/frame/XNotifyingDispatch.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/document/MacroExecMode.hpp>
+#include <com/sun/star/document/UpdateDocMode.hpp>
+#include <com/sun/star/frame/XTerminateListener2.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/proptypehlp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+#include <vcl/svapp.hxx>
+
+#ifndef __RSC
+#include <tools/errinf.hxx>
+#endif
+#include <comphelper/extract.hxx>
+
+#include <fwkdllapi.h>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_15 ( Desktop ,
+ OWeakObject ,
+ DIRECT_INTERFACE( css::lang::XTypeProvider ),
+ DIRECT_INTERFACE( css::lang::XServiceInfo ),
+ DIRECT_INTERFACE( css::frame::XDesktop ),
+ DIRECT_INTERFACE( css::frame::XComponentLoader ),
+ DIRECT_INTERFACE( css::frame::XTasksSupplier ),
+ DIRECT_INTERFACE( css::frame::XDispatchProvider ),
+ DIRECT_INTERFACE( css::frame::XDispatchProviderInterception),
+ DIRECT_INTERFACE( css::frame::XFramesSupplier ),
+ DIRECT_INTERFACE( css::frame::XFrame ),
+ DIRECT_INTERFACE( css::lang::XComponent ),
+ DIRECT_INTERFACE( css::frame::XDispatchResultListener ),
+ DIRECT_INTERFACE( css::lang::XEventListener ),
+ DIRECT_INTERFACE( css::task::XInteractionHandler ),
+ DIRECT_INTERFACE( css::beans::XPropertySet ),
+ DIRECT_INTERFACE( css::frame::XUntitledNumbers )
+ )
+
+DEFINE_XTYPEPROVIDER_15 ( Desktop ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::frame::XDesktop ,
+ css::frame::XComponentLoader ,
+ css::frame::XTasksSupplier ,
+ css::frame::XDispatchProvider ,
+ css::frame::XDispatchProviderInterception ,
+ css::frame::XFramesSupplier ,
+ css::frame::XFrame ,
+ css::lang::XComponent ,
+ css::frame::XDispatchResultListener ,
+ css::lang::XEventListener ,
+ css::task::XInteractionHandler ,
+ css::beans::XPropertySet ,
+ css::frame::XUntitledNumbers
+ )
+
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( Desktop ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_DESKTOP ,
+ IMPLEMENTATIONNAME_DESKTOP
+ )
+
+DEFINE_INIT_SERVICE ( Desktop,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a new XFrames-helper-object to handle XIndexAccess and XElementAccess.
+ // We hold member as reference ... not as pointer too!
+ // Attention: We share our frame container with this helper. Container is threadsafe himself ... So I think we can do that.
+ // But look on dispose() for right order of deinitialization.
+ OFrames* pFramesHelper = new OFrames( m_xFactory, this, &m_aChildTaskContainer );
+ m_xFramesHelper = css::uno::Reference< css::frame::XFrames >( static_cast< ::cppu::OWeakObject* >(pFramesHelper), css::uno::UNO_QUERY );
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a new dispatchhelper-object to handle dispatches.
+ // We use these helper as slave for our interceptor helper ... not directly!
+ // But he is event listener on THIS instance!
+ DispatchProvider* pDispatchHelper = new DispatchProvider( m_xFactory, this );
+ css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( static_cast< ::cppu::OWeakObject* >(pDispatchHelper), css::uno::UNO_QUERY );
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a new interception helper object to handle dispatches and implement an interceptor mechanism.
+ // Set created dispatch provider as slowest slave of it.
+ // Hold interception helper by reference only - not by pointer!
+ // So it's easiear to destroy it.
+ InterceptionHelper* pInterceptionHelper = new InterceptionHelper( this, xDispatchProvider );
+ m_xDispatchHelper = css::uno::Reference< css::frame::XDispatchProvider >( static_cast< ::cppu::OWeakObject* >(pInterceptionHelper), css::uno::UNO_QUERY );
+
+ ::rtl::OUStringBuffer sUntitledPrefix (256);
+ sUntitledPrefix.append (::rtl::OUString( String( FwkResId( STR_UNTITLED_DOCUMENT ))));
+ sUntitledPrefix.appendAscii (" ");
+
+ ::comphelper::NumberedCollection* pNumbers = new ::comphelper::NumberedCollection ();
+ m_xTitleNumberGenerator = css::uno::Reference< css::frame::XUntitledNumbers >(static_cast< ::cppu::OWeakObject* >(pNumbers), css::uno::UNO_QUERY_THROW);
+ pNumbers->setOwner ( static_cast< ::cppu::OWeakObject* >(this) );
+ pNumbers->setUntitledPrefix ( sUntitledPrefix.makeStringAndClear () );
+
+ // Safe impossible cases
+ // We can't work without this helper!
+ LOG_ASSERT2( m_xFramesHelper.is ()==sal_False, "Desktop::Desktop()", "Frames helper is not valid. XFrames, XIndexAccess and XElementAcces are not supported!\n")
+ LOG_ASSERT2( m_xDispatchHelper.is()==sal_False, "Desktop::Desktop()", "Dispatch helper is not valid. XDispatch will not work correctly!\n" )
+
+ // Enable object for real working!
+ // Otherwise all calls will be rejected ...
+ m_aTransactionManager.setWorkingMode( E_WORK );
+ }
+ )
+
+/*-************************************************************************************************************//**
+ @short standard constructor to create instance by factory
+ @descr This constructor initialize a new instance of this class by valid factory,
+ and will be set valid values on his member and baseclasses.
+
+ @attention a) Don't use your own reference during an UNO-Service-ctor! There is no guarantee, that you
+ will get over this. (e.g. using of your reference as parameter to initialize some member)
+ Do such things in DEFINE_INIT_SERVICE() method, which is called automaticly after your ctor!!!
+ b) Baseclass OBroadcastHelper is a typedef in namespace cppu!
+ The microsoft compiler has some problems to handle it right BY using namespace explicitly ::cppu::OBroadcastHelper.
+ If we write it without a namespace or expand the typedef to OBrodcastHelperVar<...> -> it will be OK!?
+ I don't know why! (other compiler not tested .. but it works!)
+
+ @seealso method DEFINE_INIT_SERVICE()
+
+ @param "xFactory" is the multi service manager, which create this instance.
+ The value must be different from NULL!
+ @return -
+
+ @onerror We throw an ASSERT in debug version or do nothing in relaese version.
+*//*-*************************************************************************************************************/
+Desktop::Desktop( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+ // Init baseclasses first
+ // Attention: Don't change order of initialization!
+ // ThreadHelpBase is a struct with a lock as member. We can't use a lock as direct member!
+ // We must garant right initialization and a valid value of this to initialize other baseclasses!
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , TransactionBase ( )
+ , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType > ( m_aLock.getShareableOslMutex() )
+ , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
+ , ::cppu::OWeakObject ( )
+ // Init member
+ #ifdef ENABLE_ASSERTIONS
+ , m_bIsTerminated ( sal_False ) // see dispose() for further informations!
+ #endif
+ , m_xFactory ( xFactory )
+ , m_aChildTaskContainer ( )
+ , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
+ , m_xFramesHelper ( )
+ , m_xDispatchHelper ( )
+ , m_eLoadState ( E_NOTSET )
+ , m_xLastFrame ( )
+ , m_aInteractionRequest ( )
+ , m_bSuspendQuickstartVeto( sal_False )
+ , m_aCommandOptions ( )
+ , m_sName ( )
+ , m_sTitle ( )
+ , m_xDispatchRecorderSupplier( )
+ , m_xPipeTerminator ( )
+ , m_xQuickLauncher ( )
+ , m_xSWThreadManager ( )
+ , m_xSfxTerminator ( )
+ , m_xTitleNumberGenerator ( )
+{
+ // Safe impossible cases
+ // We don't accept all incoming parameter.
+ LOG_ASSERT2( implcp_ctor( xFactory ), "Desktop::Desktop()", "Invalid parameter detected!")
+}
+
+/*-************************************************************************************************************//**
+ @short standard destructor
+ @descr This one do NOTHING! Use dispose() instaed of this.
+
+ @seealso method dispose()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*************************************************************************************************************/
+Desktop::~Desktop()
+{
+#ifdef ENABLE_ASSERTIONS
+ // Perhaps we should here do use a real assertion, but make the
+ // condition more specific? We don't want it to fire in unit tests
+ // in sc/qa/unit for instance, that don't even have any GUI.
+ if( !m_bIsTerminated )
+ fprintf( stderr, "This used to be an assertion failure: Desktop not terminated before being destructed,\n"
+ "but it is probably not a real problem.\n" );
+#endif
+ LOG_ASSERT2( m_aTransactionManager.getWorkingMode()!=E_CLOSE , "Desktop::~Desktop()", "Who forgot to dispose this service?" )
+}
+
+//=============================================================================
+sal_Bool SAL_CALL Desktop::terminate()
+ throw( css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ SYNCHRONIZED_START
+ ReadGuard aReadLock( m_aLock );
+
+ css::uno::Reference< css::frame::XTerminateListener > xPipeTerminator = m_xPipeTerminator;
+ css::uno::Reference< css::frame::XTerminateListener > xQuickLauncher = m_xQuickLauncher;
+ css::uno::Reference< css::frame::XTerminateListener > xSWThreadManager = m_xSWThreadManager;
+ css::uno::Reference< css::frame::XTerminateListener > xSfxTerminator = m_xSfxTerminator;
+
+ css::lang::EventObject aEvent ( static_cast< ::cppu::OWeakObject* >(this) );
+ ::sal_Bool bAskQuickStart = !m_bSuspendQuickstartVeto ;
+
+ aReadLock.unlock();
+ SYNCHRONIZED_END
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Ask normal terminate listener. They could stop terminate without closing any open document.
+ Desktop::TTerminateListenerList lCalledTerminationListener;
+ ::sal_Bool bVeto = sal_False;
+ impl_sendQueryTerminationEvent(lCalledTerminationListener, bVeto);
+ if ( bVeto )
+ {
+ impl_sendCancelTerminationEvent(lCalledTerminationListener);
+ return sal_False;
+ }
+
+ //-------------------------------------------------------------------------------------------------------------
+ // try to close all open frames.
+ // Allow using of any UI ... because Desktop.terminate() was designed as UI functionality in the past.
+ ::sal_Bool bAllowUI = sal_True;
+ ::sal_Bool bFramesClosed = impl_closeFrames(bAllowUI);
+ if ( ! bFramesClosed )
+ {
+ impl_sendCancelTerminationEvent(lCalledTerminationListener);
+ return sal_False;
+ }
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Normal listener had no problem ...
+ // all frames was closed ...
+ // now it's time to ask our specialized listener.
+ // They are handled these way because they wish to hinder the office on termination
+ // but they wish also closing of all frames.
+
+ // Note further:
+ // We shouldn't ask quicklauncher in case it was allowed from outside only.
+ // This is special trick to "ignore existing quick starter" for debug purposes.
+
+ // Attention:
+ // Order of alled listener is important !
+ // some of them are harmless .-)
+ // But some of them can be dangerous. E.g. it would be dangerous if we close our pipe
+ // and dont terminate in real because another listener throws a veto exception .-)
+
+ ::sal_Bool bTerminate = sal_False;
+ try
+ {
+ if(
+ ( bAskQuickStart ) &&
+ ( xQuickLauncher.is() )
+ )
+ {
+ xQuickLauncher->queryTermination( aEvent );
+ lCalledTerminationListener.push_back( xQuickLauncher );
+ }
+
+ if ( xSWThreadManager.is() )
+ {
+ xSWThreadManager->queryTermination( aEvent );
+ lCalledTerminationListener.push_back( xSWThreadManager );
+ }
+
+ if ( xPipeTerminator.is() )
+ {
+ xPipeTerminator->queryTermination( aEvent );
+ lCalledTerminationListener.push_back( xPipeTerminator );
+ }
+
+ if ( xSfxTerminator.is() )
+ {
+ xSfxTerminator->queryTermination( aEvent );
+ lCalledTerminationListener.push_back( xSfxTerminator );
+ }
+
+ bTerminate = sal_True;
+ }
+ catch(const css::frame::TerminationVetoException&)
+ {
+ bTerminate = sal_False;
+ }
+
+ if ( ! bTerminate )
+ impl_sendCancelTerminationEvent(lCalledTerminationListener);
+ else
+ {
+ #ifdef ENABLE_ASSERTIONS
+ // "Protect" us against dispose before terminate calls!
+ // see dispose() for further informations.
+ /* SAFE AREA --------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ m_bIsTerminated = sal_True;
+ aWriteLock.unlock();
+ /* UNSAFE AREA ------------------------------------------------------------------------------------- */
+ #endif
+
+ impl_sendNotifyTerminationEvent();
+
+ if(
+ ( bAskQuickStart ) &&
+ ( xQuickLauncher.is() )
+ )
+ {
+ xQuickLauncher->notifyTermination( aEvent );
+ }
+
+ if ( xSWThreadManager.is() )
+ xSWThreadManager->notifyTermination( aEvent );
+
+ if ( xPipeTerminator.is() )
+ xPipeTerminator->notifyTermination( aEvent );
+
+ // Must be realy the last listener to be called.
+ // Because it shutdown the whole process asynchronous !
+ if ( xSfxTerminator.is() )
+ xSfxTerminator->notifyTermination( aEvent );
+ }
+
+ return bTerminate;
+}
+
+
+//=============================================================================
+void SAL_CALL Desktop::addTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener )
+ throw( css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ css::uno::Reference< css::lang::XServiceInfo > xInfo( xListener, css::uno::UNO_QUERY );
+ if ( xInfo.is() )
+ {
+ ::rtl::OUString sImplementationName = xInfo->getImplementationName();
+
+ // SYCNHRONIZED ->
+ WriteGuard aWriteLock( m_aLock );
+
+ if( sImplementationName.equals(IMPLEMENTATIONNAME_SFXTERMINATOR) )
+ {
+ m_xSfxTerminator = xListener;
+ return;
+ }
+ if( sImplementationName.equals(IMPLEMENTATIONNAME_PIPETERMINATOR) )
+ {
+ m_xPipeTerminator = xListener;
+ return;
+ }
+ if( sImplementationName.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER) )
+ {
+ m_xQuickLauncher = xListener;
+ return;
+ }
+ if( sImplementationName.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER) )
+ {
+ m_xSWThreadManager = xListener;
+ return;
+ }
+
+ aWriteLock.unlock();
+ // <- SYCNHRONIZED
+ }
+
+ // No lock required ... container is threadsafe by itself.
+ m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ), xListener );
+}
+
+//=============================================================================
+void SAL_CALL Desktop::removeTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener )
+ throw( css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ css::uno::Reference< css::lang::XServiceInfo > xInfo( xListener, css::uno::UNO_QUERY );
+ if ( xInfo.is() )
+ {
+ ::rtl::OUString sImplementationName = xInfo->getImplementationName();
+
+ // SYCNHRONIZED ->
+ WriteGuard aWriteLock( m_aLock );
+
+ if( sImplementationName.equals(IMPLEMENTATIONNAME_SFXTERMINATOR) )
+ {
+ m_xSfxTerminator.clear();
+ return;
+ }
+
+ if( sImplementationName.equals(IMPLEMENTATIONNAME_PIPETERMINATOR) )
+ {
+ m_xPipeTerminator.clear();
+ return;
+ }
+
+ if( sImplementationName.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER) )
+ {
+ m_xQuickLauncher.clear();
+ return;
+ }
+
+ if( sImplementationName.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER) )
+ {
+ m_xSWThreadManager.clear();
+ return;
+ }
+
+ aWriteLock.unlock();
+ // <- SYCNHRONIZED
+ }
+
+ // No lock required ... container is threadsafe by itself.
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ), xListener );
+}
+
+/*-************************************************************************************************************//**
+ @interface XDesktop
+ @short get access to create enumerations of all current components
+ @descr You will be the owner of the returned object and must delete it if you don't use it again.
+
+ @seealso class TasksAccess
+ @seealso class TasksEnumeration
+
+ @param -
+ @return A reference to an XEnumerationAccess-object.
+
+ @onerror We return a null-reference.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL Desktop::getComponents() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // We use a helper class OComponentAccess to have access on all child components.
+ // Create it on demand and return it as a reference.
+ OComponentAccess* pAccess = new OComponentAccess( this );
+ css::uno::Reference< css::container::XEnumerationAccess > xAccess( static_cast< ::cppu::OWeakObject* >(pAccess), css::uno::UNO_QUERY );
+ return xAccess;
+}
+
+/*-************************************************************************************************************//**
+ @interface XDesktop
+ @short return the current active component
+ @descr The most current component is the window, model or the controller of the current active frame.
+
+ @seealso method getCurrentFrame()
+ @seealso method impl_getFrameComponent()
+
+ @param -
+ @return A reference to the component.
+
+ @onerror We return a null-reference.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::lang::XComponent > SAL_CALL Desktop::getCurrentComponent() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Set return value if method failed.
+ css::uno::Reference< css::lang::XComponent > xComponent;
+
+ // Get reference to current frame ...
+ // ... get component of this frame ... (It can be the window, the model or the controller.)
+ // ... and return the result.
+ css::uno::Reference< css::frame::XFrame > xCurrentFrame = getCurrentFrame();
+ if( xCurrentFrame.is() == sal_True )
+ {
+ xComponent = impl_getFrameComponent( xCurrentFrame );
+ }
+ return xComponent;
+}
+
+/*-************************************************************************************************************//**
+ @interface XDesktop
+ @short return the current active frame in hierarchy
+ @descr There can be more then one different active pathes in our frame hierarchy. But only one of them
+ could be the most active frame (normal he has the focus).
+ Don't mix it with getActiveFrame()! That will return our current active frame, which must be
+ a direct child of us and should be a part(!) of an active path.
+
+ @seealso method getActiveFrame()
+
+ @param -
+ @return A valid reference, if there is an active frame.
+ A null reference , otherwise.
+
+ @onerror We return a null reference.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::getCurrentFrame() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Start search with ouer direct active frame (if it exist!).
+ // Search on his children for other active frames too.
+ // Stop if no one could be found and return last of found ones.
+ css::uno::Reference< css::frame::XFramesSupplier > xLast = css::uno::Reference< css::frame::XFramesSupplier >( getActiveFrame(), css::uno::UNO_QUERY );
+ if( xLast.is() == sal_True )
+ {
+ css::uno::Reference< css::frame::XFramesSupplier > xNext = css::uno::Reference< css::frame::XFramesSupplier >( xLast->getActiveFrame(), css::uno::UNO_QUERY );
+ while( xNext.is() == sal_True )
+ {
+ xLast = xNext;
+ xNext = css::uno::Reference< css::frame::XFramesSupplier >( xNext->getActiveFrame(), css::uno::UNO_QUERY );
+ }
+ }
+ return css::uno::Reference< css::frame::XFrame >( xLast, css::uno::UNO_QUERY );
+}
+
+/*-************************************************************************************************************//**
+ @interface XComponentLoader
+ @short try to load given URL into a task
+ @descr You can give us some informations about the content, which you will load into a frame.
+ We search or create this target for you, make a type detection of given URL and try to load it.
+ As result of this operation we return the new created component or nothing, if loading failed.
+
+ @seealso -
+
+ @param "sURL" , URL, which represant the content
+ @param "sTargetFrameName" , name of target frame or special value like "_self", "_blank" ...
+ @param "nSearchFlags" , optional arguments for frame search, if target isn't a special one
+ @param "lArguments" , optional arguments for loading
+ @return A valid component reference, if loading was successfully.
+ A null reference otherwise.
+
+ @onerror We return a null reference.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::lang::XComponent > SAL_CALL Desktop::loadComponentFromURL( const ::rtl::OUString& sURL ,
+ const ::rtl::OUString& sTargetFrameName,
+ sal_Int32 nSearchFlags ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::io::IOException ,
+ css::lang::IllegalArgumentException ,
+ css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::Desktop::loadComponentFromURL" );
+
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XComponentLoader > xThis(static_cast< css::frame::XComponentLoader* >(this), css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xFactory;
+ aReadLock.unlock();
+
+ RTL_LOGFILE_PRODUCT_CONTEXT( aLog2, "PERFORMANCE - Desktop::loadComponentFromURL()" );
+ return LoadEnv::loadComponentFromURL(xThis, xSMGR, sURL, sTargetFrameName, nSearchFlags, lArguments);
+}
+
+/*-************************************************************************************************************//**
+ @interface XTasksSupplier
+ @short get access to create enumerations of ouer taskchilds
+ @descr Direct childs of desktop are tasks everytime.
+ Call these method to could create enumerations of it.
+
+But; Don't forget - you will be the owner of returned object and must release it!
+ We use a helper class to implement the access interface. They hold a weakreference to us.
+ It can be, that the desktop is dead - but not your tasksaccess-object! Then they will do nothing!
+ You can't create enumerations then.
+
+ @attention Normaly we don't need any lock here. We don't work on internal member!
+
+ @seealso class TasksAccess
+
+ @param -
+ @return A reference to an accessobject, which can create enumerations of ouer childtasks.
+
+ @onerror A null reference is returned.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL Desktop::getTasks() throw( css::uno::RuntimeException )
+{
+ LOG_WARNING("Desktop::getTasks()", "Use of obsolete interface XTaskSupplier")
+ return NULL;
+}
+
+/*-************************************************************************************************************//**
+ @interface XTasksSupplier
+ @short return current active task of ouer direct childs
+ @descr Desktop childs are tasks only ! If we have an active path from desktop
+ as top to any frame on bottom, we must have an active direct child. His reference is returned here.
+
+ @attention a) Do not confuse it with getCurrentFrame()! The current frame don't must one of ouer direct childs.
+ It can be every frame in subtree and must have the focus (Is the last one of an active path!).
+ b) We don't need any lock here. Our container is threadsafe himself and live, if we live!
+
+ @seealso method getCurrentFrame()
+
+ @param -
+ @return A reference to ouer current active taskchild.
+
+ @onerror A null reference is returned.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::frame::XTask > SAL_CALL Desktop::getActiveTask() throw( css::uno::RuntimeException )
+{
+ LOG_WARNING("Desktop::getActiveTask()", "Use of obsolete interface XTaskSupplier")
+ return NULL;
+}
+
+/*-************************************************************************************************************//**
+ @interface XDispatchProvider
+ @short search a dispatcher for given URL
+ @descr We use a helper implementation (class DispatchProvider) to do so.
+ So we don't must implement this algorithm twice!
+
+ @attention We don't need any lock here. Our helper is threadsafe himself and live, if we live!
+
+ @seealso class DispatchProvider
+
+ @param "aURL" , URL to dispatch
+ @param "sTargetFrameName" , name of target frame, who should dispatch these URL
+ @param "nSearchFlags" , flags to regulate the search
+ @param "lQueries" , list of queryDispatch() calls!
+ @return A reference or list of founded dispatch objects for these URL.
+
+ @onerror A null reference is returned.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::frame::XDispatch > SAL_CALL Desktop::queryDispatch( const css::util::URL& aURL ,
+ const ::rtl::OUString& sTargetFrameName ,
+ sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
+{
+ const char UNO_PROTOCOL[] = ".uno:";
+
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Remove uno and cmd protocol part as we want to support both of them. We store only the command part
+ // in our hash map. All other protocols are stored with the protocol part.
+ String aCommand( aURL.Main );
+ if ( aURL.Protocol.equalsIgnoreAsciiCaseAsciiL( UNO_PROTOCOL, sizeof( UNO_PROTOCOL )-1 ))
+ aCommand = aURL.Path;
+
+ // Make boost::unordered_map lookup if the current URL is in the disabled list
+ if ( m_aCommandOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aCommand ) )
+ return css::uno::Reference< css::frame::XDispatch >();
+ else
+ {
+ // We use a helper to support these interface and an interceptor mechanism.
+ // Our helper is threadsafe by himself!
+ return m_xDispatchHelper->queryDispatch( aURL, sTargetFrameName, nSearchFlags );
+ }
+}
+
+//*****************************************************************************************************************
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL Desktop::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lQueries ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ return m_xDispatchHelper->queryDispatches( lQueries );
+}
+
+/*-************************************************************************************************************//**
+ @interface XDipsatchProviderInterception
+ @short supports registration/deregistration of interception objects, which
+ are interested on special dispatches.
+
+ @descr Its realy provided by an internal helper, which is used inside the dispatch api too.
+ @param xInterceptor
+ the interceptor object, which wish to be (de)registered.
+
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+void SAL_CALL Desktop::registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
+ throw( css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
+ xInterceptionHelper->registerDispatchProviderInterceptor( xInterceptor );
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Desktop::releaseDispatchProviderInterceptor ( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
+ throw( css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
+ xInterceptionHelper->releaseDispatchProviderInterceptor( xInterceptor );
+}
+
+/*-************************************************************************************************************//**
+ @interface XFramesSupplier
+ @short return access to append or remove childs on desktop
+ @descr We don't implement these interface directly. We use a helper class to do this.
+ If you wish to add or delete childs to/from the container, call these method to get
+ a reference to the helper.
+
+ @attention Helper is threadsafe himself. So we don't need any lock here.
+
+ @seealso class OFrames
+
+ @param -
+ @return A reference to the helper.
+
+ @onerror A null reference is returned.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::frame::XFrames > SAL_CALL Desktop::getFrames() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ return m_xFramesHelper;
+}
+
+/*-************************************************************************************************************//**
+ @interface XFramesSupplier
+ @short set/get the current active child frame
+ @descr It must be a task. Direct childs of desktop are tasks only! No frames are accepted.
+ We don't save this information directly in this class. We use ouer container-helper
+ to do that.
+
+ @attention Helper is threadsafe himself. So we don't need any lock here.
+
+ @seealso class OFrameContainer
+
+ @param "xFrame", new active frame (must be valid!)
+ @return A reference to ouer current active childtask, if anyone exist.
+
+ @onerror A null reference is returned.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+void SAL_CALL Desktop::setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Get old active frame first.
+ // If nothing will change - do nothing!
+ // Otherwise set new active frame ...
+ // and deactivate last frame.
+ // It's neccessary for our FrameActionEvent listener on a frame!
+ css::uno::Reference< css::frame::XFrame > xLastActiveChild = m_aChildTaskContainer.getActive();
+ if( xLastActiveChild != xFrame )
+ {
+ m_aChildTaskContainer.setActive( xFrame );
+ if( xLastActiveChild.is() == sal_True )
+ {
+ xLastActiveChild->deactivate();
+ }
+ }
+}
+
+//*****************************************************************************************************************
+css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::getActiveFrame() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ return m_aChildTaskContainer.getActive();
+}
+
+/*-************************************************************************************************************//**
+ @interface XFrame
+ @short non implemented methods!
+ @descr Some method make no sense for our desktop! He has no window or parent or ...
+ So we should implement it empty and warn programmer, if he use it!
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ @threadsafe -
+*//*-*************************************************************************************************************/
+void SAL_CALL Desktop::initialize( const css::uno::Reference< css::awt::XWindow >& ) throw( css::uno::RuntimeException )
+{
+}
+
+//*****************************************************************************************************************
+css::uno::Reference< css::awt::XWindow > SAL_CALL Desktop::getContainerWindow() throw( css::uno::RuntimeException )
+{
+ return css::uno::Reference< css::awt::XWindow >();
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Desktop::setCreator( const css::uno::Reference< css::frame::XFramesSupplier >& /*xCreator*/ ) throw( css::uno::RuntimeException )
+{
+}
+
+//*****************************************************************************************************************
+css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL Desktop::getCreator() throw( css::uno::RuntimeException )
+{
+ return css::uno::Reference< css::frame::XFramesSupplier >();
+}
+
+//*****************************************************************************************************************
+::rtl::OUString SAL_CALL Desktop::getName() throw( css::uno::RuntimeException )
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ return m_sName;
+ /* } SAFE */
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Desktop::setName( const ::rtl::OUString& sName ) throw( css::uno::RuntimeException )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_sName = sName;
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+//*****************************************************************************************************************
+sal_Bool SAL_CALL Desktop::isTop() throw( css::uno::RuntimeException )
+{
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Desktop::activate() throw( css::uno::RuntimeException )
+{
+ // Desktop is activae always ... but sometimes our frames try to activate
+ // the complete path from bottom to top ... And our desktop is the topest frame :-(
+ // So - please don't show any assertions here. Do nothing!
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Desktop::deactivate() throw( css::uno::RuntimeException )
+{
+ // Desktop is activae always ... but sometimes our frames try to deactivate
+ // the complete path from bottom to top ... And our desktop is the topest frame :-(
+ // So - please don't show any assertions here. Do nothing!
+}
+
+//*****************************************************************************************************************
+sal_Bool SAL_CALL Desktop::isActive() throw( css::uno::RuntimeException )
+{
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+sal_Bool SAL_CALL Desktop::setComponent( const css::uno::Reference< css::awt::XWindow >& /*xComponentWindow*/ ,
+ const css::uno::Reference< css::frame::XController >& /*xController*/ ) throw( css::uno::RuntimeException )
+{
+ return sal_False;
+}
+
+//*****************************************************************************************************************
+css::uno::Reference< css::awt::XWindow > SAL_CALL Desktop::getComponentWindow() throw( css::uno::RuntimeException )
+{
+ return css::uno::Reference< css::awt::XWindow >();
+}
+
+//*****************************************************************************************************************
+css::uno::Reference< css::frame::XController > SAL_CALL Desktop::getController() throw( css::uno::RuntimeException )
+{
+ return css::uno::Reference< css::frame::XController >();
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Desktop::contextChanged() throw( css::uno::RuntimeException )
+{
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Desktop::addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& ) throw( css::uno::RuntimeException )
+{
+}
+
+//*****************************************************************************************************************
+// css::frame::XFrame
+//*****************************************************************************************************************
+void SAL_CALL Desktop::removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& ) throw( css::uno::RuntimeException )
+{
+}
+
+/*-************************************************************************************************************//**
+ @interface XFrame
+ @short try to find a frame with special parameters
+ @descr This method searches for a frame with the specified name.
+ Frames may contain other frames (e.g. a frameset) and may
+ be contained in other frames. This hierarchie ist searched by
+ this method.
+ First some special names are taken into account, i.e. "",
+ "_self", "_top", "_parent" etc. The FrameSearchFlags are ignored
+ when comparing these names with aTargetFrameName, further steps are
+ controlled by the FrameSearchFlags. If allowed, the name of the frame
+ itself is compared with the desired one, then ( again if allowed )
+ the method findFrame is called for all children of the frame.
+ If no Frame with the given name is found until the top frames container,
+ a new top Frame is created, if this is allowed by a special
+ FrameSearchFlag. The new Frame also gets the desired name.
+ We use a helper to get right search direction and react in a right manner.
+
+ @seealso class TargetFinder
+
+ @param "sTargetFrameName" , name of searched frame
+ @param "nSearchFlags" , flags to regulate search
+ @return A reference to an existing frame in hierarchy, if it exist.
+
+ @onerror A null reference is returned.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::findFrame( const ::rtl::OUString& sTargetFrameName ,
+ sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XFrame > xTarget;
+
+ //-----------------------------------------------------------------------------------------------------
+ // 0) Ignore wrong parameter!
+ // We doesn't support search for following special targets.
+ // If we reject this requests - we mustnt check for such names
+ // in following code again and again. If we do not so -wrong
+ // search results can occure!
+ //-----------------------------------------------------------------------------------------------------
+ if (
+ (sTargetFrameName==SPECIALTARGET_DEFAULT ) || // valid for dispatches - not for findFrame()!
+ (sTargetFrameName==SPECIALTARGET_MENUBAR ) || // valid for dispatches - not for findFrame()!
+ (sTargetFrameName==SPECIALTARGET_HELPAGENT) || // valid for dispatches - not for findFrame()!
+ (sTargetFrameName==SPECIALTARGET_PARENT ) || // we have no parent by definition
+ (sTargetFrameName==SPECIALTARGET_BEAMER ) // beamer frames are allowed as child of tasks only -
+ // and they exist more then ones. We have no idea which our sub tasks is the right one
+ )
+ {
+ return NULL;
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I) check for special defined targets first which must be handled exclusive.
+ // force using of "if() else if() ..."
+ //-----------------------------------------------------------------------------------------------------
+
+ // get threadsafe some neccessary member which are neccessary for following functionality
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.I) "_blank"
+ // create a new task as child of this desktop instance
+ // Note: Used helper TaskCreator use us automaticly ...
+ //-----------------------------------------------------------------------------------------------------
+ if ( sTargetFrameName==SPECIALTARGET_BLANK )
+ {
+ TaskCreator aCreator(xFactory);
+ xTarget = aCreator.createTask(sTargetFrameName,sal_False);
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.II) "_top"
+ // We are top by definition
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if ( sTargetFrameName==SPECIALTARGET_TOP )
+ {
+ xTarget = this;
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.III) "_self", ""
+ // This mean this "frame" in every case.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (
+ ( sTargetFrameName==SPECIALTARGET_SELF ) ||
+ ( sTargetFrameName.getLength()<1 )
+ )
+ {
+ xTarget = this;
+ }
+
+ else
+ {
+ //-------------------------------------------------------------------------------------------------
+ // II) otherwhise use optional given search flags
+ // force using of combinations of such flags. means no "else" part of use if() statements.
+ // But we ust break further searches if target was already found.
+ // Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
+ // TASK and CREATE are handled special.
+ // But note: Such flags are not valid for the desktop - especialy SIBLINGS or PARENT.
+ //-------------------------------------------------------------------------------------------------
+
+ // get threadsafe some neccessary member which are neccessary for following functionality
+ /* SAFE { */
+ aReadLock.lock();
+ ::rtl::OUString sOwnName = m_sName;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ //-------------------------------------------------------------------------------------------------
+ // II.I) SELF
+ // Check for right name. If it's the searched one return ourself - otherwhise
+ // ignore this flag.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ (nSearchFlags & css::frame::FrameSearchFlag::SELF) &&
+ (sOwnName == sTargetFrameName )
+ )
+ {
+ xTarget = this;
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.II) TASKS
+ // This is a special flag. Normaly it regulate search inside tasks and forbid access to parent trees.
+ // But the desktop exists outside such task trees. They are our sub trees. So the desktop implement
+ // a special feature: We use it to start search on our direct childrens only. That means we supress
+ // search on ALL child frames. May that can be usefull to get access on opened document tasks
+ // only without filter out all non realy required sub frames ...
+ // Used helper method on our container doesn't create any frame - its a search only.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::TASKS)
+ )
+ {
+ xTarget = m_aChildTaskContainer.searchOnDirectChildrens(sTargetFrameName);
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.III) CHILDREN
+ // Search on all children for the given target name.
+ // An empty name value can't occure here - because it must be already handled as "_self"
+ // before. Used helper function of container doesn't create any frame.
+ // It makes a deep search only.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
+ )
+ {
+ xTarget = m_aChildTaskContainer.searchOnAllChildrens(sTargetFrameName);
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.IV) CREATE
+ // If we haven't found any valid target frame by using normal flags - but user allowed us to create
+ // a new one ... we should do that. Used TaskCreator use us automaticly as parent!
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
+ )
+ {
+ TaskCreator aCreator(xFactory);
+ xTarget = aCreator.createTask(sTargetFrameName,sal_False);
+ }
+ }
+
+ return xTarget;
+}
+
+//=============================================================================
+void SAL_CALL Desktop::dispose()
+ throw( css::uno::RuntimeException )
+{
+ // Safe impossible cases
+ // It's an programming error if dispose is called before terminate!
+
+ // But if you just ignore the assertion (which happens in unit
+ // tests for instance in sc/qa/unit) nothing bad happens.
+#ifdef ENABLE_ASSERTIONS
+ if( !m_bIsTerminated )
+ fprintf( stderr, "This used to be an assertion failure: Desktop disposed before terminating it,\n"
+ "but nothing bad seems to happen anyway?\n" );
+#endif
+ SYNCHRONIZED_START
+ WriteGuard aWriteLock( m_aLock );
+
+ // Look for multiple calls of this method!
+ // If somewhere call dispose() twice - he will be stopped here realy!!!
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Now - we are alone and its the first call of this method ...
+ // otherwise call before had thrown a DisposedException / hopefully .-)
+ // But we dont use the transaction object created before ... we reset it immediatly ...
+ // two lines of code ... for what ?
+ // The answer: We wished to synchronize concurrent dispose() calls -> OK
+ // But next line will wait for all currently running transaction (even if they
+ // are running within the same thread!) So we would block ourself there if aTransaction
+ // will stay registered .-)
+ aTransaction.stop();
+
+ // Disable this instance for further work.
+ // This will wait for all current running transactions ...
+ // and reject all new incoming requests!
+ m_aTransactionManager.setWorkingMode( E_BEFORECLOSE );
+
+ aWriteLock.unlock();
+ SYNCHRONIZED_END
+
+ // Following lines of code can be called outside a synchronized block ...
+ // Because our transaction manager will block all new requests to this object.
+ // So nobody can use us any longer.
+ // Exception: Only removing of listener will work ... and this code cant be dangerous.
+
+ // First we has to kill all listener connections.
+ // They might rely on our member and can hinder us on releasing them.
+ css::uno::Reference< css::uno::XInterface > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ // Clear our child task container and forget all task references hardly.
+ // Normaly all open document was already closed by our terminate() function before ...
+ // New opened frames will have a problem now .-)
+ m_aChildTaskContainer.clear();
+
+ // Dispose our helper too.
+ css::uno::Reference< css::lang::XEventListener > xFramesHelper( m_xFramesHelper, css::uno::UNO_QUERY );
+ if( xFramesHelper.is() )
+ xFramesHelper->disposing( aEvent );
+
+ // At least clean up other member references.
+ m_xDispatchHelper.clear();
+ m_xFramesHelper.clear();
+ m_xLastFrame.clear();
+ m_xFactory.clear();
+
+ m_xPipeTerminator.clear();
+ m_xQuickLauncher.clear();
+ m_xSWThreadManager.clear();
+ m_xSfxTerminator.clear();
+
+ // From this point nothing will work further on this object ...
+ // excepting our dtor() .-)
+ m_aTransactionManager.setWorkingMode( E_CLOSE );
+}
+
+/*-************************************************************************************************************//**
+ @interface XComponent
+ @short add/remove listener for dispose events
+ @descr Add an event listener to this object, if you whish to get informations
+ about our dieing!
+ You must releas ethis listener reference during your own disposing() method.
+
+ @attention Our container is threadsafe himeslf. So we doesn't need any lock here.
+
+ @seealso -
+
+ @param "xListener", reference to valid listener. We don't accept invalid values!
+ @return -
+
+ @onerror -
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+void SAL_CALL Desktop::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Safe impossible cases
+ // Method not defined for all incoming parameter.
+ LOG_ASSERT2( implcp_addEventListener( xListener ), "Desktop::addEventListener()", "Invalid parameter detected!" )
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >*) NULL ), xListener );
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Desktop::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Safe impossible cases
+ // Method not defined for all incoming parameter.
+ LOG_ASSERT2( implcp_removeEventListener( xListener ), "Desktop::removeEventListener()", "Invalid parameter detected!" )
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >*) NULL ), xListener );
+}
+
+/*-************************************************************************************************************//**
+ @interface XDispatchResultListener
+ @short callback for dispatches
+ @descr To support our method "loadComponentFromURL()" we are listener on temp. created dispatcher.
+ They call us back in this method "statusChanged()". As source of given state event, they give us a
+ reference to the target frame, in which dispatch was loaded! So we can use it to return his component
+ to caller! If no target exist ... ??!!
+
+ @seealso method loadComponentFromURL()
+
+ @param "aEvent", state event which (hopefully) valid informations
+ @return -
+
+ @onerror -
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+void SAL_CALL Desktop::dispatchFinished( const css::frame::DispatchResultEvent& aEvent ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ if( m_eLoadState != E_INTERACTION )
+ {
+ m_xLastFrame = css::uno::Reference< css::frame::XFrame >();
+ m_eLoadState = E_FAILED ;
+ if( aEvent.State == css::frame::DispatchResultState::SUCCESS )
+ {
+ css::uno::Reference < css::frame::XFrame > xFrame;
+ if ( aEvent.Result >>= m_xLastFrame )
+ m_eLoadState = E_SUCCESSFUL;
+ }
+ }
+ /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
+}
+
+/*-************************************************************************************************************//**
+ @interface XEventListener
+ @short not implemented!
+ @descr We are a status listener ... and so we must be an event listener too ... But we doesn't need it realy!
+ We are a temp. listener only and our lifetime isn't smaller then of our temp. used dispatcher.
+
+ @seealso method loadComponentFromURL()
+
+ @param -
+ @return -
+
+ @onerror -
+ @threadsafe -
+*//*-*************************************************************************************************************/
+void SAL_CALL Desktop::disposing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
+{
+ LOG_ERROR( "Desktop::disposing()", "Algorithm error! Normaly desktop is temp. listener ... not all the time. So this method shouldn't be called." )
+}
+
+/*-************************************************************************************************************//**
+ @interface XInteractionHandler
+ @short callback for loadComponentFromURL for detected exceptions during load proccess
+ @descr In this case we must cancel loading and throw these detected exception again as result
+ of our own called method.
+
+ @attention a)
+ Normal loop in loadComponentFromURL() breaks on setted member m_eLoadState during callback statusChanged().
+ But these interaction feature implements second way to do so! So we must look on different callbacks
+ for same operation ... and live with it.
+ b)
+ Search for given continuations too. If any XInteractionAbort exist ... use it to abort further operations
+ for currently running operation!
+
+ @seealso method loadComponentFromURL()
+ @seealso member m_eLoadState
+
+ @param "xRequest", request for interaction - normal a wrapped target exception from bottom services
+ @return -
+
+ @onerror -
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+void SAL_CALL Desktop::handle( const css::uno::Reference< css::task::XInteractionRequest >& xRequest ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Don't check incoming request!
+ // If somewhere starts interaction without right parameter - he maked something wrong.
+ // loadComponentFromURL() waits for thjese event - otherwise it yield for ever!
+
+ // get packed request and work on it first
+ // Attention: Don't set it on internal member BEFORE interaction is finished - because
+ // "loadComponentFromURL()" yield tills this member is changed. If we do it before
+ // interaction finish we can't guarantee right functionality. May be we cancel load process to erliear ...
+ css::uno::Any aRequest = xRequest->getRequest();
+
+ // extract continuations from request
+ css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations = xRequest->getContinuations();
+ css::uno::Reference< css::task::XInteractionAbort > xAbort ;
+ css::uno::Reference< css::task::XInteractionApprove > xApprove ;
+ css::uno::Reference< css::document::XInteractionFilterSelect > xFilterSelect ;
+ sal_Bool bAbort = sal_False;
+
+ sal_Int32 nCount=lContinuations.getLength();
+ for( sal_Int32 nStep=0; nStep<nCount; ++nStep )
+ {
+ if( ! xAbort.is() )
+ xAbort = css::uno::Reference< css::task::XInteractionAbort >( lContinuations[nStep], css::uno::UNO_QUERY );
+
+ if( ! xApprove.is() )
+ xApprove = css::uno::Reference< css::task::XInteractionApprove >( lContinuations[nStep], css::uno::UNO_QUERY );
+
+ if( ! xFilterSelect.is() )
+ xFilterSelect = css::uno::Reference< css::document::XInteractionFilterSelect >( lContinuations[nStep], css::uno::UNO_QUERY );
+ }
+
+ // differ between abortable interactions (error, unknown filter ...)
+ // and other ones (ambigous but not unknown filter ...)
+ css::task::ErrorCodeRequest aErrorCodeRequest ;
+ css::document::AmbigousFilterRequest aAmbigousFilterRequest;
+ if( aRequest >>= aAmbigousFilterRequest )
+ {
+ if( xFilterSelect.is() )
+ {
+ xFilterSelect->setFilter( aAmbigousFilterRequest.SelectedFilter ); // user selected filter wins!
+ xFilterSelect->select();
+ }
+ }
+ else
+ if( aRequest >>= aErrorCodeRequest )
+ {
+ sal_Bool bWarning = ((aErrorCodeRequest.ErrCode & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
+ if (xApprove.is() && bWarning)
+ xApprove->select();
+ else
+ if (xAbort.is())
+ {
+ xAbort->select();
+ bAbort = sal_True;
+ }
+ }
+ else
+ if( xAbort.is() )
+ {
+ xAbort->select();
+ bAbort = sal_True;
+ }
+
+ /* SAFE AREA ------------------------------------------------------------------------------------------- */
+ // Ok now it's time to break yield loop of loadComponentFromURL().
+ // But only for realy aborted requests!
+ // For example warnings will be approved and we wait for any success story ...
+ if (bAbort)
+ {
+ WriteGuard aWriteLock( m_aLock );
+ m_eLoadState = E_INTERACTION;
+ m_aInteractionRequest = aRequest ;
+ aWriteLock.unlock();
+ }
+ /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
+}
+
+//-----------------------------------------------------------------------------
+::sal_Int32 SAL_CALL Desktop::leaseNumber( const css::uno::Reference< css::uno::XInterface >& xComponent )
+ throw (css::lang::IllegalArgumentException,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ return m_xTitleNumberGenerator->leaseNumber (xComponent);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL Desktop::releaseNumber( ::sal_Int32 nNumber )
+ throw (css::lang::IllegalArgumentException,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ m_xTitleNumberGenerator->releaseNumber (nNumber);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL Desktop::releaseNumberForComponent( const css::uno::Reference< css::uno::XInterface >& xComponent )
+ throw (css::lang::IllegalArgumentException,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ m_xTitleNumberGenerator->releaseNumberForComponent (xComponent);
+}
+
+//-----------------------------------------------------------------------------
+::rtl::OUString SAL_CALL Desktop::getUntitledPrefix()
+ throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ return m_xTitleNumberGenerator->getUntitledPrefix ();
+}
+
+/*-************************************************************************************************************//**
+ @short try to convert a property value
+ @descr This method is called from helperclass "OPropertySetHelper".
+ Don't use this directly!
+ You must try to convert the value of given DESKTOP_PROPHANDLE and
+ return results of this operation. This will be used to ask vetoable
+ listener. If no listener has a veto, we will change value realy!
+ ( in method setFastPropertyValue_NoBroadcast(...) )
+
+ @attention Methods of OPropertySethelper are safed by using our shared osl mutex! (see ctor!)
+ So we must use different locks to make our implementation threadsafe.
+
+ @seealso class OPropertySetHelper
+ @seealso method setFastPropertyValue_NoBroadcast()
+
+ @param "aConvertedValue" new converted value of property
+ @param "aOldValue" old value of property
+ @param "nHandle" handle of property
+ @param "aValue" new value of property
+ @return sal_True if value will be changed, sal_FALSE otherway
+
+ @onerror IllegalArgumentException, if you call this with an invalid argument
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+sal_Bool SAL_CALL Desktop::convertFastPropertyValue( css::uno::Any& aConvertedValue ,
+ css::uno::Any& aOldValue ,
+ sal_Int32 nHandle ,
+ const css::uno::Any& aValue ) throw( css::lang::IllegalArgumentException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Initialize state with sal_False !!!
+ // (Handle can be invalid)
+ sal_Bool bReturn = sal_False;
+
+ switch( nHandle )
+ {
+ case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO:
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::makeAny(m_bSuspendQuickstartVeto),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+ case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::makeAny(m_xDispatchRecorderSupplier),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+ case DESKTOP_PROPHANDLE_TITLE :
+ bReturn = PropHelper::willPropertyBeChanged(
+ css::uno::makeAny(m_sTitle),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+ }
+
+ // Return state of operation.
+ return bReturn ;
+}
+
+/*-************************************************************************************************************//**
+ @short set value of a transient property
+ @descr This method is calling from helperclass "OPropertySetHelper".
+ Don't use this directly!
+ Handle and value are valid everyway! You must set the new value only.
+ After this, baseclass send messages to all listener automaticly.
+
+ @seealso class OPropertySetHelper
+
+ @param "nHandle" handle of property to change
+ @param "aValue" new value of property
+ @return -
+
+ @onerror An exception is thrown.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+void SAL_CALL Desktop::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle ,
+ const css::uno::Any& aValue ) throw( css::uno::Exception )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ switch( nHandle )
+ {
+ case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO: aValue >>= m_bSuspendQuickstartVeto;
+ break;
+ case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER: aValue >>= m_xDispatchRecorderSupplier;
+ break;
+ case DESKTOP_PROPHANDLE_TITLE: aValue >>= m_sTitle;
+ break;
+ }
+}
+
+/*-************************************************************************************************************//**
+ @short get value of a transient property
+ @descr This method is calling from helperclass "OPropertySetHelper".
+ Don't use this directly!
+
+ @attention We don't need any mutex or lock here ... We use threadsafe container or methods here only!
+
+ @seealso class OPropertySetHelper
+
+ @param "nHandle" handle of property to change
+ @param "aValue" current value of property
+ @return -
+
+ @onerror -
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+void SAL_CALL Desktop::getFastPropertyValue( css::uno::Any& aValue ,
+ sal_Int32 nHandle ) const
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ switch( nHandle )
+ {
+ case DESKTOP_PROPHANDLE_ACTIVEFRAME : aValue <<= m_aChildTaskContainer.getActive();
+ break;
+ case DESKTOP_PROPHANDLE_ISPLUGGED : aValue <<= sal_False;
+ break;
+ case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO: aValue <<= m_bSuspendQuickstartVeto;
+ break;
+ case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER: aValue <<= m_xDispatchRecorderSupplier;
+ break;
+ case DESKTOP_PROPHANDLE_TITLE: aValue <<= m_sTitle;
+ break;
+ }
+}
+
+/*-************************************************************************************************************//**
+ @short return structure and information about transient properties
+ @descr This method is calling from helperclass "OPropertySetHelper".
+ Don't use this directly!
+
+ @attention You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
+ Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
+ So we could have two different mutex/lock mechanism at the same object.
+
+ @seealso class OPropertySetHelper
+
+ @param -
+ @return structure with property-informations
+
+ @onerror -
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+::cppu::IPropertyArrayHelper& SAL_CALL Desktop::getInfoHelper()
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
+ static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ // Ready for multithreading
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfoHelper == NULL )
+ {
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
+ // "sal_True" say: Table is sorted by name.
+ static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return(*pInfoHelper);
+}
+
+/*-************************************************************************************************************//**
+ @short return propertysetinfo
+ @descr You can call this method to get information about transient properties
+ of this object.
+
+ @attention You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
+ Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
+ So we could have two different mutex/lock mechanism at the same object.
+
+ @seealso class OPropertySetHelper
+ @seealso interface XPropertySet
+ @seealso interface XMultiPropertySet
+
+ @param -
+ @return reference to object with information [XPropertySetInfo]
+
+ @onerror -
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL Desktop::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException)
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
+ static css::uno::Reference< css::beans::XPropertySetInfo >* pInfo = NULL;
+
+ if( pInfo == NULL )
+ {
+ // Ready for multithreading
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfo == NULL )
+ {
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+/*-************************************************************************************************************//**
+ @short return current component of current frame
+ @descr The desktop himself has no component. But every frame in subtree.
+ If somewhere call getCurrentComponent() at this class, we try to find the right frame and
+ then we try to become his component. It can be a VCL-component, the model or the controller
+ of founded frame.
+
+ @attention We don't work on internal member ... so we doesn't need any lock here.
+
+ @seealso method getCurrentComponent();
+
+ @param "xFrame", reference to valid frame in hierarchy. Method is not defined for invalid values.
+ But we don't check these. Its an IMPL-method and caller must use it right!
+ @return A reference to found component.
+
+ @onerror A null reference is returned.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::lang::XComponent > Desktop::impl_getFrameComponent( const css::uno::Reference< css::frame::XFrame >& xFrame ) const
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Set default return value, if method failed.
+ css::uno::Reference< css::lang::XComponent > xComponent;
+ // Does no controller exists?
+ css::uno::Reference< css::frame::XController > xController = xFrame->getController();
+ if( xController.is() == sal_False )
+ {
+ // Controller not exist - use the VCL-component.
+ xComponent = css::uno::Reference< css::lang::XComponent >( xFrame->getComponentWindow(), css::uno::UNO_QUERY );
+ }
+ else
+ {
+ // Does no model exists?
+ css::uno::Reference< css::frame::XModel > xModel( xController->getModel(), css::uno::UNO_QUERY );
+ if( xModel.is() == sal_True )
+ {
+ // Model exist - use the model as component.
+ xComponent = css::uno::Reference< css::lang::XComponent >( xModel, css::uno::UNO_QUERY );
+ }
+ else
+ {
+ // Model not exist - use the controller as component.
+ xComponent = css::uno::Reference< css::lang::XComponent >( xController, css::uno::UNO_QUERY );
+ }
+ }
+
+ return xComponent;
+}
+
+/*-************************************************************************************************************//**
+ @short create table with information about properties
+ @descr We use a helper class to support properties. These class need some information about this.
+ These method create a new static description table with name, type, r/w-flags and so on ...
+
+ @seealso class OPropertySetHelper
+ @seealso method getInfoHelper()
+
+ @param -
+ @return Static table with information about properties.
+
+ @onerror -
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+const css::uno::Sequence< css::beans::Property > Desktop::impl_getStaticPropertyDescriptor()
+{
+ // Create a new static property array to initialize sequence!
+ // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
+ // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
+ // It's necessary for methods of OPropertySetHelper.
+ // ATTENTION:
+ // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
+
+ static const css::beans::Property pProperties[] =
+ {
+ css::beans::Property( DESKTOP_PROPNAME_ACTIVEFRAME , DESKTOP_PROPHANDLE_ACTIVEFRAME , ::getCppuType((const css::uno::Reference< css::lang::XComponent >*)NULL) , css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
+ css::beans::Property( DESKTOP_PROPNAME_DISPATCHRECORDERSUPPLIER , DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER, ::getCppuType((const css::uno::Reference< css::frame::XDispatchRecorderSupplier >*)NULL), css::beans::PropertyAttribute::TRANSIENT ),
+ css::beans::Property( DESKTOP_PROPNAME_ISPLUGGED , DESKTOP_PROPHANDLE_ISPLUGGED , ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
+ css::beans::Property( DESKTOP_PROPNAME_SUSPENDQUICKSTARTVETO , DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO , ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT ),
+ css::beans::Property( DESKTOP_PROPNAME_TITLE , DESKTOP_PROPHANDLE_TITLE , ::getCppuType((const ::rtl::OUString*)NULL) , css::beans::PropertyAttribute::TRANSIENT ),
+ };
+ // Use it to initialize sequence!
+ static const css::uno::Sequence< css::beans::Property > lPropertyDescriptor( pProperties, DESKTOP_PROPCOUNT );
+ // Return static "PropertyDescriptor"
+ return lPropertyDescriptor;
+}
+
+//=============================================================================
+void Desktop::impl_sendQueryTerminationEvent(Desktop::TTerminateListenerList& lCalledListener,
+ ::sal_Bool& bVeto )
+{
+ bVeto = sal_False;
+
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ) );
+ if ( ! pContainer )
+ return;
+
+ css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
+
+ ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
+ while ( aIterator.hasMoreElements() )
+ {
+ try
+ {
+ css::uno::Reference< css::frame::XTerminateListener > xListener(aIterator.next(), css::uno::UNO_QUERY);
+ if ( ! xListener.is() )
+ continue;
+ xListener->queryTermination( aEvent );
+ lCalledListener.push_back(xListener);
+ }
+ catch( const css::frame::TerminationVetoException& )
+ {
+ // first veto will stop notification loop.
+ bVeto = sal_True;
+ return;
+ }
+ catch( const css::uno::Exception& )
+ {
+ // clean up container.
+ // E.g. dead remote listener objects can make trouble otherwise.
+ // Iterator implementation allows removing objects during it's used !
+ aIterator.remove();
+ }
+ }
+}
+
+//=============================================================================
+void Desktop::impl_sendCancelTerminationEvent(const Desktop::TTerminateListenerList& lCalledListener)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
+ Desktop::TTerminateListenerList::const_iterator pIt;
+ for ( pIt = lCalledListener.begin();
+ pIt != lCalledListener.end ();
+ ++pIt )
+ {
+ try
+ {
+ // Note: cancelTermination() is a new and optional interface method !
+ css::uno::Reference< css::frame::XTerminateListener > xListener = *pIt;
+ css::uno::Reference< css::frame::XTerminateListener2 > xListenerGeneration2(xListener, css::uno::UNO_QUERY);
+ if ( ! xListenerGeneration2.is() )
+ continue;
+ xListenerGeneration2->cancelTermination( aEvent );
+ }
+ catch( const css::uno::Exception& )
+ {}
+ }
+}
+
+//=============================================================================
+void Desktop::impl_sendNotifyTerminationEvent()
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ) );
+ if ( ! pContainer )
+ return;
+
+ css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
+
+ ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
+ while ( aIterator.hasMoreElements() )
+ {
+ try
+ {
+ css::uno::Reference< css::frame::XTerminateListener > xListener(aIterator.next(), css::uno::UNO_QUERY);
+ if ( ! xListener.is() )
+ continue;
+ xListener->notifyTermination( aEvent );
+ }
+ catch( const css::uno::Exception& )
+ {
+ // clean up container.
+ // E.g. dead remote listener objects can make trouble otherwise.
+ // Iterator implementation allows removing objects during it's used !
+ aIterator.remove();
+ }
+ }
+}
+
+//=============================================================================
+::sal_Bool Desktop::impl_closeFrames(::sal_Bool bAllowUI)
+{
+ SYNCHRONIZED_START
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > lFrames = m_aChildTaskContainer.getAllElements();
+ aReadLock.unlock();
+ SYNCHRONIZED_END
+
+ ::sal_Int32 c = lFrames.getLength();
+ ::sal_Int32 i = 0;
+ ::sal_Int32 nNonClosedFrames = 0;
+
+ for( i=0; i<c; ++i )
+ {
+ try
+ {
+ css::uno::Reference< css::frame::XFrame > xFrame = lFrames[i];
+
+ // XController.suspend() will show an UI ...
+ // Use it in case it was allowed from outside only.
+ sal_Bool bSuspended = sal_False;
+ css::uno::Reference< css::frame::XController > xController( xFrame->getController(), css::uno::UNO_QUERY );
+ if (
+ ( bAllowUI ) &&
+ ( xController.is() )
+ )
+ {
+ bSuspended = xController->suspend( sal_True );
+ if ( ! bSuspended )
+ {
+ ++nNonClosedFrames;
+ continue;
+ }
+ }
+
+ // Try to close frame (in case no UI was allowed without calling XController->suspend() before!)
+ // But don't deliver ownership to any other one!
+ // This method can be called again.
+ css::uno::Reference< css::util::XCloseable > xClose( xFrame, css::uno::UNO_QUERY );
+ if ( xClose.is() )
+ {
+ try
+ {
+ xClose->close(sal_False);
+ }
+ catch(const css::util::CloseVetoException&)
+ {
+ // Any internal process of this frame disagree with our request.
+ // Safe this state but dont break these loop. Other frames has to be closed!
+ ++nNonClosedFrames;
+
+ // Reactivate controller.
+ // It can happen that XController.suspend() returned true ... but a registered close listener
+ // throwed these veto exception. Then the controller has to be reactivated. Otherwise
+ // these document doesnt work any more.
+ if (
+ (bSuspended ) &&
+ (xController.is())
+ )
+ xController->suspend(sal_False);
+ }
+
+ // If interface XClosable interface exists and was used ...
+ // it's not allowed to use XComponent->dispose() also !
+ continue;
+ }
+
+ // XClosable not supported ?
+ // Then we have to dispose these frame hardly.
+ css::uno::Reference< css::lang::XComponent > xDispose( xFrame, css::uno::UNO_QUERY );
+ if ( xDispose.is() )
+ xDispose->dispose();
+
+ // Don't remove these frame from our child container!
+ // A frame do it by itself inside close()/dispose() method.
+ }
+ catch(const css::lang::DisposedException&)
+ {
+ // Dispose frames are closed frames.
+ // So we can count it here .-)
+ }
+ }
+
+ return (nNonClosedFrames < 1);
+}
+
+//_________________________________________________________________________________________________________________
+// debug methods
+//_________________________________________________________________________________________________________________
+
+/*-----------------------------------------------------------------------------------------------------------------
+ The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
+ we return "sal_True". (otherwise sal_False) This mechanism is used to throw an ASSERT!
+-----------------------------------------------------------------------------------------------------------------*/
+
+#ifdef ENABLE_ASSERTIONS
+
+//*****************************************************************************************************************
+// We work with valid servicemanager only.
+sal_Bool Desktop::implcp_ctor( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+{
+ return(
+ ( &xFactory == NULL ) ||
+ ( xFactory.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+// We work with valid listener only.
+sal_Bool Desktop::implcp_addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+{
+ return(
+ ( &xListener == NULL ) ||
+ ( xListener.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+// We work with valid listener only.
+sal_Bool Desktop::implcp_removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+{
+ return(
+ ( &xListener == NULL ) ||
+ ( xListener.is() == sal_False )
+ );
+}
+
+#endif // #ifdef ENABLE_ASSERTIONS
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/dispatchhelper.cxx b/framework/source/services/dispatchhelper.cxx
new file mode 100644
index 000000000000..4bd3260defcb
--- /dev/null
+++ b/framework/source/services/dispatchhelper.cxx
@@ -0,0 +1,229 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_______________________________________________
+// my own includes
+#include <services/dispatchhelper.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XNotifyingDispatch.hpp>
+
+//_______________________________________________
+// includes of other projects
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//_______________________________________________
+// non exported const
+
+//_______________________________________________
+// non exported definitions
+
+//_______________________________________________
+// declarations
+
+//_______________________________________________
+// XInterface, XTypeProvider, XServiceInfo
+
+DEFINE_XSERVICEINFO_MULTISERVICE(DispatchHelper ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_DISPATCHHELPER ,
+ IMPLEMENTATIONNAME_DISPATCHHELPER)
+
+DEFINE_INIT_SERVICE( DispatchHelper, {} )
+
+//_______________________________________________
+
+/** ctor.
+
+ @param xSMGR the global uno service manager, which can be used to create own needed services.
+*/
+DispatchHelper::DispatchHelper( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ : ThreadHelpBase( )
+ // Init member
+ , m_xSMGR (xSMGR)
+{
+}
+
+//_______________________________________________
+
+/** dtor.
+*/
+DispatchHelper::~DispatchHelper()
+{
+}
+
+//_______________________________________________
+
+/** capsulate all steps of a dispatch request and provide so an easy way for dispatches.
+
+ @param xDispatchProvider
+ identifies the object, which provides may be valid dispatch objects for this execute.
+
+ @param sURL
+ describes the requested feature.
+
+ @param sTargetFrameName
+ points to the frame, which must be used (or may be created) for this dispatch.
+
+ @param nSearchFlags
+ in case the <var>sTargetFrameName</var> isn't unique, these flags regulate further searches.
+
+ @param lArguments
+ optional arguments for this request.
+
+ @return An Any which capsulate a possible result of the internal wrapped dispatch.
+ */
+css::uno::Any SAL_CALL DispatchHelper::executeDispatch(
+ const css::uno::Reference< css::frame::XDispatchProvider >& xDispatchProvider ,
+ const ::rtl::OUString& sURL ,
+ const ::rtl::OUString& sTargetFrameName ,
+ sal_Int32 nSearchFlags ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Reference< css::uno::XInterface > xTHIS(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+
+ // check for valid parameters
+ if (
+ (!xDispatchProvider.is()) ||
+ (sURL.getLength()<1 )
+ )
+ {
+ return css::uno::Any();
+ }
+
+ // parse given URL
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
+ aReadLock.unlock();
+ /* } SAFE */
+
+ css::util::URL aURL;
+ aURL.Complete = sURL;
+ xParser->parseStrict(aURL);
+
+ // search dispatcher
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xDispatchProvider->queryDispatch(aURL, sTargetFrameName, nSearchFlags);
+ css::uno::Reference< css::frame::XNotifyingDispatch > xNotifyDispatch (xDispatch, css::uno::UNO_QUERY);
+
+ // make sure that synchronous execution is used (if possible)
+ css::uno::Sequence< css::beans::PropertyValue > aArguments( lArguments );
+ sal_Int32 nLength = lArguments.getLength();
+ aArguments.realloc( nLength + 1 );
+ aArguments[ nLength ].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SynchronMode"));
+ aArguments[ nLength ].Value <<= (sal_Bool) sal_True;
+
+ css::uno::Any aResult;
+ if (xNotifyDispatch.is())
+ {
+ // dispatch it with guaranteed notification
+ // Here we can hope for a result ... instead of the normal dispatch.
+ css::uno::Reference< css::frame::XDispatchResultListener > xListener(xTHIS, css::uno::UNO_QUERY);
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ m_xBroadcaster = css::uno::Reference< css::uno::XInterface >(xNotifyDispatch, css::uno::UNO_QUERY);
+ m_aResult = css::uno::Any();
+ m_aBlock.reset();
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ // dispatch it and wait for a notification
+ // TODO/MBA: waiting in main thread?!
+ xNotifyDispatch->dispatchWithNotification(aURL, aArguments, xListener);
+ aResult = m_aResult;
+ }
+ else
+ if (xDispatch.is())
+ {
+ // dispatch it without any chance to get a result
+ xDispatch->dispatch( aURL, aArguments );
+ }
+
+ return aResult;
+}
+
+//_______________________________________________
+
+/** callback for started dispatch with guaranteed notifications.
+
+ We must save the result, so the method executeDispatch() can return it.
+ Further we must release the broadcaster (otherwhise it can't die)
+ and unblock the waiting executeDispatch() request.
+
+ @param aResult
+ describes the result of the dispatch operation
+ */
+void SAL_CALL DispatchHelper::dispatchFinished( const css::frame::DispatchResultEvent& aResult )
+ throw(css::uno::RuntimeException)
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ m_aResult <<= aResult;
+ m_aBlock.set();
+ m_xBroadcaster.clear();
+
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** we has to realease our broadcaster reference.
+
+ @param aEvent
+ describe the source of this event and MUST be our save broadcaster!
+ */
+void SAL_CALL DispatchHelper::disposing( const css::lang::EventObject& )
+ throw(css::uno::RuntimeException)
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+
+ m_aResult.clear();
+ m_aBlock.set();
+ m_xBroadcaster.clear();
+
+ /* } SAFE */
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/frame.cxx b/framework/source/services/frame.cxx
new file mode 100644
index 000000000000..e4d5655ca5f0
--- /dev/null
+++ b/framework/source/services/frame.cxx
@@ -0,0 +1,3305 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <services/frame.hxx>
+#include <dispatch/dispatchprovider.hxx>
+
+#include <dispatch/interceptionhelper.hxx>
+#include <dispatch/closedispatcher.hxx>
+#include <dispatch/windowcommanddispatch.hxx>
+#include <loadenv/loadenv.hxx>
+#include <helper/oframes.hxx>
+#include <helper/statusindicatorfactory.hxx>
+#include <framework/titlehelper.hxx>
+#include <classes/droptargetlistener.hxx>
+#include <classes/taskcreator.hxx>
+#include <loadenv/targethelper.hxx>
+#include <framework/framelistanalyzer.hxx>
+#include <helper/dockingareadefaultacceptor.hxx>
+#include <dispatch/dispatchinformationprovider.hxx>
+#include <threadhelp/transactionguard.hxx>
+#include <pattern/window.hxx>
+#include <services.h>
+#include <properties.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/task/XJobExecutor.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+#include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/awt/XDataTransferProviderAccess.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+
+#include <com/sun/star/frame/XTitleChangeBroadcaster.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <comphelper/sequenceashashmap.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/proptypehlp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/window.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/svapp.hxx>
+
+#include <toolkit/unohlp.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/moduleoptions.hxx>
+
+#ifdef ENABLE_ASSERTIONS
+ #ifndef _RTL_STRBUF_HXX_
+ #include <rtl/strbuf.hxx>
+ #endif
+#endif
+
+#include <vcl/menu.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+css::uno::WeakReference< css::frame::XFrame > Frame::m_xCloserFrame = css::uno::WeakReference< css::frame::XFrame >();
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_21 ( Frame ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::frame::XFramesSupplier ),
+ DIRECT_INTERFACE(css::frame::XFrame ),
+ DIRECT_INTERFACE(css::lang::XComponent ),
+ DIRECT_INTERFACE(css::task::XStatusIndicatorFactory ),
+ DIRECT_INTERFACE(css::frame::XDispatchProvider ),
+ DIRECT_INTERFACE(css::frame::XDispatchInformationProvider ),
+ DIRECT_INTERFACE(css::frame::XDispatchProviderInterception ),
+ DIRECT_INTERFACE(css::beans::XPropertySet ),
+ DIRECT_INTERFACE(css::beans::XPropertySetInfo ),
+ DIRECT_INTERFACE(css::awt::XWindowListener ),
+ DIRECT_INTERFACE(css::awt::XTopWindowListener ),
+ DIRECT_INTERFACE(css::awt::XFocusListener ),
+ DERIVED_INTERFACE(css::lang::XEventListener, css::awt::XWindowListener ),
+ DIRECT_INTERFACE(css::document::XActionLockable ),
+ DIRECT_INTERFACE(css::util::XCloseable ),
+ DIRECT_INTERFACE(css::util::XCloseBroadcaster ),
+ DIRECT_INTERFACE(css::frame::XComponentLoader ),
+ DIRECT_INTERFACE(css::frame::XTitle ),
+ DIRECT_INTERFACE(css::frame::XTitleChangeBroadcaster )
+ )
+
+DEFINE_XTYPEPROVIDER_20 ( Frame ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::frame::XFramesSupplier ,
+ css::frame::XFrame ,
+ css::lang::XComponent ,
+ css::task::XStatusIndicatorFactory ,
+ css::beans::XPropertySet ,
+ css::beans::XPropertySetInfo ,
+ css::frame::XDispatchProvider ,
+ css::frame::XDispatchInformationProvider ,
+ css::frame::XDispatchProviderInterception ,
+ css::awt::XWindowListener ,
+ css::awt::XTopWindowListener ,
+ css::awt::XFocusListener ,
+ css::lang::XEventListener ,
+ css::util::XCloseable ,
+ css::util::XCloseBroadcaster ,
+ css::frame::XComponentLoader ,
+ css::frame::XTitle ,
+ css::frame::XTitleChangeBroadcaster
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( Frame ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_FRAME ,
+ IMPLEMENTATIONNAME_FRAME
+ )
+
+DEFINE_INIT_SERVICE ( Frame,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY_THROW);
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a new dispatchhelper-object to handle dispatches.
+ // We use these helper as slave for our interceptor helper ... not directly!
+ // But he is event listener on THIS instance!
+ DispatchProvider* pDispatchHelper = new DispatchProvider( m_xFactory, this );
+ css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( static_cast< ::cppu::OWeakObject* >(pDispatchHelper), css::uno::UNO_QUERY );
+
+ //-------------------------------------------------------------------------------------------------------------
+ DispatchInformationProvider* pInfoHelper = new DispatchInformationProvider(m_xFactory, this);
+ m_xDispatchInfoHelper = css::uno::Reference< css::frame::XDispatchInformationProvider >( static_cast< ::cppu::OWeakObject* >(pInfoHelper), css::uno::UNO_QUERY );
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a new interception helper object to handle dispatches and implement an interceptor mechanism.
+ // Set created dispatch provider as slowest slave of it.
+ // Hold interception helper by reference only - not by pointer!
+ // So it's easiear to destroy it.
+ InterceptionHelper* pInterceptionHelper = new InterceptionHelper( this, xDispatchProvider );
+ m_xDispatchHelper = css::uno::Reference< css::frame::XDispatchProvider >( static_cast< ::cppu::OWeakObject* >(pInterceptionHelper), css::uno::UNO_QUERY );
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a new XFrames-helper-object to handle XIndexAccess and XElementAccess.
+ // We hold member as reference ... not as pointer too!
+ // Attention: We share our frame container with this helper. Container is threadsafe himself ... So I think we can do that.
+ // But look on dispose() for right order of deinitialization.
+ OFrames* pFramesHelper = new OFrames( m_xFactory, this, &m_aChildFrameContainer );
+ m_xFramesHelper = css::uno::Reference< css::frame::XFrames >( static_cast< ::cppu::OWeakObject* >(pFramesHelper), css::uno::UNO_QUERY );
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Initialize a the drop target listener.
+ // We hold member as reference ... not as pointer too!
+ DropTargetListener* pDropListener = new DropTargetListener( m_xFactory, this );
+ m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >( static_cast< ::cppu::OWeakObject* >(pDropListener), css::uno::UNO_QUERY );
+
+ // Safe impossible cases
+ // We can't work without these helpers!
+ LOG_ASSERT2( xDispatchProvider.is ()==sal_False, "Frame::impl_initService()", "Slowest slave for dispatch- and interception helper isn't valid. XDispatchProvider, XDispatch, XDispatchProviderInterception are not full supported!" )
+ LOG_ASSERT2( m_xDispatchHelper.is ()==sal_False, "Frame::impl_initService()", "Interception helper isn't valid. XDispatchProvider, XDispatch, XDispatchProviderInterception are not full supported!" )
+ LOG_ASSERT2( m_xFramesHelper.is ()==sal_False, "Frame::impl_initService()", "Frames helper isn't valid. XFrames, XIndexAccess and XElementAcces are not supported!" )
+ LOG_ASSERT2( m_xDropTargetListener.is()==sal_False, "Frame::impl_initService()", "DropTarget helper isn't valid. Drag and drop without functionality!" )
+
+ //-------------------------------------------------------------------------------------------------------------
+ // establish notifies for changing of "disabled commands" configuration during runtime
+ m_aCommandOptions.EstablisFrameCallback(this);
+
+ //-------------------------------------------------------------------------------------------------------------
+ // Create an initial layout manager
+ // Create layout manager and connect it to the newly created frame
+ m_xLayoutManager = css::uno::Reference< css::frame::XLayoutManager >(m_xFactory->createInstance(SERVICENAME_LAYOUTMANAGER), css::uno::UNO_QUERY);
+
+ //-------------------------------------------------------------------------------------------------------------
+ // set information about all supported properties at the base class helper PropertySetHelper
+ impl_initializePropInfo();
+ }
+ )
+
+/*-****************************************************************************************************//**
+ @short standard constructor to create instance by factory
+ @descr This constructor initialize a new instance of this class by valid factory,
+ and will be set valid values on his member and baseclasses.
+
+ @attention a) Don't use your own reference during an UNO-Service-ctor! There is no guarantee, that you
+ will get over this. (e.g. using of your reference as parameter to initialize some member)
+ Do such things in DEFINE_INIT_SERVICE() method, which is called automaticly after your ctor!!!
+ b) Baseclass OBroadcastHelper is a typedef in namespace cppu!
+ The microsoft compiler has some problems to handle it right BY using namespace explicitly ::cppu::OBroadcastHelper.
+ If we write it without a namespace or expand the typedef to OBrodcastHelperVar<...> -> it will be OK!?
+ I don't know why! (other compiler not tested .. but it works!)
+
+ @seealso method DEFINE_INIT_SERVICE()
+
+ @param "xFactory" is the multi service manager, which create this instance.
+ The value must be different from NULL!
+ @return -
+
+ @onerror ASSERT in debug version or nothing in relaese version.
+*//*-*****************************************************************************************************/
+Frame::Frame( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , TransactionBase ( )
+ , PropertySetHelper ( xFactory,
+ &m_aLock,
+ &m_aTransactionManager,
+ sal_False) // sal_False => dont release shared mutex on calling us!
+ , ::cppu::OWeakObject ( )
+ // init member
+ , m_xFactory ( xFactory )
+ , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
+ , m_xParent ( )
+ , m_xContainerWindow ( )
+ , m_xComponentWindow ( )
+ , m_xController ( )
+ , m_eActiveState ( E_INACTIVE )
+ , m_sName ( )
+ , m_bIsFrameTop ( sal_True ) // I think we are top without a parent ... and there is no parent yet!
+ , m_bConnected ( sal_False ) // There exist no component inside of use => sal_False, we are not connected!
+ , m_nExternalLockCount ( 0 )
+ , m_bSelfClose ( sal_False ) // Important!
+ , m_bIsHidden ( sal_True )
+ , m_xTitleHelper ( )
+ , m_pWindowCommandDispatch ( 0 )
+ , m_aChildFrameContainer ( )
+{
+ // Check incoming parameter to avoid against wrong initialization.
+ LOG_ASSERT2( implcp_ctor( xFactory ), "Frame::Frame()", "Invalid parameter detected!" )
+
+ /* Please have a look on "@attentions" of description before! */
+}
+
+/*-****************************************************************************************************//**
+ @short standard destructor
+ @descr This one do NOTHING! Use dispose() instaed of this.
+
+ @seealso method dispose()
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+Frame::~Frame()
+{
+ LOG_ASSERT2( m_aTransactionManager.getWorkingMode()!=E_CLOSE, "Frame::~Frame()", "Who forgot to dispose this service?" )
+}
+
+/*-************************************************************************************************************//**
+ @interface XComponentLoader
+ @short try to load given URL into a task
+ @descr You can give us some informations about the content, which you will load into a frame.
+ We search or create this target for you, make a type detection of given URL and try to load it.
+ As result of this operation we return the new created component or nothing, if loading failed.
+
+ @seealso -
+
+ @param "sURL" , URL, which represant the content
+ @param "sTargetFrameName" , name of target frame or special value like "_self", "_blank" ...
+ @param "nSearchFlags" , optional arguments for frame search, if target isn't a special one
+ @param "lArguments" , optional arguments for loading
+ @return A valid component reference, if loading was successfully.
+ A null reference otherwise.
+
+ @onerror We return a null reference.
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+css::uno::Reference< css::lang::XComponent > SAL_CALL Frame::loadComponentFromURL( const ::rtl::OUString& sURL ,
+ const ::rtl::OUString& sTargetFrameName,
+ sal_Int32 nSearchFlags ,
+ const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::io::IOException ,
+ css::lang::IllegalArgumentException ,
+ css::uno::RuntimeException )
+{
+ {
+ // If the frame is closed the call might lead to crash even with target "_blank",
+ // so the DisposedException should be thrown in this case
+ // It still looks to be too dangerous to set the transaction for the whole loading process
+ // so the guard is used in scopes to let the standard check be used
+
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ }
+
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XComponentLoader > xThis(static_cast< css::frame::XComponentLoader* >(this), css::uno::UNO_QUERY);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xFactory;
+ aReadLock.unlock();
+
+ return LoadEnv::loadComponentFromURL(xThis, xSMGR, sURL, sTargetFrameName, nSearchFlags, lArguments);
+}
+
+/*-****************************************************************************************************//**
+ @short return access to append or remove childs on desktop
+ @descr We don't implement these interface directly. We use a helper class to do this.
+ If you wish to add or delete childs to/from the container, call these method to get
+ a reference to the helper.
+
+ @seealso class OFrames
+
+ @param -
+ @return A reference to the helper which answer your queries.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XFrames > SAL_CALL Frame::getFrames() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+
+/*TODO
+ This is a temp. HACK!
+ Our parent (a Task!) stand in close/dispose and set working mode to E_BEFOERECLOSE
+ and call dispose on us! We tra to get this xFramesHelper and are reject by an "already closed" pranet instance ....
+ => We use SOFTEXCEPTIONS here ... but we should make it right in further times ....
+ */
+
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ // Return access to all child frames to caller.
+ // Ouer childframe container is implemented in helper class OFrames and used as a reference m_xFramesHelper!
+ return m_xFramesHelper;
+}
+
+/*-****************************************************************************************************//**
+ @short get the current active child frame
+ @descr It must be a frameto. Direct childs of a frame are frames only! No task or desktop is accepted.
+ We don't save this information directly in this class. We use ouer container-helper
+ to do that.
+
+ @seealso class OFrameContainer
+ @seealso method setActiveFrame()
+
+ @param -
+ @return A reference to ouer current active childframe, if anyone exist.
+ @return A null reference, if nobody is active.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::getActiveFrame() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ // Return current active frame.
+ // This information is avaliable on the container.
+ return m_aChildFrameContainer.getActive();
+}
+
+/*-****************************************************************************************************//**
+ @short set the new active direct child frame
+ @descr It must be a frame to. Direct childs of frame are frames only! No task or desktop is accepted.
+ We don't save this information directly in this class. We use ouer container-helper
+ to do that.
+
+ @seealso class OFrameContainer
+ @seealso method getActiveFrame()
+
+ @param "xFrame", reference to new active child. It must be an already existing child!
+ @return -
+
+ @onerror An assertion is thrown and element is ignored, if given frame is'nt already a child of us.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameters.
+ LOG_ASSERT2( implcp_setActiveFrame( xFrame ), "Frame::setActiveFrame()", "Invalid parameter detected!" )
+ // Look for rejected calls!
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ // Copy neccessary member for threadsafe access!
+ // m_aChildFrameContainer is threadsafe himself and he live if we live!!!
+ // ...and our transaction is non breakable too ...
+ css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive();
+ EActiveState eActiveState = m_eActiveState ;
+
+ aWriteLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ // Don't work, if "new" active frame is'nt different from current one!
+ // (xFrame==NULL is allowed to UNSET it!)
+ if( xActiveChild != xFrame )
+ {
+ // ... otherwise set new and deactivate old one.
+ m_aChildFrameContainer.setActive( xFrame );
+ if (
+ ( eActiveState != E_INACTIVE ) &&
+ ( xActiveChild.is() == sal_True )
+ )
+ {
+ xActiveChild->deactivate();
+ }
+ }
+
+ if( xFrame.is() == sal_True )
+ {
+ // If last active frame had focus ...
+ // ... reset state to ACTIVE and send right FrameActionEvent for focus lost.
+ if( eActiveState == E_FOCUS )
+ {
+ aWriteLock.lock();
+ eActiveState = E_ACTIVE ;
+ m_eActiveState = eActiveState;
+ aWriteLock.unlock();
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_DEACTIVATING );
+ }
+
+ // If last active frame was active ...
+ // but new one isn't it ...
+ // ... set it as active one.
+ if (
+ ( eActiveState == E_ACTIVE ) &&
+ ( xFrame->isActive() == sal_False )
+ )
+ {
+ xFrame->activate();
+ }
+ }
+ else
+ // If this frame is active and has no active subframe anymore it is UI active too
+ if( eActiveState == E_ACTIVE )
+ {
+ aWriteLock.lock();
+ eActiveState = E_FOCUS ;
+ m_eActiveState = eActiveState;
+ aWriteLock.unlock();
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_ACTIVATED );
+ }
+}
+
+/*-****************************************************************************************************//**
+ initialize new created layout manager
+**/
+void lcl_enableLayoutManager(const css::uno::Reference< css::frame::XLayoutManager >& xLayoutManager,
+ const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ // Provide container window to our layout manager implementation
+ xLayoutManager->attachFrame(xFrame);
+
+ css::uno::Reference< css::frame::XFrameActionListener > xListen(xLayoutManager, css::uno::UNO_QUERY_THROW);
+ xFrame->addFrameActionListener(xListen);
+
+ DockingAreaDefaultAcceptor* pAcceptor = new DockingAreaDefaultAcceptor(xFrame);
+ css::uno::Reference< css::ui::XDockingAreaAcceptor > xDockingAreaAcceptor( static_cast< ::cppu::OWeakObject* >(pAcceptor), css::uno::UNO_QUERY_THROW);
+ xLayoutManager->setDockingAreaAcceptor(xDockingAreaAcceptor);
+}
+
+/*-****************************************************************************************************//**
+ deinitialize layout manager
+**/
+void lcl_disableLayoutManager(const css::uno::Reference< css::frame::XLayoutManager >& xLayoutManager,
+ const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ css::uno::Reference< css::frame::XFrameActionListener > xListen(xLayoutManager, css::uno::UNO_QUERY_THROW);
+ xFrame->removeFrameActionListener(xListen);
+ xLayoutManager->setDockingAreaAcceptor(css::uno::Reference< css::ui::XDockingAreaAcceptor >());
+ xLayoutManager->attachFrame(css::uno::Reference< css::frame::XFrame >());
+}
+
+/*-****************************************************************************************************//**
+ @short initialize frame instance
+ @descr A frame needs a window. This method set a new one ... but should called one times only!
+ We use this window to listen for window events and forward it to our set component.
+ Its used as parent of component window too.
+
+ @seealso method getContainerWindow()
+ @seealso method setComponent()
+ @seealso member m_xContainerWindow
+
+ @param "xWindow", reference to new container window - must be valid!
+ @return -
+
+ @onerror We do nothing.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::initialize( const css::uno::Reference< css::awt::XWindow >& xWindow ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ if (!xWindow.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Frame::initialize() called without a valid container window reference.")),
+ static_cast< css::frame::XFrame* >(this));
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ if ( m_xContainerWindow.is() )
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Frame::initialized() is called more then once, which isnt usefull nor allowed.")),
+ static_cast< css::frame::XFrame* >(this));
+
+ // Look for rejected calls first!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ // Enable object for real working ... so follow impl methods don't must handle it special! (e.g. E_SOFTEXCEPTIONS for rejected calls)
+ m_aTransactionManager.setWorkingMode( E_WORK );
+
+ // This must be the first call of this method!
+ // We should initialize our object and open it for working.
+ // Set the new window.
+ LOG_ASSERT2( m_xContainerWindow.is()==sal_True, "Frame::initialize()", "Leak detected! This state should never occure ..." )
+ m_xContainerWindow = xWindow;
+
+ // if window is initially visible, we will never get a windowShowing event
+ Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
+ if (pWindow && pWindow->IsVisible())
+ m_bIsHidden = sal_False;
+
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xFactory;
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager = m_xLayoutManager;
+
+ // Release lock ... because we call some impl methods, which are threadsafe by himself.
+ // If we hold this lock - we will produce our own deadlock!
+ aWriteLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ if (xLayoutManager.is())
+ lcl_enableLayoutManager(xLayoutManager, this);
+
+ // create progress helper
+ css::uno::Reference< css::frame::XFrame > xThis (static_cast< css::frame::XFrame* >(this) , css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xIndicatorFactory(xSMGR->createInstance(IMPLEMENTATIONNAME_STATUSINDICATORFACTORY), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::lang::XInitialization > xIndicatorInit (xIndicatorFactory , css::uno::UNO_QUERY_THROW);
+ css::uno::Sequence< css::uno::Any > lArgs(2);
+ css::beans::NamedValue aArg;
+ aArg.Name = STATUSINDICATORFACTORY_PROPNAME_FRAME;
+ aArg.Value <<= xThis;
+ lArgs[0] <<= aArg;
+ aArg.Name = STATUSINDICATORFACTORY_PROPNAME_ALLOWPARENTSHOW;
+ aArg.Value <<= sal_True;
+ lArgs[1] <<= aArg;
+ xIndicatorInit->initialize(lArgs);
+
+ // SAFE -> ----------------------------------
+ aWriteLock.lock();
+ m_xIndicatorFactoryHelper = xIndicatorFactory;
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // Start listening for events after setting it on helper class ...
+ // So superflous messages are filtered to NULL :-)
+ implts_startWindowListening();
+
+ impl_enablePropertySet();
+
+ m_pWindowCommandDispatch = new WindowCommandDispatch(xSMGR, this);
+
+ // Initialize title functionality
+ TitleHelper* pTitleHelper = new TitleHelper(xSMGR);
+ m_xTitleHelper = css::uno::Reference< css::frame::XTitle >(static_cast< ::cppu::OWeakObject* >(pTitleHelper), css::uno::UNO_QUERY_THROW);
+ pTitleHelper->setOwner(xThis);
+}
+
+/*-****************************************************************************************************//**
+ @short returns current set container window
+ @descr The ContainerWindow property is used as a container for the component
+ in this frame. So this object implements a container interface too.
+ The instantiation of the container window is done by the user of this class.
+ The frame is the owner of its container window.
+
+ @seealso method initialize()
+
+ @param -
+ @return A reference to current set containerwindow.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::awt::XWindow > SAL_CALL Frame::getContainerWindow() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ return m_xContainerWindow;
+}
+
+/*-****************************************************************************************************//**
+ @short set parent frame
+ @descr We need a parent to support some functionality! e.g. findFrame()
+ By the way we use the chance to set an internal information about our top state.
+ So we must not check this information during every isTop() call.
+ We are top, if our parent is the desktop instance or we havent any parent.
+
+ @seealso getCreator()
+ @seealso findFrame()
+ @seealso isTop()
+ @seealos m_bIsFrameTop
+
+ @param xCreator
+ valid reference to our new owner frame, which should implement a supplier interface
+
+ @threadsafe yes
+ @modified 08.05.2002 09:35, as96863
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::setCreator( const css::uno::Reference< css::frame::XFramesSupplier >& xCreator ) throw( css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_xParent = xCreator;
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::frame::XDesktop > xIsDesktop( xCreator, css::uno::UNO_QUERY );
+ m_bIsFrameTop = ( xIsDesktop.is() || ! xCreator.is() );
+}
+
+/*-****************************************************************************************************//**
+ @short returns current parent frame
+ @descr The Creator is the parent frame container. If it is NULL, the frame is the uppermost one.
+
+ @seealso method setCreator()
+
+ @param -
+ @return A reference to current set parent frame container.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL Frame::getCreator() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ return m_xParent;
+}
+
+/*-****************************************************************************************************//**
+ @short returns current set name of frame
+ @descr This name is used to find target of findFrame() or queryDispatch() calls.
+
+ @seealso method setName()
+
+ @param -
+ @return Current set name of frame.
+
+ @onerror An empty string is returned.
+*//*-*****************************************************************************************************/
+::rtl::OUString SAL_CALL Frame::getName() throw( css::uno::RuntimeException )
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ return m_sName;
+ /* } SAFE */
+}
+
+/*-****************************************************************************************************//**
+ @short set new name for frame
+ @descr This name is used to find target of findFrame() or queryDispatch() calls.
+
+ @attention Special names like "_blank", "_self" aren't allowed ...
+ "_beamer" or "_menubar" excepts this rule!
+
+ @seealso method getName()
+
+ @param "sName", new frame name.
+ @return -
+
+ @onerror We do nothing.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::setName( const ::rtl::OUString& sName ) throw( css::uno::RuntimeException )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ // Set new name ... but look for invalid special target names!
+ // They are not allowed to set.
+ if (TargetHelper::isValidNameForFrame(sName))
+ m_sName = sName;
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+/*-****************************************************************************************************//**
+ @short search for frames
+ @descr This method searches for a frame with the specified name.
+ Frames may contain other frames (e.g. a frameset) and may
+ be contained in other frames. This hierarchie ist searched by
+ this method.
+ First some special names are taken into account, i.e. "",
+ "_self", "_top", "_blank" etc. The nSearchFlags are ignored
+ when comparing these names with sTargetFrameName, further steps are
+ controlled by the search flags. If allowed, the name of the frame
+ itself is compared with the desired one, then ( again if allowed )
+ the method findFrame() is called for all children, for siblings
+ and as last for the parent frame.
+ If no frame with the given name is found until the top frames container,
+ a new top one is created, if this is allowed by a special
+ flag. The new frame also gets the desired name.
+
+ @param sTargetFrameName
+ special names (_blank, _self) or real name of target frame
+ @param nSearchFlags
+ optional flags which regulate search for non special target frames
+
+ @return A reference to found or may be new created frame.
+ @threadsafe yes
+ @modified 16.05.2002 11:08, as96863
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::findFrame( const ::rtl::OUString& sTargetFrameName,
+ sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XFrame > xTarget;
+
+ //-----------------------------------------------------------------------------------------------------
+ // 0) Ignore wrong parameter!
+ // We doesn't support search for following special targets.
+ // If we reject this requests - we mustnt check for such names
+ // in following code again and again. If we do not so -wrong
+ // search results can occure!
+ //-----------------------------------------------------------------------------------------------------
+ if (
+ (sTargetFrameName==SPECIALTARGET_DEFAULT ) || // valid for dispatches - not for findFrame()!
+ (sTargetFrameName==SPECIALTARGET_MENUBAR ) || // valid for dispatches - not for findFrame()!
+ (sTargetFrameName==SPECIALTARGET_HELPAGENT) // valid for dispatches - not for findFrame()!
+ )
+ {
+ return NULL;
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I) check for special defined targets first which must be handled exclusive.
+ // force using of "if() else if() ..."
+ //-----------------------------------------------------------------------------------------------------
+
+ // get threadsafe some neccessary member which are neccessary for following functionality
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::frame::XFrame > xParent ( m_xParent, css::uno::UNO_QUERY );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
+ sal_Bool bIsTopFrame = m_bIsFrameTop;
+ sal_Bool bIsTopWindow = WindowHelper::isTopWindow(m_xContainerWindow);
+ aReadLock.unlock();
+ /* } SAFE */
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.I) "_blank"
+ // Not allowed for a normal frame - but for the desktop.
+ // Use helper class to do so. It use the desktop automaticly.
+ //-----------------------------------------------------------------------------------------------------
+ if ( sTargetFrameName==SPECIALTARGET_BLANK )
+ {
+ TaskCreator aCreator(xFactory);
+ xTarget = aCreator.createTask(sTargetFrameName,sal_False);
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.II) "_parent"
+ // It doesn't matter if we have a valid parent or not. User ask for him and get it.
+ // An empty result is a valid result too.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if ( sTargetFrameName==SPECIALTARGET_PARENT )
+ {
+ xTarget = xParent;
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.III) "_top"
+ // If we are not the top frame in this hierarchy, we must forward request to our parent.
+ // Otherwhise we must return ourself.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if ( sTargetFrameName==SPECIALTARGET_TOP )
+ {
+ if (bIsTopFrame)
+ xTarget = this;
+ else
+ if (xParent.is()) // If we are not top - the parent MUST exist. But may it's better to check it again .-)
+ xTarget = xParent->findFrame(SPECIALTARGET_TOP,0);
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.IV) "_self", ""
+ // This mean this frame in every case.
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if (
+ ( sTargetFrameName==SPECIALTARGET_SELF ) ||
+ ( sTargetFrameName.getLength()<1 )
+ )
+ {
+ xTarget = this;
+ }
+
+ //-----------------------------------------------------------------------------------------------------
+ // I.V) "_beamer"
+ // This is a special sub frame of any task. We must return it if we found it on our direct childrens
+ // or create it there if it not already exists.
+ // Note: Such beamer exists for task(top) frames only!
+ //-----------------------------------------------------------------------------------------------------
+ else
+ if ( sTargetFrameName==SPECIALTARGET_BEAMER )
+ {
+ // We are a task => search or create the beamer
+ if (bIsTopWindow)
+ {
+ xTarget = m_aChildFrameContainer.searchOnDirectChildrens(SPECIALTARGET_BEAMER);
+ if ( ! xTarget.is() )
+ {
+ /* TODO
+ Creation not supported yet!
+ Wait for new layout manager service because we can't plug it
+ inside already opened document of this frame ...
+ */
+ }
+ }
+ // We arent a task => forward request to our parent or ignore it.
+ else
+ if (xParent.is())
+ xTarget = xParent->findFrame(SPECIALTARGET_BEAMER,0);
+ }
+
+ else
+ {
+ //-------------------------------------------------------------------------------------------------
+ // II) otherwhise use optional given search flags
+ // force using of combinations of such flags. means no "else" part of use if() statements.
+ // But we ust break further searches if target was already found.
+ // Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
+ // TASK and CREATE are handled special.
+ //-------------------------------------------------------------------------------------------------
+
+ // get threadsafe some neccessary member which are neccessary for following functionality
+ /* SAFE { */
+ aReadLock.lock();
+ ::rtl::OUString sOwnName = m_sName;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ //-------------------------------------------------------------------------------------------------
+ // II.I) SELF
+ // Check for right name. If it's the searched one return ourself - otherwhise
+ // ignore this flag.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ (nSearchFlags & css::frame::FrameSearchFlag::SELF) &&
+ (sOwnName == sTargetFrameName )
+ )
+ {
+ xTarget = this;
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.II) CHILDREN
+ // Search on all children for the given target name.
+ // An empty name value can't occure here - because it must be already handled as "_self"
+ // before. Used helper function of container doesn't create any frame.
+ // It makes a deep search only.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
+ )
+ {
+ xTarget = m_aChildFrameContainer.searchOnAllChildrens(sTargetFrameName);
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.III) TASKS
+ // This is a special flag. It regulate search on this task tree only or allow search on
+ // all other ones (which are sibling trees of us) too.
+ // Upper search must stop at this frame if we are the topest one and the TASK flag isn't set
+ // or we can ignore it if we have no valid parent.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( bIsTopFrame && (nSearchFlags & css::frame::FrameSearchFlag::TASKS) ) ||
+ ( ! bIsTopFrame )
+ )
+ {
+ //-------------------------------------------------------------------------------------------------
+ // II.III.I) SIBLINGS
+ // Search on all our direct siblings - means all childrens of our parent.
+ // Use this flag in combination with TASK. We must supress such upper search if
+ // user has not set it and if we are a top frame.
+ // Attention: Don't forward this request to our parent as a findFrame() call.
+ // In such case we must protect us against recursive calls.
+ // Use snapshot of our parent. But don't use queryFrames() of XFrames interface.
+ // Because it's return all siblings and all her childrens including our children too
+ // if we call it with the CHILDREN flag. We doesn't need that - we need the direct container
+ // items of our parent only to start searches there. So we must use the container interface
+ // XIndexAccess instead of XFrames.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::SIBLINGS) &&
+ ( xParent.is() ) // search on siblings is impossible without a parent
+ )
+ {
+ css::uno::Reference< css::frame::XFramesSupplier > xSupplier( xParent, css::uno::UNO_QUERY );
+ if (xSupplier.is())
+ {
+ css::uno::Reference< css::container::XIndexAccess > xContainer( xSupplier->getFrames(), css::uno::UNO_QUERY );
+ if (xContainer.is())
+ {
+ sal_Int32 nCount = xContainer->getCount();
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ css::uno::Reference< css::frame::XFrame > xSibling;
+ if (
+ ( !(xContainer->getByIndex(i)>>=xSibling) ) || // control unpacking
+ ( ! xSibling.is() ) || // check for valid items
+ ( xSibling==static_cast< ::cppu::OWeakObject* >(this) ) // ignore ourself! (We are a part of this container too - but search on our children was already done.)
+ )
+ {
+ continue;
+ }
+
+ // Don't allow upper search here! Use rigth flags to regulate it.
+ // And allow deep search on children only - if it was allowed for us too.
+ sal_Int32 nRightFlags = css::frame::FrameSearchFlag::SELF;
+ if (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
+ nRightFlags |= css::frame::FrameSearchFlag::CHILDREN;
+ xTarget = xSibling->findFrame(sTargetFrameName, nRightFlags );
+ // perform search be breaking further search if a result exist.
+ if (xTarget.is())
+ break;
+ }
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.III.II) PARENT
+ // Forward search to our parent (if he exists.)
+ // To prevent us against recursive and superflous calls (which can occure if we allow him
+ // to search on his childrens too) we must change used search flags.
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::PARENT) &&
+ ( xParent.is() )
+ )
+ {
+ if (xParent->getName() == sTargetFrameName)
+ xTarget = xParent;
+ else
+ {
+ sal_Int32 nRightFlags = nSearchFlags;
+ nRightFlags &= ~css::frame::FrameSearchFlag::CHILDREN;
+ xTarget = xParent->findFrame(sTargetFrameName, nRightFlags);
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // II.IV) CREATE
+ // If we haven't found any valid target frame by using normal flags - but user allowed us to create
+ // a new one ... we should do that. Used TaskCreator use Desktop instance automaticly as parent!
+ //-------------------------------------------------------------------------------------------------
+ if (
+ ( ! xTarget.is() ) &&
+ (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
+ )
+ {
+ TaskCreator aCreator(xFactory);
+ xTarget = aCreator.createTask(sTargetFrameName,sal_False);
+ }
+ }
+
+ return xTarget;
+}
+
+/*-****************************************************************************************************//**
+ @short -
+ @descr Returns sal_True, if this frame is a "top frame", otherwise sal_False.
+ The "m_bIsFrameTop" member must be set in the ctor or setCreator() method.
+ A top frame is a member of the top frame container or a member of the
+ task frame container. Both containers can create new frames if the findFrame()
+ method of their css::frame::XFrame interface is called with a frame name not yet known.
+
+ @seealso ctor
+ @seealso method setCreator()
+ @seealso method findFrame()
+
+ @param -
+ @return true, if is it a top frame ... false otherwise.
+
+ @onerror No error should occure!
+*//*-*****************************************************************************************************/
+sal_Bool SAL_CALL Frame::isTop() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ // This information is set in setCreator().
+ // We are top, if ouer parent is a task or the desktop or if no parent exist!
+ return m_bIsFrameTop;
+}
+
+/*-****************************************************************************************************//**
+ @short activate frame in hierarchy
+ @descr This feature is used to mark active pathes in our frame hierarchy.
+ You can be a listener for this event to react for it ... change some internal states or something else.
+
+ @seealso method deactivate()
+ @seealso method isActivate()
+ @seealso enum EActiveState
+ @seealso listener mechanism
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::activate() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ // Copy neccessary member and free the lock.
+ // It's not neccessary for m_aChildFrameContainer ... because
+ // he is threadsafe himself and live if we live.
+ // We use a registered transaction to prevent us against
+ // breaks during this operation!
+ css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive() ;
+ css::uno::Reference< css::frame::XFramesSupplier > xParent ( m_xParent, css::uno::UNO_QUERY ) ;
+ css::uno::Reference< css::frame::XFrame > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XWindow > xComponentWindow( m_xComponentWindow, css::uno::UNO_QUERY ) ;
+ EActiveState eState = m_eActiveState ;
+
+ aWriteLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ //_________________________________________________________________________________________________________
+ // 1) If I'am not active before ...
+ if( eState == E_INACTIVE )
+ {
+ // ... do it then.
+ aWriteLock.lock();
+ eState = E_ACTIVE;
+ m_eActiveState = eState;
+ aWriteLock.unlock();
+ // Deactivate sibling path and forward activation to parent ... if any parent exist!
+ if( xParent.is() == sal_True )
+ {
+ // Everytime set THIS frame as active child of parent and activate it.
+ // We MUST have a valid path from bottom to top as active path!
+ // But we must deactivate the old active sibling path first.
+
+ // Attention: Deactivation of an active path, deactivate the whole path ... from bottom to top!
+ // But we wish to deactivate founded sibling-tree only.
+ // [ see deactivate() / step 4) for further informations! ]
+
+ xParent->setActiveFrame( xThis );
+
+ // Then we can activate from here to top.
+ // Attention: We are ACTIVE now. And the parent will call activate() at us!
+ // But we do nothing then! We are already activated.
+ xParent->activate();
+ }
+ // Its neccessary to send event NOW - not before.
+ // Activation goes from bottom to top!
+ // Thats the reason to activate parent first and send event now.
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_ACTIVATED );
+ }
+
+ //_________________________________________________________________________________________________________
+ // 2) I was active before or current activated and there is a path from here to bottom, who CAN be active.
+ // But ouer direct child of path is not active yet.
+ // (It can be, if activation occur in the middle of a current path!)
+ // In these case we activate path to bottom to set focus on right frame!
+ if (
+ ( eState == E_ACTIVE ) &&
+ ( xActiveChild.is() == sal_True ) &&
+ ( xActiveChild->isActive() == sal_False )
+ )
+ {
+ xActiveChild->activate();
+ }
+
+ //_________________________________________________________________________________________________________
+ // 3) I was active before or current activated. But if I have no active child => I will get the focus!
+ if (
+ ( eState == E_ACTIVE ) &&
+ ( xActiveChild.is() == sal_False )
+ )
+ {
+ aWriteLock.lock();
+ eState = E_FOCUS;
+ m_eActiveState = eState;
+ aWriteLock.unlock();
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_ACTIVATED );
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short deactivate frame in hierarchy
+ @descr This feature is used to deactive pathes in our frame hierarchy.
+ You can be a listener for this event to react for it ... change some internal states or something else.
+
+ @seealso method activate()
+ @seealso method isActivate()
+ @seealso enum EActiveState
+ @seealso listener mechanism
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::deactivate() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ // Copy neccessary member and free the lock.
+ css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive() ;
+ css::uno::Reference< css::frame::XFramesSupplier > xParent ( m_xParent, css::uno::UNO_QUERY ) ;
+ css::uno::Reference< css::frame::XFrame > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ EActiveState eState = m_eActiveState ;
+
+ aWriteLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ // Work only, if there something to do!
+ if( eState != E_INACTIVE )
+ {
+ //_____________________________________________________________________________________________________
+ // 1) Deactivate all active childs.
+ if (
+ ( xActiveChild.is() == sal_True ) &&
+ ( xActiveChild->isActive() == sal_True )
+ )
+ {
+ xActiveChild->deactivate();
+ }
+
+ //_____________________________________________________________________________________________________
+ // 2) If I have the focus - I will lost it now.
+ if( eState == E_FOCUS )
+ {
+ // Set new state INACTIVE(!) and send message to all listener.
+ // Don't set ACTIVE as new state. This frame is deactivated for next time - due to activate().
+ aWriteLock.lock();
+ eState = E_ACTIVE;
+ m_eActiveState = eState ;
+ aWriteLock.unlock();
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_DEACTIVATING );
+ }
+
+ //_____________________________________________________________________________________________________
+ // 3) If I'am active - I will be deactivated now.
+ if( eState == E_ACTIVE )
+ {
+ // Set new state and send message to all listener.
+ aWriteLock.lock();
+ eState = E_INACTIVE;
+ m_eActiveState = eState ;
+ aWriteLock.unlock();
+ implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_DEACTIVATING );
+ }
+
+ //_____________________________________________________________________________________________________
+ // 4) If there is a path from here to my parent ...
+ // ... I'am on the top or in the middle of deactivated subtree and action was started here.
+ // I must deactivate all frames from here to top, which are members of current path.
+ // Stop, if THESE frame not the active frame of ouer parent!
+ if (
+ ( xParent.is() == sal_True ) &&
+ ( xParent->getActiveFrame() == xThis )
+ )
+ {
+ // We MUST break the path - otherwise we will get the focus - not ouer parent! ...
+ // Attention: Ouer parent don't call us again - WE ARE NOT ACTIVE YET!
+ // [ see step 3 and condition "if ( m_eActiveState!=INACTIVE ) ..." in this method! ]
+ xParent->deactivate();
+ }
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short returns active state
+ @descr Call it to get informations about current active state of this frame.
+
+ @seealso method activate()
+ @seealso method deactivate()
+ @seealso enum EActiveState
+
+ @param -
+ @return true if active, false otherwise.
+
+ @onerror No error should occure.
+*//*-*****************************************************************************************************/
+sal_Bool SAL_CALL Frame::isActive() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ return (
+ ( m_eActiveState == E_ACTIVE ) ||
+ ( m_eActiveState == E_FOCUS )
+ );
+}
+
+/*-****************************************************************************************************//**
+ @short ???
+ @descr -
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::contextChanged() throw( css::uno::RuntimeException )
+{
+ // Look for rejected calls!
+ // Sometimes called during closing object... => soft exceptions
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+ // Impl-method is threadsafe himself!
+ // Send event to all listener for frame actions.
+ implts_sendFrameActionEvent( css::frame::FrameAction_CONTEXT_CHANGED );
+}
+
+/*-****************************************************************************************************//**
+ @short set new component inside the frame
+ @descr A frame is a container for a component. Use this method to set, change or realease it!
+ We accept null references! The xComponentWindow will be a child of our container window
+ and get all window events from us.
+
+ @attention (a) A current set component can disagree with the suspend() request!
+ We don't set the new one and return with false then.
+ (b) It's possible to set:
+ (b1) a simple component here which supports the window only - no controller;
+ (b2) a full featured component which supports window and controller;
+ (b3) or both to NULL if outside code which to forget this component.
+
+ @seealso method getComponentWindow()
+ @seealso method getController()
+
+ @param xComponentWindow
+ valid reference to new component window which will be a child of internal container window
+ May <NULL/> for releasing.
+ @param xController
+ reference to new component controller
+ (may <NULL/> for relasing or setting of a simple component)
+
+ @return <TRUE/> if operation was successful, <FALSE/> otherwise.
+
+ @onerror We return <FALSE/>.
+ @threadsafe yes
+ @modified 06.05.2002 11:39, as96863
+*//*-*****************************************************************************************************/
+sal_Bool SAL_CALL Frame::setComponent( const css::uno::Reference< css::awt::XWindow >& xComponentWindow ,
+ const css::uno::Reference< css::frame::XController >& xController ) throw( css::uno::RuntimeException )
+{
+ //_____________________________________________________________________________________________________
+ // Ignore this HACK of sfx2!
+ // He call us with an valid controller without a valid window ... Thats not allowed!
+ if ( xController.is() && ! xComponentWindow.is() )
+ return sal_True;
+
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ //_____________________________________________________________________________________________________
+ // Get threadsafe some copies of used members.
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
+ css::uno::Reference< css::awt::XWindow > xOldComponentWindow = m_xComponentWindow;
+ css::uno::Reference< css::frame::XController > xOldController = m_xController;
+ Window* pOwnWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ sal_Bool bHadFocus = pOwnWindow->HasChildPathFocus();
+ sal_Bool bWasConnected = m_bConnected;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ //_____________________________________________________________________________________________________
+ // stop listening on old window
+ // May it produce some trouble.
+ // But don't forget to listen on new window again ... or reactivate listening
+ // if we reject this setComponent() request and leave this method without changing the old window.
+ implts_stopWindowListening();
+
+ // Notify all listener, that this component (if current one exist) will be unloaded.
+ if (bWasConnected)
+ implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_DETACHING );
+
+ //_____________________________________________________________________________________________________
+ // otherwhise release old component first
+ // Always release controller before releasing window,
+ // because controller may want to access its window!
+ // But check for real changes - may the new controller is the old one.
+ if (
+ (xOldController.is() ) &&
+ (xOldController != xController)
+ )
+ {
+ /* ATTENTION
+ Don't suspend the old controller here. Because the outside caller must do that
+ by definition. We have to dispose it here only.
+ */
+
+ // Before we dispose this controller we should hide it inside this frame instance.
+ // We hold it alive for next calls by using xOldController!
+ /* SAFE {*/
+ WriteGuard aWriteLock( m_aLock );
+ m_xController = NULL;
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::lang::XComponent > xDisposable( xOldController, css::uno::UNO_QUERY );
+ if (xDisposable.is())
+ {
+ try
+ {
+ xDisposable->dispose();
+ }
+ catch(const css::lang::DisposedException&)
+ {}
+ }
+ xOldController = NULL;
+ }
+
+ //_____________________________________________________________________________________________________
+ // Now it's time to release the component window.
+ // If controller wasn't released successfully - this code line shouldn't be reached.
+ // Because in case of "suspend()==false" we return immediately with false ...
+ // see before
+ // Check for real changes too.
+ if (
+ (xOldComponentWindow.is() ) &&
+ (xOldComponentWindow != xComponentWindow)
+ )
+ {
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_xComponentWindow = NULL;
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::lang::XComponent > xDisposable( xOldComponentWindow, css::uno::UNO_QUERY );
+ if (xDisposable.is())
+ {
+ try
+ {
+ xDisposable->dispose();
+ }
+ catch(const css::lang::DisposedException&)
+ {}
+ }
+ xOldComponentWindow = NULL;
+ }
+
+ //_____________________________________________________________________________________________________
+ // Now it's time to set the new component ...
+ // By the way - find out our new "load state" - means if we have a valid component inside.
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_xComponentWindow = xComponentWindow;
+ m_xController = xController ;
+ m_bConnected = (m_xComponentWindow.is() || m_xController.is());
+ sal_Bool bIsConnected = m_bConnected;
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ //_____________________________________________________________________________________________________
+ // notifies all interest listener, that current component was changed or a new one was loaded
+ if (bIsConnected && bWasConnected)
+ implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_REATTACHED );
+ else
+ if (bIsConnected && !bWasConnected)
+ implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_ATTACHED );
+
+ //_____________________________________________________________________________________________________
+ // A new component window doesn't know anything about current active/focus states.
+ // Set this information on it!
+ if (
+ (bHadFocus ) &&
+ (xComponentWindow.is())
+ )
+ {
+ xComponentWindow->setFocus();
+ }
+
+ // If it was a new component window - we must resize it to fill out
+ // our container window.
+ implts_resizeComponentWindow();
+ // New component should change our current icon ...
+ implts_setIconOnWindow();
+ // OK - start listening on new window again - or do nothing if it is an empty one.
+ implts_startWindowListening();
+
+ /* SAFE { */
+ aWriteLock.lock();
+ impl_checkMenuCloser();
+ aWriteLock.unlock();
+ /* } SAFE */
+
+ return sal_True;
+}
+
+/*-****************************************************************************************************//**
+ @short returns current set component window
+ @descr Frames are used to display components. The actual displayed component is
+ held by the m_xComponentWindow property. If the component implements only a
+ XComponent interface, the communication between the frame and the
+ component is very restricted. Better integration is achievable through a
+ XController interface.
+ If the component wants other objects to be able to get information about its
+ ResourceDescriptor it has to implement a XModel interface.
+ This frame is the owner of the component window.
+
+ @seealso method setComponent()
+
+ @param -
+ @return css::uno::Reference to current set component window.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::awt::XWindow > SAL_CALL Frame::getComponentWindow() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Register transaction and reject wrong calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ return m_xComponentWindow;
+}
+
+/*-****************************************************************************************************//**
+ @short returns current set controller
+ @descr Frames are used to display components. The actual displayed component is
+ held by the m_xComponentWindow property. If the component implements only a
+ XComponent interface, the communication between the frame and the
+ component is very restricted. Better integration is achievable through a
+ XController interface.
+ If the component wants other objects to be able to get information about its
+ ResourceDescriptor it has to implement a XModel interface.
+ This frame is the owner of the component window.
+
+ @seealso method setComponent()
+
+ @param -
+ @return css::uno::Reference to current set controller.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XController > SAL_CALL Frame::getController() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ return m_xController;
+}
+
+/*-****************************************************************************************************//**
+ @short add/remove listener for activate/deactivate/contextChanged events
+ @descr -
+
+ @seealso method activate()
+ @seealso method deactivate()
+ @seealso method contextChanged()
+
+ @param "xListener" reference to your listener object
+ @return -
+
+ @onerror Listener is ignored.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_addFrameActionListener( xListener ), "Frame::addFrameActionListener()", "Invalid parameter detected." )
+ // Listener container is threadsafe by himself ... but we must look for rejected calls!
+ // Our OMenuDispatch-helper (is a member of ODispatchProvider!) is create at startup of this frame BEFORE initialize!
+ // => soft exceptions!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.addInterface( ::getCppuType( (const css::uno::Reference< css::frame::XFrameActionListener >*)NULL ), xListener );
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_removeFrameActionListener( xListener ), "Frame::removeFrameActionListener()", "Invalid parameter detected." )
+ // Listener container is threadsafe by himself ... but we must look for rejected calls after disposing!
+ // But we must work with E_SOFTEXCEPTIONS ... because sometimes we are called from our listeners
+ // during dispose! Our work mode is E_BEFORECLOSE then ... and E_HARDEXCEPTIONS whould throw a DisposedException.
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( (const css::uno::Reference< css::frame::XFrameActionListener >*)NULL ), xListener );
+}
+
+/*-****************************************************************************************************//**
+ @short support two way mechanism to release a frame
+ @descr This method ask internal component (controller) if he accept this close request.
+ In case of <TRUE/> nothing will be happen (from point of caller of this close method).
+ In case of <FALSE/> a CloseVetoException is thrown. After such exception given parameter
+ <var>bDeliverOwnerShip</var> regulate which will be the new owner of this instance.
+
+ @attention It's the replacement for XTask::close() which is marked as obsolete method.
+
+ @param bDeliverOwnerShip
+ If parameter is set to <FALSE/> the original caller will be the owner after thrown
+ veto exception and must try to close this frame at later time again. Otherwhise the
+ source of throwed exception is the right one. May it will be the frame himself.
+
+ @thrown CloseVetoException
+ if any internal things willn't be closed
+
+ @threadsafe yes
+ @modified 06.05.2002 08:33, as96863
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::close( sal_Bool bDeliverOwnerShip ) throw( css::util::CloseVetoException,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // At the end of this method may we must dispose ourself ...
+ // and may nobody from outside hold a reference to us ...
+ // then it's a good idea to do that by ourself.
+ css::uno::Reference< css::uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
+
+ // Check any close listener before we look for currently running internal processes.
+ // Because if a listener disagree with this close() request - we hace time to finish this
+ // internal operations too ...
+ // Note: container is threadsafe himself.
+ css::lang::EventObject aSource (static_cast< ::cppu::OWeakObject*>(this));
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >*) NULL ) );
+ if (pContainer!=NULL)
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ ((css::util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnerShip );
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+
+ // Ok - no listener disagreed with this close() request
+ // check if this frame is used for any load process currently
+ if (isActionLocked())
+ {
+ if (bDeliverOwnerShip)
+ {
+ /* SAFE */
+ WriteGuard aWriteLock( m_aLock );
+ m_bSelfClose = sal_True;
+ aWriteLock.unlock();
+ /* SAFE */
+ }
+
+ throw css::util::CloseVetoException(DECLARE_ASCII("Frame in use for loading document ..."),static_cast< ::cppu::OWeakObject*>(this));
+ }
+
+ if ( ! setComponent(NULL,NULL) )
+ throw css::util::CloseVetoException(DECLARE_ASCII("Component couldn't be deattached ..."),static_cast< ::cppu::OWeakObject*>(this));
+
+ // If closing is allowed ... inform all istener and dispose this frame!
+ pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >*) NULL ) );
+ if (pContainer!=NULL)
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ ((css::util::XCloseListener*)pIterator.next())->notifyClosing( aSource );
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_bIsHidden = sal_True;
+ aWriteLock.unlock();
+ /* } SAFE */
+ impl_checkMenuCloser();
+
+ // Attention: We must release our own registered transaction here. Otherwhise following dispose() call
+ // wait for us too ....
+ aTransaction.stop();
+ dispose();
+}
+
+/*-****************************************************************************************************//**
+ @short be a listener for close events!
+ @descr Adds/remove a CloseListener at this frame instance. If the close() method is called on
+ this object, the such listener are informed and can disagree with that by throwing
+ a CloseVetoException.
+
+ @seealso Frame::close()
+
+ @param xListener
+ reference to your listener object
+
+ @onerror Listener is ignored.
+
+ @threadsafe yes
+ @modified 06.05.2002 10:03, as96863
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::addCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ // We doesn't need any lock here ...
+ // Container lives if we live and is threadsafe by himself.
+ m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >* ) NULL ), xListener );
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::removeCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException)
+{
+ // Use soft exception mode - moslty this method is called during disposing of this frame ...
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+ // We doesn't need any lock here ...
+ // Container lives if we live and is threadsafe by himself.
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >* ) NULL ), xListener );
+}
+
+//*****************************************************************************************************************
+::rtl::OUString SAL_CALL Frame::getTitle()
+ throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XTitle > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ return xTitle->getTitle();
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::setTitle( const ::rtl::OUString& sTitle )
+ throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XTitle > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ xTitle->setTitle(sTitle);
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::addTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener)
+ throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ xTitle->addTitleChangeListener(xListener);
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::removeTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener )
+ throw (css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XTitleChangeBroadcaster > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ xTitle->removeTitleChangeListener(xListener);
+}
+
+/*-****************************************************************************************************/
+void Frame::implts_forgetSubFrames()
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::container::XIndexAccess > xContainer(m_xFramesHelper, css::uno::UNO_QUERY_THROW);
+ aReadLock.unlock();
+ // <- SAFE
+
+ sal_Int32 c = xContainer->getCount();
+ sal_Int32 i = 0;
+
+ for (i=0; i<c; ++i)
+ {
+ try
+ {
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ xContainer->getByIndex(i) >>= xFrame;
+ if (xFrame.is())
+ xFrame->setCreator(css::uno::Reference< css::frame::XFramesSupplier >());
+ }
+ catch(const css::uno::Exception&)
+ {
+ // Ignore errors here.
+ // Nobody can guarantee a stable index in multi threaded environments .-)
+ }
+ }
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ m_xFramesHelper.clear(); // clear uno reference
+ m_aChildFrameContainer.clear(); // clear container content
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+/*-****************************************************************************************************//**
+ @short destroy instance
+ @descr The owner of this object calles the dispose method if the object
+ should be destroyed. All other objects and components, that are registered
+ as an EventListener are forced to release their references to this object.
+ Furthermore this frame is removed from its parent frame container to release
+ this reference. The reference attributes are disposed and released also.
+
+ @attention Look for globale description at beginning of file too!
+ (DisposedException, FairRWLock ..., initialize, dispose)
+
+ @seealso method initialize()
+ @seealso baseclass FairRWLockBase!
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::dispose() throw( css::uno::RuntimeException )
+{
+ // We should hold a reference to ourself ...
+ // because our owner dispose us and release our reference ...
+ // May be we will die before we could finish this method ...
+ css::uno::Reference< css::frame::XFrame > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+
+ LOG_DISPOSEEVENT( "Frame", sName )
+
+ // First operation should be ... "stopp all listening for window events on our container window".
+ // These events are superflous but can make trouble!
+ // We will die, die and die ...
+ implts_stopWindowListening();
+
+ delete m_pWindowCommandDispatch;
+
+ // Send message to all listener and forget her references.
+ css::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ // set "end of live" for our property set helper
+ impl_disablePropertySet();
+
+ // interception/dispatch chain must be destructed explicitly
+ // Otherwhise some dispatches and/or interception objects wont die.
+ css::uno::Reference< css::lang::XEventListener > xDispatchHelper(m_xDispatchHelper, css::uno::UNO_QUERY_THROW);
+ xDispatchHelper->disposing(aEvent);
+ xDispatchHelper.clear();
+
+ // Disable this instance for further work.
+ // This will wait for all current running ones ...
+ // and reject all further requests!
+ m_aTransactionManager.setWorkingMode( E_BEFORECLOSE );
+
+ // Don't show any dialogs, errors or something else any more!
+ // If somewhere called dispose() whitout close() before - normaly no dialogs
+ // should exist. Otherwhise it's the problem of the outside caller.
+ // Note:
+ // (a) Do it after stopWindowListening(). May that force some active/deactive
+ // notifications which we doesn't need here realy.
+ // (b) Don't forget to save the old value of IsDialogCancelEnabled() to
+ // restore it afterwards. We cannot call EnableDialogCancel( sal_False )
+ // as we would kill the headless mode!
+ sal_Bool bCancelDialogs( Application::IsDialogCancelEnabled() );
+ Application::EnableDialogCancel( sal_True );
+
+ // We should be alone for ever and further dispose calls are rejected by lines before ...
+ // I hope it :-)
+
+ // Free references of our frame tree.
+ // Force parent container to forget this frame too ...
+ // ( It's contained in m_xParent and so no css::lang::XEventListener for m_xParent! )
+ // It's important to do that before we free some other internal structures.
+ // Because if our parent gets an activate and found us as last possible active frame
+ // he try to deactivate us ... and we run into some trouble (DisposedExceptions!).
+ if( m_xParent.is() == sal_True )
+ {
+ m_xParent->getFrames()->remove( xThis );
+ m_xParent = css::uno::Reference< css::frame::XFramesSupplier >();
+ }
+
+ /* } SAFE */
+ // Forget our internal component and her window first.
+ // So we can release our container window later without problems.
+ // Because this container window is the parent of the component window ...
+ // Note: Dispose it hard - because suspending must be done inside close() call!
+ // But try to dispose the controller first befor you destroy the window.
+ // Because the window is used by the controller too ...
+ if (m_xController.is())
+ {
+ css::uno::Reference< css::lang::XComponent > xDisposable( m_xController, css::uno::UNO_QUERY );
+ if (xDisposable.is())
+ xDisposable->dispose();
+ }
+
+ if (m_xComponentWindow.is())
+ {
+ css::uno::Reference< css::lang::XComponent > xDisposable( m_xComponentWindow, css::uno::UNO_QUERY );
+ if (xDisposable.is())
+ xDisposable->dispose();
+ }
+
+ impl_checkMenuCloser();
+
+ impl_disposeContainerWindow( m_xContainerWindow );
+
+ /*ATTENTION
+ Clear container after successful removing from parent container ...
+ because our parent could be the desktop which stand in dispose too!
+ If we have already cleared our own container we lost our child before this could be
+ remove himself at this instance ...
+ Release m_xFramesHelper after that ... it's the same problem between parent and child!
+ "m_xParent->getFrames()->remove( xThis );" needs this helper ...
+ Otherwise we get a null reference and could finish removing successfuly.
+ => You see: Order of calling operations is important!!!
+ */
+ implts_forgetSubFrames();
+
+ // Release some other references.
+ // This calls should be easy ... I hope it :-)
+ m_xDispatchHelper.clear();
+ m_xFactory.clear();
+ m_xDropTargetListener.clear();
+ m_xDispatchRecorderSupplier.clear();
+ m_xLayoutManager.clear();
+ m_xIndicatorFactoryHelper.clear();
+
+ // It's important to set default values here!
+ // If may be later somewhere change the disposed-behaviour of this implementation
+ // and doesn't throw any DisposedExceptions we must guarantee best matching default values ...
+ m_eActiveState = E_INACTIVE;
+ m_sName = ::rtl::OUString();
+ m_bIsFrameTop = sal_False;
+ m_bConnected = sal_False;
+ m_nExternalLockCount = 0;
+ m_bSelfClose = sal_False;
+ m_bIsHidden = sal_True;
+
+ // Disable this instance for further working realy!
+ m_aTransactionManager.setWorkingMode( E_CLOSE );
+
+ // Don't forget it restore old value -
+ // otherwhise no dialogs can be shown anymore in other frames.
+ Application::EnableDialogCancel( bCancelDialogs );
+}
+
+/*-****************************************************************************************************//**
+ @short Be a listener for dispose events!
+ @descr Adds/remove an EventListener to this object. If the dispose method is called on
+ this object, the disposing method of the listener is called.
+
+ @seealso -
+
+ @param "xListener" reference to your listener object.
+ @return -
+
+ @onerror Listener is ignored.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_addEventListener( xListener ), "Frame::addEventListener()", "Invalid parameter detected." )
+ // Look for rejected calls only!
+ // Container is threadsafe.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_removeEventListener( xListener ), "Frame::removeEventListener()", "Invalid parameter detected." )
+ // Look for rejected calls only!
+ // Container is threadsafe.
+ // Use E_SOFTEXCEPTIONS to allow removing listeners during dispose call!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
+}
+
+/*-****************************************************************************************************//**
+ @short create new status indicator
+ @descr Use returned status indicator to show progresses and some text informations.
+ All created objects share the same dialog! Only the last one can show his information.
+
+ @seealso class StatusIndicatorFactory
+ @seealso class StatusIndicator
+
+ @param -
+ @return A reference to created object.
+
+ @onerror We return a null reference.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::task::XStatusIndicator > SAL_CALL Frame::createStatusIndicator() throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
+ // Look for rejected calls!
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ // Make snapshot of neccessary member and define default return value.
+ css::uno::Reference< css::task::XStatusIndicator > xExternal(m_xIndicatorInterception.get(), css::uno::UNO_QUERY);
+ css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory = m_xIndicatorFactoryHelper;
+
+ aReadLock.unlock();
+ /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
+
+ // Was set from outside to intercept any progress activities!
+ if (xExternal.is())
+ return xExternal;
+
+ // Or use our own factory as fallback, to create such progress.
+ if (xFactory.is())
+ return xFactory->createStatusIndicator();
+
+ return css::uno::Reference< css::task::XStatusIndicator >();
+}
+
+/*-****************************************************************************************************//**
+ @short search for target to load URL
+ @descr This method searches for a dispatch for the specified DispatchDescriptor.
+ The FrameSearchFlags and the FrameName of the DispatchDescriptor are
+ treated as described for findFrame.
+
+ @seealso method findFrame()
+ @seealso method queryDispatches()
+ @seealso method set/getName()
+ @seealso class TargetFinder
+
+ @param "aURL" , URL for loading
+ @param "sTargetFrameName" , name of target frame
+ @param "nSearchFlags" , additional flags to regulate search if sTargetFrameName isn't clear
+ @return css::uno::Reference to dispatch handler.
+
+ @onerror A null reference is returned.
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XDispatch > SAL_CALL Frame::queryDispatch( const css::util::URL& aURL ,
+ const ::rtl::OUString& sTargetFrameName,
+ sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
+{
+ const char UNO_PROTOCOL[] = ".uno:";
+
+ // Don't check incoming parameter here! Our helper do it for us and it isn't a good idea to do it more then ones!
+ // But look for rejected calls!
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // Remove uno and cmd protocol part as we want to support both of them. We store only the command part
+ // in our hash map. All other protocols are stored with the protocol part.
+ String aCommand( aURL.Main );
+ if ( aURL.Protocol.equalsIgnoreAsciiCaseAsciiL( UNO_PROTOCOL, sizeof( UNO_PROTOCOL )-1 ))
+ aCommand = aURL.Path;
+
+ // Make boost::unordered_map lookup if the current URL is in the disabled list
+ if ( m_aCommandOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aCommand ) )
+ return css::uno::Reference< css::frame::XDispatch >();
+ else
+ {
+ // We use a helper to support these interface and an interceptor mechanism.
+ // Our helper is threadsafe by himself!
+ return m_xDispatchHelper->queryDispatch( aURL, sTargetFrameName, nSearchFlags );
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short handle more then ones dispatches at same call
+ @descr Returns a sequence of dispatches. For details see the queryDispatch method.
+ For failed dispatches we return empty items in list!
+
+ @seealso method queryDispatch()
+
+ @param "lDescriptor" list of dispatch arguments for queryDispatch()!
+ @return List of dispatch references. Some elements can be NULL!
+
+ @onerror An empty list is returned.
+*//*-*****************************************************************************************************/
+css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL Frame::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException )
+{
+ // Don't check incoming parameter here! Our helper do it for us and it isn't a good idea to do it more then ones!
+ // But look for rejected calls!
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ // We use a helper to support these interface and an interceptor mechanism.
+ // Our helper is threadsafe by himself!
+ return m_xDispatchHelper->queryDispatches( lDescriptor );
+}
+
+/*-****************************************************************************************************//**
+ @short register/unregister interceptor for dispatch calls
+ @descr If you whish to handle some dispatches by himself ... you should be
+ an interceptor for it. Please see class OInterceptionHelper for further informations.
+
+ @seealso class OInterceptionHelper
+
+ @param "xInterceptor", reference to your interceptor implementation.
+ @return -
+
+ @onerror Interceptor is ignored.
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException )
+{
+ // We use a helper to support these interface and an interceptor mechanism.
+ // This helper is threadsafe himself and check incoming parameter too.
+ // I think we don't need any lock here!
+ // But we must look for rejected calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
+ xInterceptionHelper->registerDispatchProviderInterceptor( xInterceptor );
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::releaseDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException )
+{
+ // We use a helper to support these interface and an interceptor mechanism.
+ // This helper is threadsafe himself and check incoming parameter too.
+ // I think we don't need any lock here!
+ // But we must look for rejected calls ...
+ // Sometimes we are called during our dispose() method ... => soft exceptions!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
+ xInterceptionHelper->releaseDispatchProviderInterceptor( xInterceptor );
+}
+
+/*-****************************************************************************************************//**
+ @short provides information about all possible dispatch functions
+ inside the currnt frame environment
+*//*-*****************************************************************************************************/
+css::uno::Sequence< sal_Int16 > SAL_CALL Frame::getSupportedCommandGroups()
+ throw(css::uno::RuntimeException)
+{
+ return m_xDispatchInfoHelper->getSupportedCommandGroups();
+}
+
+//*****************************************************************************************************************
+css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL Frame::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
+ throw(css::uno::RuntimeException)
+{
+ return m_xDispatchInfoHelper->getConfigurableDispatchInformation(nCommandGroup);
+}
+
+/*-****************************************************************************************************//**
+ @short notifications for window events
+ @descr We are a listener on our container window to forward it to our component window.
+
+ @seealso method setComponent()
+ @seealso member m_xContainerWindow
+ @seealso member m_xComponentWindow
+
+ @param "aEvent" describe source of detected event
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::windowResized( const css::awt::WindowEvent&
+#if OSL_DEBUG_LEVEL > 0
+aEvent
+#endif
+) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_windowResized( aEvent ), "Frame::windowResized()", "Invalid parameter detected." )
+ // Look for rejected calls.
+ // Part of dispose-mechanism => soft exceptions
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Impl-method is threadsafe!
+ // If we have a current component window - we must resize it!
+ implts_resizeComponentWindow();
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::focusGained( const css::awt::FocusEvent&
+#if OSL_DEBUG_LEVEL > 0
+aEvent
+#endif
+) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_focusGained( aEvent ), "Frame::focusGained()", "Invalid parameter detected." )
+ // Look for rejected calls.
+ // Part of dispose() mechanism ... => soft exceptions!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+ // Make snapshot of member!
+ css::uno::Reference< css::awt::XWindow > xComponentWindow = m_xComponentWindow;
+ aReadLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ if( xComponentWindow.is() == sal_True )
+ {
+ xComponentWindow->setFocus();
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short notifications for window events
+ @descr We are a listener on our container window to forward it to our component window ...
+ but a XTopWindowListener we are only if we are a top frame!
+
+ @seealso method setComponent()
+ @seealso member m_xContainerWindow
+ @seealso member m_xComponentWindow
+
+ @param "aEvent" describe source of detected event
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::windowActivated( const css::lang::EventObject&
+#if OSL_DEBUG_LEVEL > 0
+aEvent
+#endif
+) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_windowActivated( aEvent ), "Frame::windowActivated()", "Invalid parameter detected." )
+ // Look for rejected calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+ // Make snapshot of member!
+ EActiveState eState = m_eActiveState;
+ aReadLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Activate the new active path from here to top.
+ if( eState == E_INACTIVE )
+ {
+ setActiveFrame( css::uno::Reference< css::frame::XFrame >() );
+ activate();
+ }
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::windowDeactivated( const css::lang::EventObject&
+#if OSL_DEBUG_LEVEL > 0
+aEvent
+#endif
+) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_windowDeactivated( aEvent ), "Frame::windowDeactivated()", "Invalid parameter detected." )
+ // Look for rejected calls.
+ // Sometimes called during dispose() => soft exceptions
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+
+ css::uno::Reference< css::frame::XFrame > xParent ( m_xParent, css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
+ EActiveState eActiveState = m_eActiveState ;
+
+ aReadLock.unlock();
+
+ if( eActiveState != E_INACTIVE )
+ {
+ // Deactivation is always done implicitely by activation of another frame.
+ // Only if no activation is done, deactivations have to be processed if the activated window
+ // is a parent window of the last active Window!
+ SolarMutexClearableGuard aSolarGuard;
+ Window* pFocusWindow = Application::GetFocusWindow();
+ if (
+ ( xContainerWindow.is() == sal_True ) &&
+ ( xParent.is() == sal_True ) &&
+ ( (css::uno::Reference< css::frame::XDesktop >( xParent, css::uno::UNO_QUERY )).is() == sal_False )
+ )
+ {
+ css::uno::Reference< css::awt::XWindow > xParentWindow = xParent->getContainerWindow() ;
+ Window* pParentWindow = VCLUnoHelper::GetWindow( xParentWindow );
+ //#i70261#: dialogs opend from an OLE object will cause a deactivate on the frame of the OLE object
+ // on Solaris/Linux at that time pFocusWindow is still NULL because the focus handling is different; right after
+ // the deactivation the focus will be set into the dialog!
+ // currently I see no case where a sub frame could get a deactivate with pFocusWindow being NULL permanently
+ // so for now this case is omitted from handled deactivations
+ if( pFocusWindow && pParentWindow->IsChild( pFocusWindow ) )
+ {
+ css::uno::Reference< css::frame::XFramesSupplier > xSupplier( xParent, css::uno::UNO_QUERY );
+ if( xSupplier.is() == sal_True )
+ {
+ aSolarGuard.clear();
+ xSupplier->setActiveFrame( css::uno::Reference< css::frame::XFrame >() );
+ }
+ }
+ }
+ }
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::windowClosing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
+{
+ /* #i62088#
+ Some interceptor objects intercept our "internaly asynchronoues implemented" dispatch call.
+ And they close this frame directly (means synchronous then).
+ Means: Frame::windowClosing()->Frame::close()
+ In such situation its not a good idea to hold this transaction count alive .-)
+ */
+ {
+ // Look for rejected calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+ // deactivate this frame ...
+ deactivate();
+ }
+
+ // ... and try to close it
+ // But do it asynchron inside the main thread.
+ // VCL has no fun to do such things outside his main thread :-(
+ // Note: The used dispatch make it asynchronous for us .-)
+
+ /*ATTENTION!
+ Don't try to suspend the controller here! Because it's done inside used dispatch().
+ Otherwhise the dialog "would you save your changes?" will be shown more then once ...
+ */
+
+ /* SAFE */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
+ aReadLock.unlock();
+ /* SAFE */
+
+ css::util::URL aURL;
+ aURL.Complete = DECLARE_ASCII(".uno:CloseFrame");
+ css::uno::Reference< css::util::XURLTransformer > xParser(xFactory->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
+ xParser->parseStrict(aURL);
+
+ css::uno::Reference< css::frame::XDispatch > xCloser = queryDispatch(aURL, SPECIALTARGET_SELF, 0);
+ if (xCloser.is())
+ xCloser->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue >());
+
+ // Attention: If this dispatch works synchronous ... and full fill its job ...
+ // this line of code will never be reached ...
+ // Or if it will be reached it will be for sure that all your member are gone .-)
+}
+
+/*-****************************************************************************************************//**
+ @short react for a show event for the internal container window
+ @descr Normaly we doesn't need this information realy. But we can use it to
+ implement the special feature "trigger first visible task".
+
+ Algorithm: - first we have to check if we are a top (task) frame
+ It's not enough to be a top frame! Because we MUST have the desktop as parent.
+ But frames without a parent are top too. So it's not possible to check isTop() here!
+ We have to look for the type of our parent.
+ - if we are a task frame, then we have to check if we are the first one.
+ We use a static variable to do so. They will be reset to afterwards be shure
+ that further calls of this method doesn't do anything then.
+ - Then we have to trigger the right event string on the global job executor.
+
+ @seealso css::task::JobExecutor
+
+ @param aEvent
+ describes the source of this event
+ We are not interested on this information. We are interested on the visible state only.
+
+ @threadsafe yes
+ @modified 31.07.2002 07:56, as96863
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::windowShown( const css::lang::EventObject& ) throw(css::uno::RuntimeException)
+{
+ static sal_Bool bFirstVisibleTask = sal_True;
+
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XDesktop > xDesktopCheck( m_xParent, css::uno::UNO_QUERY );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
+ m_bIsHidden = sal_False;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ impl_checkMenuCloser();
+
+ if (xDesktopCheck.is())
+ {
+ /* STATIC SAFE { */
+ WriteGuard aStaticWriteLock( LockHelper::getGlobalLock() );
+ sal_Bool bMustBeTriggered = bFirstVisibleTask;
+ bFirstVisibleTask = sal_False;
+ aStaticWriteLock.unlock();
+ /* } STATIC SAFE */
+
+ if (bMustBeTriggered)
+ {
+ css::uno::Reference< css::task::XJobExecutor > xExecutor( xFactory->createInstance( SERVICENAME_JOBEXECUTOR ), css::uno::UNO_QUERY );
+ if (xExecutor.is())
+ {
+ xExecutor->trigger( DECLARE_ASCII("onFirstVisibleTask") );
+ }
+ }
+ }
+}
+
+void SAL_CALL Frame::windowHidden( const css::lang::EventObject& ) throw(css::uno::RuntimeException)
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ m_bIsHidden = sal_True;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ impl_checkMenuCloser();
+}
+
+/*-****************************************************************************************************//**
+ @short called by dispose of our windows!
+ @descr This object is forced to release all references to the interfaces given
+ by the parameter source. We are a listener at our container window and
+ should listen for his diposing.
+
+ @seealso XWindowListener
+ @seealso XTopWindowListener
+ @seealso XFocusListener
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void SAL_CALL Frame::disposing( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Check incoming parameter.
+ LOG_ASSERT2( implcp_disposing( aEvent ), "Frame::disposing()", "Invalid parameter detected." )
+ // Look for rejected calls.
+ // May be we are called during releasing our windows in our in dispose call!? => soft exceptions
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+
+ if( aEvent.Source == m_xContainerWindow )
+ {
+ // NECCESSARY: Impl-method is threadsafe by himself!
+ aWriteLock.unlock();
+ implts_stopWindowListening();
+ aWriteLock.lock();
+ m_xContainerWindow = css::uno::Reference< css::awt::XWindow >();
+ }
+}
+
+/*-************************************************************************************************************//**
+ @interface com.sun.star.document.XActionLockable
+ @short implement locking of frame/task from outside
+ @descr Sometimes we have problems to decide if closing of task is allowed. Because; frame/task
+ could be used for pending loading jobs. So you can lock this object from outside and
+ prevent instance against closing during using! But - don't do it in a wrong or expensive manner.
+ Otherwise task couldn't die anymore!!!
+
+ @seealso interface XActionLockable
+ @seeelso method BaseDispatcher::implts_loadIt()
+ @seeelso method Desktop::loadComponentFromURL()
+
+ @param -
+ @return true if frame/task is locked
+ false otherwise
+
+ @onerror -
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+sal_Bool SAL_CALL Frame::isActionLocked() throw( css::uno::RuntimeException )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ReadGuard aReadLock( m_aLock );
+ return( m_nExternalLockCount!=0);
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::addActionLock() throw( css::uno::RuntimeException )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ ++m_nExternalLockCount;
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::removeActionLock() throw( css::uno::RuntimeException )
+{
+ // Register no transaction here! Otherwhise we wait for ever inside possible
+ // implts_checkSuicide()/dispose() request ...
+
+ /* SAFE AREA */{
+ WriteGuard aWriteLock( m_aLock );
+ LOG_ASSERT2( m_nExternalLockCount<=0, "Frame::removeActionLock()", "Frame isn't locked! Possible multithreading problem detected." )
+ --m_nExternalLockCount;
+ }/* SAFE */
+
+ implts_checkSuicide();
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::setActionLocks( sal_Int16 nLock ) throw( css::uno::RuntimeException )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ WriteGuard aWriteLock( m_aLock );
+ // Attention: If somewhere called resetActionLocks() before and get e.g. 5 locks ...
+ // and tried to set these 5 ones here after his operations ...
+ // we can't ignore setted requests during these two calls!
+ // So we must add(!) these 5 locks here.
+ m_nExternalLockCount = m_nExternalLockCount + nLock;
+}
+
+//*****************************************************************************************************************
+sal_Int16 SAL_CALL Frame::resetActionLocks() throw( css::uno::RuntimeException )
+{
+ // Register no transaction here! Otherwhise we wait for ever inside possible
+ // implts_checkSuicide()/dispose() request ...
+
+ sal_Int16 nCurrentLocks = 0;
+ /* SAFE */{
+ WriteGuard aWriteLock( m_aLock );
+ nCurrentLocks = m_nExternalLockCount;
+ m_nExternalLockCount = 0;
+ }/* SAFE */
+
+ // Attention:
+ // external lock count is 0 here every time ... but if
+ // member m_bSelfClose is set to true too .... we call our own close()/dispose().
+ // See close() for further informations
+ implts_checkSuicide();
+
+ return nCurrentLocks;
+}
+
+//*****************************************************************************************************************
+void Frame::impl_initializePropInfo()
+{
+ impl_setPropertyChangeBroadcaster(static_cast< css::frame::XFrame* >(this));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ FRAME_PROPNAME_DISPATCHRECORDERSUPPLIER,
+ FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER,
+ ::getCppuType((const css::uno::Reference< css::frame::XDispatchRecorderSupplier >*)NULL),
+ css::beans::PropertyAttribute::TRANSIENT));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ FRAME_PROPNAME_INDICATORINTERCEPTION,
+ FRAME_PROPHANDLE_INDICATORINTERCEPTION,
+ ::getCppuType((const css::uno::Reference< css::task::XStatusIndicator >*)NULL),
+ css::beans::PropertyAttribute::TRANSIENT));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ FRAME_PROPNAME_ISHIDDEN,
+ FRAME_PROPHANDLE_ISHIDDEN,
+ ::getBooleanCppuType(),
+ css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ FRAME_PROPNAME_LAYOUTMANAGER,
+ FRAME_PROPHANDLE_LAYOUTMANAGER,
+ ::getCppuType((const css::uno::Reference< ::com::sun::star::frame::XLayoutManager >*)NULL),
+ css::beans::PropertyAttribute::TRANSIENT));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ FRAME_PROPNAME_TITLE,
+ FRAME_PROPHANDLE_TITLE,
+ ::getCppuType((const ::rtl::OUString*)NULL),
+ css::beans::PropertyAttribute::TRANSIENT));
+}
+
+//*****************************************************************************************************************
+void SAL_CALL Frame::impl_setPropertyValue(const ::rtl::OUString& /*sProperty*/,
+ sal_Int32 nHandle ,
+ const css::uno::Any& aValue )
+
+{
+ static ::rtl::OUString MATERIALPROP_TITLE(RTL_CONSTASCII_USTRINGPARAM("title"));
+
+ /* There is no need to lock any mutex here. Because we share the
+ solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
+ see ctor of PropertySetHelper for further informations.
+ */
+
+ /* Attention: You can use nHandle only, if you are sure that all supported
+ properties has an unique handle. That must be guaranteed
+ inside method impl_initializePropInfo()!
+ */
+ switch (nHandle)
+ {
+ case FRAME_PROPHANDLE_TITLE :
+ {
+ ::rtl::OUString sExternalTitle;
+ aValue >>= sExternalTitle;
+ setTitle (sExternalTitle);
+ }
+ break;
+
+ case FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
+ aValue >>= m_xDispatchRecorderSupplier;
+ break;
+
+ case FRAME_PROPHANDLE_LAYOUTMANAGER :
+ {
+ css::uno::Reference< css::frame::XLayoutManager > xOldLayoutManager = m_xLayoutManager;
+ css::uno::Reference< css::frame::XLayoutManager > xNewLayoutManager;
+ aValue >>= xNewLayoutManager;
+
+ if (xOldLayoutManager != xNewLayoutManager)
+ {
+ m_xLayoutManager = xNewLayoutManager;
+ if (xOldLayoutManager.is())
+ lcl_disableLayoutManager(xOldLayoutManager, this);
+ if (xNewLayoutManager.is())
+ lcl_enableLayoutManager(xNewLayoutManager, this);
+ }
+ }
+ break;
+
+ case FRAME_PROPHANDLE_INDICATORINTERCEPTION :
+ {
+ css::uno::Reference< css::task::XStatusIndicator > xProgress;
+ aValue >>= xProgress;
+ m_xIndicatorInterception = xProgress;
+ }
+ break;
+
+ #ifdef ENABLE_WARNINGS
+ default :
+ LOG_WARNING( "Frame::setFastPropertyValue_NoBroadcast()", "Invalid handle detected!" )
+ break;
+ #endif
+ }
+}
+
+//*****************************************************************************************************************
+css::uno::Any SAL_CALL Frame::impl_getPropertyValue(const ::rtl::OUString& /*sProperty*/,
+ sal_Int32 nHandle )
+{
+ /* There is no need to lock any mutex here. Because we share the
+ solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
+ see ctor of PropertySetHelper for further informations.
+ */
+
+ /* Attention: You can use nHandle only, if you are sure that all supported
+ properties has an unique handle. That must be guaranteed
+ inside method impl_initializePropInfo()!
+ */
+ css::uno::Any aValue;
+ switch (nHandle)
+ {
+ case FRAME_PROPHANDLE_TITLE :
+ aValue <<= getTitle ();
+ break;
+
+ case FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
+ aValue <<= m_xDispatchRecorderSupplier;
+ break;
+
+ case FRAME_PROPHANDLE_ISHIDDEN :
+ aValue <<= m_bIsHidden;
+ break;
+
+ case FRAME_PROPHANDLE_LAYOUTMANAGER :
+ aValue <<= m_xLayoutManager;
+ break;
+
+ case FRAME_PROPHANDLE_INDICATORINTERCEPTION :
+ {
+ css::uno::Reference< css::task::XStatusIndicator > xProgress(m_xIndicatorInterception.get(), css::uno::UNO_QUERY);
+ aValue = css::uno::makeAny(xProgress);
+ }
+ break;
+
+ #ifdef ENABLE_WARNINGS
+ default :
+ LOG_WARNING( "Frame::getFastPropertyValue()", "Invalid handle detected!" )
+ break;
+ #endif
+ }
+
+ return aValue;
+}
+
+/*-****************************************************************************************************//**
+ @short dispose old container window and forget his reference
+ @descr Sometimes we must repair our "modal dialog parent mechanism" too!
+
+ @seealso -
+
+ @param "xWindow", reference to old container window to dispose it
+ @return An empty reference.
+
+ @onerror -
+ @threadsafe NO!
+*//*-*****************************************************************************************************/
+void Frame::impl_disposeContainerWindow( css::uno::Reference< css::awt::XWindow >& xWindow )
+{
+ if( xWindow.is() == sal_True )
+ {
+ xWindow->setVisible( sal_False );
+ // All VclComponents are XComponents; so call dispose before discarding
+ // a css::uno::Reference< XVclComponent >, because this frame is the owner of the window
+ xWindow->dispose();
+ xWindow = css::uno::Reference< css::awt::XWindow >();
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short send frame action event to our listener
+ @descr This method is threadsafe AND can be called by our dispose method too!
+
+ @seealso -
+
+ @param "aAction", describe the event for sending
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void Frame::implts_sendFrameActionEvent( const css::frame::FrameAction& aAction )
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Sometimes used by dispose() => soft exceptions!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ // Log informations about order of events to file!
+ // (only activated in debug version!)
+ LOG_FRAMEACTIONEVENT( "Frame", m_sName, aAction )
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Send css::frame::FrameAction event to all listener.
+ // Get container for right listener.
+ // FOLLOW LINES ARE THREADSAFE!!!
+ // ( OInterfaceContainerHelper is synchronized with m_aListenerContainer! )
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XFrameActionListener >*) NULL ) );
+
+ if( pContainer != NULL )
+ {
+ // Build action event.
+ css::frame::FrameActionEvent aFrameActionEvent( static_cast< ::cppu::OWeakObject* >(this), this, aAction );
+
+ // Get iterator for access to listener.
+ ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
+ // Send message to all listener.
+ while( aIterator.hasMoreElements() == sal_True )
+ {
+ try
+ {
+ ((css::frame::XFrameActionListener*)aIterator.next())->frameAction( aFrameActionEvent );
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ aIterator.remove();
+ }
+ }
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short helper to resize our component window
+ @descr A frame contains 2 windows - a container ~ and a component window.
+ This method resize inner component window to full size of outer container window.
+ This method is threadsafe AND can be called by our dispose method too!
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+*//*-*****************************************************************************************************/
+void Frame::implts_resizeComponentWindow()
+{
+ // usually the LayoutManager does the resizing
+ // in case there is no LayoutManager resizing has to be done here
+ if ( !m_xLayoutManager.is() )
+ {
+ css::uno::Reference< css::awt::XWindow > xComponentWindow( getComponentWindow() );
+ if( xComponentWindow.is() == sal_True )
+ {
+ css::uno::Reference< css::awt::XDevice > xDevice( getContainerWindow(), css::uno::UNO_QUERY );
+
+ // Convert relativ size to output size.
+ css::awt::Rectangle aRectangle = getContainerWindow()->getPosSize();
+ css::awt::DeviceInfo aInfo = xDevice->getInfo();
+ css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
+ aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
+
+ // Resize our component window.
+ xComponentWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE );
+ }
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short helper to set icon on our container window (if it is a system window!)
+ @descr We use our internal set controller (if it exist) to specify which factory he represanted.
+ These information can be used to find right icon. But our controller can say it us directly
+ too ... we should ask his optional property set first ...
+
+ @seealso method Window::SetIcon()
+
+ @param -
+ @return -
+
+ @onerror We do nothing.
+*//*-*****************************************************************************************************/
+void Frame::implts_setIconOnWindow()
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Look for rejected calls.
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Make snapshot of neccessary members and release lock.
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow, css::uno::UNO_QUERY );
+ css::uno::Reference< css::frame::XController > xController ( m_xController , css::uno::UNO_QUERY );
+ aReadLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ if(
+ ( xContainerWindow.is() == sal_True ) &&
+ ( xController.is() == sal_True )
+ )
+ {
+ //-------------------------------------------------------------------------------------------------------------
+ // a) set default value to an invalid one. So we can start further searches for right icon id, if
+ // first steps failed!
+ // We must reset it to any fallback value - if no search step returns a valid result.
+ sal_Int32 nIcon = -1;
+
+ //-------------------------------------------------------------------------------------------------------------
+ // b) try to find information on controller propertyset directly
+ // Don't forget to catch possible exceptions - because these property is an optional one!
+ css::uno::Reference< css::beans::XPropertySet > xSet( xController, css::uno::UNO_QUERY );
+ if( xSet.is() == sal_True )
+ {
+ try
+ {
+ xSet->getPropertyValue( DECLARE_ASCII("IconId") )>>= nIcon;
+ }
+ catch( css::beans::UnknownPropertyException& )
+ {
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------
+ // c) if b) failed ... analyze argument list of currently loaded document insde the frame to find the filter.
+ // He can be used to detect right factory - and these can be used to match factory to icon ...
+ if( nIcon == -1 )
+ {
+ css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
+ if( xModel.is() == sal_True )
+ {
+ SvtModuleOptions::EFactory eFactory = SvtModuleOptions::ClassifyFactoryByModel(xModel);
+ if (eFactory != SvtModuleOptions::E_UNKNOWN_FACTORY)
+ nIcon = SvtModuleOptions().GetFactoryIcon( eFactory );
+ }
+ }
+
+ //-------------------------------------------------------------------------------------------------------------
+ // d) if all steps failed - use fallback!
+ if( nIcon == -1 )
+ {
+ nIcon = 0;
+ }
+
+ //-------------------------------------------------------------------------------------------------------------
+ // e) set icon on container window now
+ // Don't forget SolarMutex! We use vcl directly :-(
+ // Check window pointer for right WorkWindow class too!!!
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ {
+ SolarMutexGuard aSolarGuard;
+ Window* pWindow = (VCLUnoHelper::GetWindow( xContainerWindow ));
+ if(
+ ( pWindow != NULL ) &&
+ ( pWindow->GetType() == WINDOW_WORKWINDOW )
+ )
+ {
+ WorkWindow* pWorkWindow = (WorkWindow*)pWindow;
+ pWorkWindow->SetIcon( (sal_uInt16)nIcon );
+ }
+ }
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ }
+}
+
+/*-************************************************************************************************************//**
+ @short helper to start/stop listeneing for window events on container window
+ @descr If we get a new container window, we must set it on internal memeber ...
+ and stop listening at old one ... and start listening on new one!
+ But sometimes (in dispose() call!) it's neccessary to stop listeneing without starting
+ on new connections. So we split this functionality to make it easier at use.
+
+ @seealso method initialize()
+ @seealso method dispose()
+
+ @param -
+ @return -
+
+ @onerror We do nothing!
+ @threadsafe yes
+*//*-*************************************************************************************************************/
+void Frame::implts_startWindowListening()
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Make snapshot of neccessary member!
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow ;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory ;
+ css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > xDragDropListener = m_xDropTargetListener;
+ css::uno::Reference< css::awt::XWindowListener > xWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XFocusListener > xFocusListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XTopWindowListener > xTopWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ aReadLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ if( xContainerWindow.is() == sal_True )
+ {
+ xContainerWindow->addWindowListener( xWindowListener);
+ xContainerWindow->addFocusListener ( xFocusListener );
+
+ css::uno::Reference< css::awt::XTopWindow > xTopWindow( xContainerWindow, css::uno::UNO_QUERY );
+ if( xTopWindow.is() == sal_True )
+ {
+ xTopWindow->addTopWindowListener( xTopWindowListener );
+
+ css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer( xFactory->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
+ if( xTransfer.is() == sal_True )
+ {
+ css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget( xContainerWindow );
+ if( xDropTarget.is() == sal_True )
+ {
+ xDropTarget->addDropTargetListener( xDragDropListener );
+ xDropTarget->setActive( sal_True );
+ }
+ }
+ }
+ }
+}
+
+//*****************************************************************************************************************
+void Frame::implts_stopWindowListening()
+{
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+ // Sometimes used by dispose() => soft exceptions!
+ TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Make snapshot of neccessary member!
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow ;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory ;
+ css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > xDragDropListener = m_xDropTargetListener;
+ css::uno::Reference< css::awt::XWindowListener > xWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XFocusListener > xFocusListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XTopWindowListener > xTopWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ aReadLock.unlock();
+ /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
+
+ if( xContainerWindow.is() == sal_True )
+ {
+ xContainerWindow->removeWindowListener( xWindowListener);
+ xContainerWindow->removeFocusListener ( xFocusListener );
+
+ css::uno::Reference< css::awt::XTopWindow > xTopWindow( xContainerWindow, css::uno::UNO_QUERY );
+ if( xTopWindow.is() == sal_True )
+ {
+ xTopWindow->removeTopWindowListener( xTopWindowListener );
+
+ css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer( xFactory->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
+ if( xTransfer.is() == sal_True )
+ {
+ css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget( xContainerWindow );
+ if( xDropTarget.is() == sal_True )
+ {
+ xDropTarget->removeDropTargetListener( xDragDropListener );
+ xDropTarget->setActive( sal_False );
+ }
+ }
+ }
+ }
+}
+
+/*-****************************************************************************************************//**
+ @short helper to force breaked close() request again
+ @descr If we self disagree with a close() request, and detect that all external locks are gone ...
+ then we must try to close this frame again.
+
+ @seealso XCloseable::close()
+ @seealso Frame::close()
+ @seealso Frame::removeActionLock()
+ @seealso Frame::resetActionLock()
+ @seealso m_bSelfClose
+ @seealso m_nExternalLockCount
+
+ @threadsafe yes
+ @modified 06.05.2002 09:31, as96863
+*//*-*****************************************************************************************************/
+void Frame::implts_checkSuicide()
+{
+ /* SAFE */
+ ReadGuard aReadLock(m_aLock);
+ // in case of lock==0 and safed state of previous close() request m_bSelfClose
+ // we must force close() again. Because we had disagreed with that before.
+ sal_Bool bSuicide = (m_nExternalLockCount==0 && m_bSelfClose);
+ m_bSelfClose = sal_False;
+ aReadLock.unlock();
+ /* } SAFE */
+ // force close and deliver owner ship to source of possible throwed veto exception
+ // Attention: Because this method isn't designed to throw such exception we must supress
+ // it for outside code!
+ try
+ {
+ if (bSuicide)
+ close(sal_True);
+ }
+ catch(const css::util::CloseVetoException&)
+ {}
+ catch(const css::lang::DisposedException&)
+ {}
+}
+
+//_______________________________________________________________
+
+/** little helper to enable/disable the menu closer at the menubar of the given frame.
+
+ @param xFrame
+ we use its layout manager to set/reset a special callback.
+ Its existence regulate visibility of this closer item.
+
+ @param bState
+ <TRUE/> enable; <FALSE/> disable this state
+ */
+
+void Frame::impl_setCloser( /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame ,
+ /*IN*/ sal_Bool bState )
+{
+ // Note: If start module isnt installed - no closer has to be shown!
+ if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE))
+ return;
+
+ try
+ {
+ css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ xFrameProps->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
+ css::uno::Reference< css::beans::XPropertySet > xLayoutProps(xLayoutManager, css::uno::UNO_QUERY_THROW);
+ xLayoutProps->setPropertyValue(LAYOUTMANAGER_PROPNAME_MENUBARCLOSER, css::uno::makeAny(bState));
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+//_______________________________________________________________
+
+/** it checks, which of the top level task frames must have the special menu closer for
+ switching to the backing window mode.
+
+ It analyze the current list of visible top level frames. Only the last real document
+ frame can have this symbol. Not the help frame nor the backing task itself.
+ Here we do anything related to this closer. We remove it from the old frame and set it
+ for the new one.
+ */
+
+void Frame::impl_checkMenuCloser()
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+
+ // only top frames, which are part of our desktop hierarchy, can
+ // do so! By the way - we need the desktop instance to have acess
+ // to all other top level frames too.
+ css::uno::Reference< css::frame::XDesktop > xDesktop (m_xParent, css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XFramesSupplier > xTaskSupplier(xDesktop , css::uno::UNO_QUERY);
+ if ( !xDesktop.is() || !xTaskSupplier.is() )
+ return;
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ // analyze the list of current open tasks
+ // Suppress search for other views to the same model ...
+ // It's not needed here and can be very expensive.
+ FrameListAnalyzer aAnalyzer(
+ xTaskSupplier,
+ this,
+ FrameListAnalyzer::E_HIDDEN | FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT);
+
+ // specify the new frame, which must have this special state ...
+ css::uno::Reference< css::frame::XFrame > xNewCloserFrame;
+
+ // -----------------------------
+ // a)
+ // If there exist ate least one other frame - there are two frames currently open.
+ // But we can enable this closer only, if one of these two tasks includes the help module.
+ // The "other frame" couldn't be the help. Because then it wouldn't be part of this "other list".
+ // In such case it will be seperated to the reference aAnalyzer.m_xHelp!
+ // But we must check, if weself includes the help ...
+ // Check aAnalyzer.m_bReferenceIsHelp!
+ if (
+ (aAnalyzer.m_lOtherVisibleFrames.getLength()==1) &&
+ (
+ (aAnalyzer.m_bReferenceIsHelp ) ||
+ (aAnalyzer.m_bReferenceIsHidden)
+ )
+ )
+ {
+ // others[0] can't be the backing component!
+ // Because it's set at the special member aAnalyzer.m_xBackingComponent ... :-)
+ xNewCloserFrame = aAnalyzer.m_lOtherVisibleFrames[0];
+ }
+ else
+ // -----------------------------
+ // b)
+ // There is no other frame ... means no other document frame. The help module
+ // will be handled seperatly and must(!) be ignored here ... excepting weself includes the help.
+ if (
+ (aAnalyzer.m_lOtherVisibleFrames.getLength()==0) &&
+ (!aAnalyzer.m_bReferenceIsHelp ) &&
+ (!aAnalyzer.m_bReferenceIsHidden ) &&
+ (!aAnalyzer.m_bReferenceIsBacking )
+ )
+ {
+ xNewCloserFrame = this;
+ }
+
+ // Look for neccessary actions ...
+ // Only if the closer state must be moved from one frame to another one
+ // or must be enabled/disabled at all.
+ /* STATIC SAFE { */
+ WriteGuard aStaticWriteLock(LockHelper::getGlobalLock());
+ css::uno::Reference< css::frame::XFrame > xCloserFrame (m_xCloserFrame.get(), css::uno::UNO_QUERY);
+ if (xCloserFrame!=xNewCloserFrame)
+ {
+ if (xCloserFrame.is())
+ impl_setCloser(xCloserFrame, sal_False);
+ if (xNewCloserFrame.is())
+ impl_setCloser(xNewCloserFrame, sal_True);
+ m_xCloserFrame = xNewCloserFrame;
+ }
+ aStaticWriteLock.unlock();
+ /* } STATIC SAFE */
+}
+
+//_________________________________________________________________________________________________________________
+// debug methods
+//_________________________________________________________________________________________________________________
+
+/*-----------------------------------------------------------------------------------------------------------------
+ The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
+ we return "sal_True". (otherwise sal_False) This mechanism is used to throw an ASSERT!
+-----------------------------------------------------------------------------------------------------------------*/
+
+#ifdef ENABLE_ASSERTIONS
+
+//*****************************************************************************************************************
+// We don't accept null pointer or references!
+sal_Bool Frame::implcp_ctor( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+{
+ return (
+ ( &xFactory == NULL ) ||
+ ( xFactory.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+// Its allowed to reset the active frame membervariable with a NULL-css::uno::Reference but not with a NULL-pointer!
+// And we accept frames only! No tasks and desktops!
+sal_Bool Frame::implcp_setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ return (
+ ( &xFrame == NULL ) ||
+ ( css::uno::Reference< css::frame::XDesktop >( xFrame, css::uno::UNO_QUERY ).is() == sal_True )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener )
+{
+ return (
+ ( &xListener == NULL ) ||
+ ( xListener.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener )
+{
+ return (
+ ( &xListener == NULL ) ||
+ ( xListener.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+{
+ return (
+ ( &xListener == NULL ) ||
+ ( xListener.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+{
+ return (
+ ( &xListener == NULL ) ||
+ ( xListener.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_windowResized( const css::awt::WindowEvent& aEvent )
+{
+ return (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_focusGained( const css::awt::FocusEvent& aEvent )
+{
+ return (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_windowActivated( const css::lang::EventObject& aEvent )
+{
+ return (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_windowDeactivated( const css::lang::EventObject& aEvent )
+{
+ return (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ );
+}
+
+//*****************************************************************************************************************
+sal_Bool Frame::implcp_disposing( const css::lang::EventObject& aEvent )
+{
+ return (
+ ( &aEvent == NULL ) ||
+ ( aEvent.Source.is() == sal_False )
+ );
+}
+
+#endif // #ifdef ENABLE_ASSERTIONS
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/fwk_services.src b/framework/source/services/fwk_services.src
new file mode 100644
index 000000000000..d2368f9eacdc
--- /dev/null
+++ b/framework/source/services/fwk_services.src
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "framework.hrc"
+
+Window DLG_BACKING
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Border = FALSE;
+
+ String STR_BACKING_WELCOME
+ {
+ Text [ en-US ] = "Welcome to";
+ };
+ String STR_BACKING_WELCOMEPRODUCT
+ {
+ Text [ en-US ] = "%PRODUCTNAME";
+ };
+ String STR_BACKING_CREATE
+ {
+ Text [ en-US ] = "Create a new document";
+ };
+ String STR_BACKING_TEMPLATE
+ {
+ Text [ en-US ] = "~Templates...";
+ };
+ String STR_BACKING_FILE
+ {
+ Text [ en-US ] = "~Open...";
+ };
+ String STR_BACKING_EXTHELP
+ {
+ Text [ en-US ] = "Add new features to %PRODUCTNAME";
+ };
+ String STR_BACKING_REGHELP
+ {
+ Text [ en-US ] = "Register your %PRODUCTNAME";
+ };
+ String STR_BACKING_INFOHELP
+ {
+ Text [ en-US ] = "Get more information about %PRODUCTNAME";
+ };
+ String STR_BACKING_TPLREP
+ {
+ Text [ en-US ] = "Get more templates for %PRODUCTNAME";
+ };
+};
+
+Resource RES_BACKING_IMAGES
+{
+ Bitmap BMP_BACKING_EXT
+ {
+ File = "extension.png";
+ };
+ Bitmap BMP_BACKING_REG
+ {
+ File = "register_32.png";
+ };
+ Bitmap BMP_BACKING_INFO
+ {
+ File = "info_26.png";
+ };
+ Bitmap BMP_BACKING_TPLREP
+ {
+ File = "addtemplate_32.png";
+ };
+ Bitmap BMP_BACKING_WRITER
+ {
+ File = "odt_32.png";
+ };
+ Bitmap BMP_BACKING_CALC
+ {
+ File = "ods_32.png";
+ };
+ Bitmap BMP_BACKING_IMPRESS
+ {
+ File = "odp_32.png";
+ };
+ Bitmap BMP_BACKING_DRAW
+ {
+ File = "odg_32.png";
+ };
+ Bitmap BMP_BACKING_DATABASE
+ {
+ File = "odb_32.png";
+ };
+ Bitmap BMP_BACKING_FORMULA
+ {
+ File = "odf_32.png";
+ };
+ Bitmap BMP_BACKING_OPENFILE
+ {
+ File = "folder_32.png";
+ };
+ Bitmap BMP_BACKING_OPENTEMPLATE
+ {
+ File = "templates_32.png";
+ };
+};
+
+Window WIN_TABWINDOW
+{
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ TabControl TC_TABCONTROL
+ {
+ OutputSize = TRUE ;
+ };
+};
+
diff --git a/framework/source/services/license.cxx b/framework/source/services/license.cxx
new file mode 100644
index 000000000000..cdcb26e67f2d
--- /dev/null
+++ b/framework/source/services/license.cxx
@@ -0,0 +1,603 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <services/license.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <macros/debug.hxx>
+#include <services.h>
+
+// local header for UI implementation
+#include "services/licensedlg.hxx"
+#include "classes/resource.hrc"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#include <unotools/bootstrap.hxx>
+#include <osl/file.hxx>
+#include <svtools/xtextedt.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/date.hxx>
+#include <tools/time.hxx>
+#include <tools/datetime.hxx>
+#include <osl/file.hxx>
+#include <osl/time.h>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+using namespace utl;
+using namespace ::osl ;
+using namespace ::cppu ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star::beans ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::util ;
+using namespace ::com::sun::star::frame ;
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+// license file name
+static const char *szLicensePath = "/share/readme";
+#ifdef UNX
+static const char *szUNXLicenseName = "/LICENSE";
+static const char *szUNXLicenseExt = "";
+#elif defined(WNT) || defined(OS2)
+static const char *szWNTLicenseName = "/license";
+static const char *szWNTLicenseExt = ".txt";
+#endif
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+License::License( const Reference< XMultiServiceFactory >& xFactory )
+ // Init baseclasses first
+ // Attention:
+ // Don't change order of initialization!
+ // ThreadHelpBase is a struct with a mutex as member. We can't use a mutex as member, while
+ // we must garant right initialization and a valid value of this! First initialize
+ // baseclasses and then members. And we need the mutex for other baseclasses !!!
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , OWeakObject ( )
+ // Init member
+ , m_xFactory ( xFactory )
+ , m_bTerminate ( sal_False )
+{
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+License::~License()
+{
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+
+DEFINE_XINTERFACE_4 ( License ,
+ OWeakObject ,
+ DIRECT_INTERFACE(XTypeProvider ),
+ DIRECT_INTERFACE(XServiceInfo ),
+ DIRECT_INTERFACE(XJob ),
+ DIRECT_INTERFACE(XCloseable )
+ )
+
+DEFINE_XTYPEPROVIDER_4 ( License ,
+ XTypeProvider ,
+ XServiceInfo ,
+ XJob ,
+ XCloseable
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( License,
+ OWeakObject ,
+ SERVICENAME_LICENSE ,
+ IMPLEMENTATIONNAME_LICENSE
+ )
+
+DEFINE_INIT_SERVICE ( License,
+ {
+ }
+ )
+
+
+
+static DateTime _oslDateTimeToDateTime(const oslDateTime& aDateTime)
+{
+ return DateTime(
+ Date(aDateTime.Day, aDateTime.Month, aDateTime.Year),
+ Time(aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds));
+}
+
+static ::rtl::OUString _makeDateTimeString (const DateTime& aDateTime, sal_Bool bUTC = sal_False)
+{
+ ::rtl::OStringBuffer aDateTimeString;
+ aDateTimeString.append((sal_Int32)aDateTime.GetYear());
+ aDateTimeString.append("-");
+ if (aDateTime.GetMonth()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetMonth());
+ aDateTimeString.append("-");
+ if (aDateTime.GetDay()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetDay());
+ aDateTimeString.append("T");
+ if (aDateTime.GetHour()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetHour());
+ aDateTimeString.append(":");
+ if (aDateTime.GetMin()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetMin());
+ aDateTimeString.append(":");
+ if (aDateTime.GetSec()<10) aDateTimeString.append("0");
+ aDateTimeString.append((sal_Int32)aDateTime.GetSec());
+ if (bUTC) aDateTimeString.append("Z");
+
+ return OStringToOUString(aDateTimeString.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
+}
+
+static sal_Bool _parseDateTime(const ::rtl::OUString& aString, DateTime& aDateTime)
+{
+ // take apart a canonical literal xsd:dateTime string
+ //CCYY-MM-DDThh:mm:ss(Z)
+
+ ::rtl::OUString aDateTimeString = aString.trim();
+
+ // check length
+ if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
+ return sal_False;
+
+ sal_Int32 nDateLength = 10;
+ sal_Int32 nTimeLength = 8;
+
+ ::rtl::OUString aDateTimeSep(RTL_CONSTASCII_USTRINGPARAM("T"));
+ ::rtl::OUString aDateSep(RTL_CONSTASCII_USTRINGPARAM("-"));
+ ::rtl::OUString aTimeSep(RTL_CONSTASCII_USTRINGPARAM(":"));
+ ::rtl::OUString aUTCString(RTL_CONSTASCII_USTRINGPARAM("Z"));
+
+ ::rtl::OUString aDateString = aDateTimeString.copy(0, nDateLength);
+ ::rtl::OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength);
+
+ sal_Int32 nIndex = 0;
+ sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32();
+ sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32();
+ sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32();
+ nIndex = 0;
+ sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32();
+ sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32();
+ sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32();
+
+ Date tmpDate((sal_uInt16)nDay, (sal_uInt16)nMonth, (sal_uInt16)nYear);
+ Time tmpTime(nHour, nMinute, nSecond);
+ DateTime tmpDateTime(tmpDate, tmpTime);
+ if (aString.indexOf(aUTCString) < 0)
+ tmpDateTime.ConvertToUTC();
+
+ aDateTime = tmpDateTime;
+ return sal_True;
+}
+
+static ::rtl::OUString _getCurrentDateString()
+{
+ ::rtl::OUString aString;
+ return _makeDateTimeString(DateTime());
+}
+
+// execution of license check...
+css::uno::Any SAL_CALL License::execute(const css::uno::Sequence< css::beans::NamedValue >& )
+ throw( css::lang::IllegalArgumentException, css::uno::Exception)
+{
+ // return value
+ Any aRet; aRet <<= sal_False;
+
+ try
+ {
+ ::rtl::OUString aBaseInstallPath;
+ Bootstrap::PathStatus aBaseLocateResult =
+ Bootstrap::locateBaseInstallation(aBaseInstallPath);
+ if (aBaseLocateResult != Bootstrap::PATH_EXISTS)
+ {
+ aRet <<= sal_False;
+ return aRet;
+ }
+ // determine the filename of the license to show
+ ::rtl::OUString aLangString;
+ ::com::sun::star::lang::Locale aLocale;
+ AllSettings aSettings(Application::GetSettings());
+ aLocale = aSettings.GetUILocale();
+ ResMgr* pResMgr = ResMgr::SearchCreateResMgr("fwe", aLocale);
+
+ aLangString = aLocale.Language;
+ if ( aLocale.Country.getLength() != 0 )
+ {
+ aLangString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-"));
+ aLangString += aLocale.Country;
+ if ( aLocale.Variant.getLength() != 0 )
+ {
+ aLangString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-"));
+ aLangString += aLocale.Variant;
+ }
+ }
+#if defined(WNT) || defined(OS2)
+ ::rtl::OUString aLicensePath =
+ aBaseInstallPath + ::rtl::OUString::createFromAscii(szLicensePath)
+ + ::rtl::OUString::createFromAscii(szWNTLicenseName)
+ + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_"))
+ + aLangString
+ + ::rtl::OUString::createFromAscii(szWNTLicenseExt);
+#else
+ ::rtl::OUString aLicensePath =
+ aBaseInstallPath + ::rtl::OUString::createFromAscii(szLicensePath)
+ + ::rtl::OUString::createFromAscii(szUNXLicenseName)
+ + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_"))
+ + aLangString
+ + ::rtl::OUString::createFromAscii(szUNXLicenseExt);
+#endif
+ // check if we need to show the license at all
+ // open org.openoffice.Setup/Office/ooLicenseAcceptDate
+ ::rtl::OUString sConfigSrvc = SERVICENAME_CFGPROVIDER;
+ ::rtl::OUString sAccessSrvc(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationUpdateAccess"));
+ ::rtl::OUString sReadSrvc = SERVICENAME_CFGREADACCESS;
+
+ // get configuration provider
+ Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >(
+ m_xFactory->createInstance(sConfigSrvc), UNO_QUERY_THROW);
+ Sequence< Any > theArgs(1);
+ NamedValue v;
+ v.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NodePath"));
+ v.Value <<= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup/Office"));
+ theArgs[0] <<= v;
+ Reference< XPropertySet > pset = Reference< XPropertySet >(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW);
+
+ // if we find a date there, compare it to baseinstall license date
+ ::rtl::OUString aAcceptDate;
+ if (pset->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooLicenseAcceptDate"))) >>= aAcceptDate)
+ {
+ // get LicenseFileDate from base install
+ ::rtl::OUString aLicenseURL = aLicensePath;
+ DirectoryItem aDirItem;
+ if (DirectoryItem::get(aLicenseURL, aDirItem) != FileBase::E_None)
+ return makeAny(sal_False);
+ FileStatus aStatus(FileStatusMask_All);
+ if (aDirItem.getFileStatus(aStatus) != FileBase::E_None)
+ return makeAny(sal_False);
+ TimeValue aTimeVal = aStatus.getModifyTime();
+ oslDateTime aDateTimeVal;
+ if (!osl_getDateTimeFromTimeValue(&aTimeVal, &aDateTimeVal))
+ return makeAny(sal_False);
+
+ // compare dates
+ DateTime aLicenseDateTime = _oslDateTimeToDateTime(aDateTimeVal);
+ DateTime aAcceptDateTime;
+ if (!_parseDateTime(aAcceptDate, aAcceptDateTime))
+ return makeAny(sal_False);
+
+ if ( aAcceptDateTime > aLicenseDateTime )
+ return makeAny(sal_True);
+ }
+ // prepare to show
+ // display license dialog
+ LicenseDialog* pDialog = new LicenseDialog(aLicensePath, pResMgr);
+ sal_Bool bAgreed = (pDialog->Execute() == 1);
+ delete pDialog;
+
+ if (bAgreed) {
+
+ // write org.openoffice.Setup/ooLicenseAcceptDate
+ aAcceptDate = _getCurrentDateString();
+ pset->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooLicenseAcceptDate")), makeAny(aAcceptDate));
+ Reference< XChangesBatch >(pset, UNO_QUERY_THROW)->commitChanges();
+
+ // enable quickstarter
+ sal_Bool bQuickstart( sal_True );
+ sal_Bool bAutostart( sal_True );
+ Sequence< Any > aSeq( 2 );
+ aSeq[0] <<= bQuickstart;
+ aSeq[1] <<= bAutostart;
+
+ Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.office.Quickstart"))),UNO_QUERY );
+ if ( xQuickstart.is() )
+ xQuickstart->initialize( aSeq );
+
+ aRet <<= sal_True;
+ }
+ else
+ {
+ aRet <<= sal_False;
+ }
+ }
+ catch (RuntimeException&)
+ {
+ // license could not be verified
+ aRet <<= sal_False;
+ }
+ return aRet;
+}
+
+void SAL_CALL License::close(sal_Bool /*bDeliverOwnership*/) throw (css::util::CloseVetoException)
+{
+ if (!m_bTerminate)
+ throw CloseVetoException();
+}
+void SAL_CALL License::addCloseListener(const css::uno::Reference< css::util::XCloseListener >&)
+ throw (css::uno::RuntimeException)
+{
+}
+void SAL_CALL License::removeCloseListener(const css::uno::Reference< css::util::XCloseListener >&)
+ throw (css::uno::RuntimeException)
+{
+}
+
+
+//************************************************************************
+// License Dialog
+//************************************************************************
+
+LicenseDialog::LicenseDialog(const ::rtl::OUString & aLicensePath, ResMgr *pResMgr) :
+ ModalDialog(NULL, ResId(DLG_LICENSE, *pResMgr)),
+ aLicenseML(this, ResId(ML_LICENSE, *pResMgr)),
+ aInfo1FT(this, ResId(FT_INFO1, *pResMgr)),
+ aInfo2FT(this, ResId(FT_INFO2, *pResMgr)),
+ aInfo3FT(this, ResId(FT_INFO3, *pResMgr)),
+ aInfo2_1FT(this, ResId(FT_INFO2_1, *pResMgr)),
+ aInfo3_1FT(this, ResId(FT_INFO3_1, *pResMgr)),
+ aFixedLine(this, ResId(FL_DIVIDE, *pResMgr)),
+ aPBPageDown(this, ResId(PB_PAGEDOWN, *pResMgr)),
+ aPBDecline( this, ResId(PB_DECLINE, *pResMgr) ),
+ aPBAccept( this, ResId(PB_ACCEPT, *pResMgr) ),
+ aArrow(this, ResId(IMG_ARROW, *pResMgr)),
+ aStrAccept( ResId(LICENSE_ACCEPT, *pResMgr) ),
+ aStrNotAccept( ResId(LICENSE_NOTACCEPT, *pResMgr) ),
+ bEndReached(sal_False)
+{
+ FreeResource();
+
+ aLicenseML.SetEndReachedHdl( LINK(this, LicenseDialog, EndReachedHdl) );
+ aLicenseML.SetScrolledHdl( LINK(this, LicenseDialog, ScrolledHdl) );
+
+ aPBPageDown.SetClickHdl( LINK(this, LicenseDialog, PageDownHdl) );
+ aPBDecline.SetClickHdl( LINK(this, LicenseDialog, DeclineBtnHdl) );
+ aPBAccept.SetClickHdl( LINK(this, LicenseDialog, AcceptBtnHdl) );
+
+ // We want a automatic repeating page down button
+ WinBits aStyle = aPBPageDown.GetStyle();
+ aStyle |= WB_REPEAT;
+ aPBPageDown.SetStyle( aStyle );
+
+ String aText = aInfo2FT.GetText();
+ aText.SearchAndReplaceAll( UniString::CreateFromAscii("%PAGEDOWN"), aPBPageDown.GetText() );
+ aInfo2FT.SetText( aText );
+
+ aPBDecline.SetText( aStrNotAccept );
+ aPBAccept.SetText( aStrAccept );
+
+ aPBAccept.Disable();
+
+ // load license text
+ File aLicenseFile(aLicensePath);
+ if ( aLicenseFile.open(osl_File_OpenFlag_Read) == FileBase::E_None)
+ {
+ DirectoryItem d;
+ DirectoryItem::get(aLicensePath, d);
+ FileStatus fs(FileStatusMask_FileSize);
+ d.getFileStatus(fs);
+ sal_uInt64 nBytesRead = 0;
+ sal_uInt64 nPosition = 0;
+ sal_uInt32 nBytes = (sal_uInt32)fs.getFileSize();
+ sal_Char *pBuffer = new sal_Char[nBytes];
+ while (aLicenseFile.read(pBuffer+nPosition, nBytes-nPosition, nBytesRead) == FileBase::E_None
+ && nPosition + nBytesRead < nBytes)
+ {
+ nPosition += nBytesRead;
+ }
+ ::rtl::OUString aLicenseString(pBuffer, nBytes, RTL_TEXTENCODING_UTF8,
+ OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE);
+ delete[] pBuffer;
+ aLicenseML.SetText(aLicenseString);
+ }
+
+}
+
+LicenseDialog::~LicenseDialog()
+{
+}
+
+IMPL_LINK( LicenseDialog, PageDownHdl, PushButton *, EMPTYARG )
+{
+ aLicenseML.ScrollDown( SCROLL_PAGEDOWN );
+ return 0;
+}
+
+IMPL_LINK( LicenseDialog, EndReachedHdl, LicenseView *, EMPTYARG )
+{
+ bEndReached = sal_True;
+
+ EnableControls();
+
+ return 0;
+}
+
+IMPL_LINK( LicenseDialog, ScrolledHdl, LicenseView *, EMPTYARG )
+{
+ EnableControls();
+
+ return 0;
+}
+
+IMPL_LINK( LicenseDialog, DeclineBtnHdl, PushButton *, EMPTYARG )
+{
+ EndDialog(0);
+ return 0;
+}
+IMPL_LINK( LicenseDialog, AcceptBtnHdl, PushButton *, EMPTYARG )
+{
+ EndDialog(1);
+ return 0;
+}
+
+
+void LicenseDialog::EnableControls()
+{
+ if( !bEndReached &&
+ ( aLicenseML.IsEndReached() || !aLicenseML.GetText().Len() ) )
+ bEndReached = sal_True;
+
+ if ( bEndReached )
+ {
+ Point aPos( aInfo1FT.GetPosPixel().X(),
+ aInfo3_1FT.GetPosPixel().Y() );
+ aArrow.SetPosPixel( aPos );
+ aPBAccept.Enable();
+ }
+ else
+ {
+ Point aPos( aInfo1FT.GetPosPixel().X(),
+ aInfo2_1FT.GetPosPixel().Y() );
+ aArrow.SetPosPixel( aPos );
+ aPBAccept.Disable();
+ }
+
+ if ( aLicenseML.IsEndReached() )
+ aPBPageDown.Disable();
+ else
+ aPBPageDown.Enable();
+
+}
+
+
+LicenseView::LicenseView( Window* pParent, const ResId& rResId )
+ : MultiLineEdit( pParent, rResId )
+{
+ SetLeftMargin( 5 );
+
+ mbEndReached = IsEndReached();
+
+ StartListening( *GetTextEngine() );
+}
+
+LicenseView::~LicenseView()
+{
+ maEndReachedHdl = Link();
+ maScrolledHdl = Link();
+
+ EndListeningAll();
+}
+
+void LicenseView::ScrollDown( ScrollType eScroll )
+{
+ ScrollBar* pScroll = GetVScrollBar();
+
+ if ( pScroll )
+ pScroll->DoScrollAction( eScroll );
+}
+
+sal_Bool LicenseView::IsEndReached() const
+{
+ sal_Bool bEndReached;
+
+ ExtTextView* pView = GetTextView();
+ ExtTextEngine* pEdit = GetTextEngine();
+ sal_uLong nHeight = pEdit->GetTextHeight();
+ Size aOutSize = pView->GetWindow()->GetOutputSizePixel();
+ Point aBottom( 0, aOutSize.Height() );
+
+ if ( (sal_uLong) pView->GetDocPos( aBottom ).Y() >= nHeight - 1 )
+ bEndReached = sal_True;
+ else
+ bEndReached = sal_False;
+
+ return bEndReached;
+}
+
+void LicenseView::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.IsA( TYPE(TextHint) ) )
+ {
+ sal_Bool bLastVal = EndReached();
+ sal_uLong nId = ((const TextHint&)rHint).GetId();
+
+ if ( nId == TEXT_HINT_PARAINSERTED )
+ {
+ if ( bLastVal )
+ mbEndReached = IsEndReached();
+ }
+ else if ( nId == TEXT_HINT_VIEWSCROLLED )
+ {
+ if ( ! mbEndReached )
+ mbEndReached = IsEndReached();
+ maScrolledHdl.Call( this );
+ }
+
+ if ( EndReached() && !bLastVal )
+ {
+ maEndReachedHdl.Call( this );
+ }
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/mediatypedetectionhelper.cxx b/framework/source/services/mediatypedetectionhelper.cxx
new file mode 100644
index 000000000000..8e62ee50f1b4
--- /dev/null
+++ b/framework/source/services/mediatypedetectionhelper.cxx
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <services/mediatypedetectionhelper.hxx>
+#include <services.h>
+#include <svl/inettype.hxx>
+#include <tools/string.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+
+using namespace ::com::sun::star ;
+using namespace ::rtl ;
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+MediaTypeDetectionHelper::MediaTypeDetectionHelper( const uno::Reference< lang::XMultiServiceFactory >& xFactory )
+ : m_xFactory( xFactory )
+{
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+MediaTypeDetectionHelper::~MediaTypeDetectionHelper()
+{
+}
+
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( MediaTypeDetectionHelper
+ , ::cppu::OWeakObject
+ , SERVICENAME_MEDIATYPEDETECTIONHELPER
+ , IMPLEMENTATIONNAME_MEDIATYPEDETECTIONHELPER
+ )
+
+DEFINE_INIT_SERVICE ( MediaTypeDetectionHelper,
+ {
+ }
+ )
+
+//*****************************************************************************************************************
+// XStringMapping
+//*****************************************************************************************************************
+
+sal_Bool SAL_CALL MediaTypeDetectionHelper::mapStrings(
+ uno::Sequence< OUString >& rSeq )
+ throw(uno::RuntimeException)
+{
+ sal_Bool bModified = sal_False;
+ for( sal_Int32 i = rSeq.getLength(); i--; )
+ {
+
+ OUString& rUrl = rSeq[i];
+ INetContentType eType = INetContentTypes::GetContentTypeFromURL( rUrl );
+
+ UniString aType( INetContentTypes::GetContentType( eType ) );
+ if( aType.Len() )
+ {
+ rUrl = aType;
+ bModified = sal_True;
+ }
+ }
+ return bModified;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/modelwinservice.cxx b/framework/source/services/modelwinservice.cxx
new file mode 100644
index 000000000000..d50fe7dcc653
--- /dev/null
+++ b/framework/source/services/modelwinservice.cxx
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urltransformer.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "services.h"
+#include "services/modelwinservice.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/awt/XControlModel.hpp>
+
+using namespace ::com::sun::star;
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+class Impl_ModelWinService
+{
+ public:
+ ~Impl_ModelWinService();
+
+ static Impl_ModelWinService* getSingleInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager );
+
+ uno::Any getByName( const ::rtl::OUString& sName )
+ throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException );
+
+ uno::Sequence< ::rtl::OUString > getElementNames()
+ throw( uno::RuntimeException );
+
+ sal_Bool hasByName( const ::rtl::OUString& sName )
+ throw( uno::RuntimeException );
+
+ uno::Type getElementType()
+ throw( css::uno::RuntimeException );
+
+ sal_Bool hasElements()
+ throw( css::uno::RuntimeException );
+
+ void registerModelForXWindow( const uno::Reference< awt::XWindow >& rWindow, const uno::Reference< awt::XControlModel >& rModel );
+
+ void deregisterModelForXWindow( const uno::Reference< awt::XWindow >& rWindow );
+
+ private:
+ typedef BaseHash< uno::WeakReference< awt::XControlModel > > ModelWinMap;
+
+ Impl_ModelWinService();
+ Impl_ModelWinService( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager );
+
+ static Impl_ModelWinService* m_pModelWinService;
+
+ ::com::sun::star::uno::WeakReference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager;
+ ModelWinMap m_aModelMap;
+};
+
+Impl_ModelWinService* Impl_ModelWinService::m_pModelWinService = 0;
+
+Impl_ModelWinService* Impl_ModelWinService::getSingleInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager )
+{
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ if ( !m_pModelWinService )
+ m_pModelWinService = new Impl_ModelWinService( rServiceManager );
+ return m_pModelWinService;
+}
+
+Impl_ModelWinService::Impl_ModelWinService( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager ) :
+ m_xServiceManager( rServiceManager )
+{
+}
+
+Impl_ModelWinService::Impl_ModelWinService()
+{
+}
+
+Impl_ModelWinService::~Impl_ModelWinService()
+{
+}
+
+void Impl_ModelWinService::registerModelForXWindow( const uno::Reference< awt::XWindow >& rWindow, const uno::Reference< awt::XControlModel >& rModel )
+{
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ ::rtl::OUString sName = rtl::OUString::valueOf( reinterpret_cast< sal_Int64 >((void*)rWindow.get()));
+ ModelWinMap::iterator pIter = m_aModelMap.find( sName );
+ if ( pIter != m_aModelMap.end() )
+ pIter->second = rModel;
+ else
+ m_aModelMap[sName] = rModel;
+}
+
+void Impl_ModelWinService::deregisterModelForXWindow( const uno::Reference< awt::XWindow >& /*rWindow*/ )
+{
+}
+
+uno::Any Impl_ModelWinService::getByName( const ::rtl::OUString& sName )
+throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ uno::Any aAny;
+
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ ModelWinMap::iterator pIter = m_aModelMap.find( sName );
+ if ( pIter != m_aModelMap.end())
+ {
+ uno::Reference< awt::XControlModel > xModel( pIter->second );
+ aAny = uno::makeAny(xModel);
+ }
+
+ return aAny;
+}
+
+uno::Sequence< ::rtl::OUString > Impl_ModelWinService::getElementNames()
+throw( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ uno::Sequence< ::rtl::OUString > aResult( m_aModelMap.size() );
+
+ sal_Int32 i = 0;
+ ModelWinMap::const_iterator pIter = m_aModelMap.begin();
+ while ( pIter != m_aModelMap.end())
+ aResult[i++] = pIter->first;
+
+ return aResult;
+}
+
+sal_Bool Impl_ModelWinService::hasByName( const ::rtl::OUString& sName )
+throw( uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ ModelWinMap::iterator pIter = m_aModelMap.find( sName );
+ if ( pIter != m_aModelMap.end())
+ return true;
+ else
+ return false;
+}
+
+uno::Type Impl_ModelWinService::getElementType()
+throw( css::uno::RuntimeException )
+{
+ return ::getCppuType(( const uno::Reference< awt::XControlModel >*)NULL );
+}
+
+sal_Bool Impl_ModelWinService::hasElements()
+throw( css::uno::RuntimeException )
+{
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ return (m_aModelMap.size() > 0);
+}
+
+//*****************************************************************************************************************
+// css::uno::XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+
+DEFINE_XINTERFACE_4 ( ModelWinService ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::container::XNameAccess ),
+ DIRECT_INTERFACE(css::container::XElementAccess )
+ )
+
+DEFINE_XTYPEPROVIDER_4 ( ModelWinService ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::container::XNameAccess ,
+ css::container::XElementAccess
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( ModelWinService ,
+ OWeakObject ,
+ SERVICENAME_MODELWINSERVICE ,
+ IMPLEMENTATIONNAME_MODELWINSERVICE
+ )
+
+DEFINE_INIT_SERVICE ( ModelWinService,
+ {
+ }
+ )
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+ModelWinService::ModelWinService(const uno::Reference< lang::XMultiServiceFactory >& rServiceManager ) :
+ m_xServiceManager( rServiceManager )
+{
+}
+
+ModelWinService::~ModelWinService()
+{
+}
+
+void ModelWinService::registerModelForXWindow( const uno::Reference< awt::XWindow >& rWindow, const uno::Reference< awt::XControlModel >& rModel )
+{
+ Impl_ModelWinService::getSingleInstance(m_xServiceManager)->registerModelForXWindow( rWindow, rModel );
+}
+
+void ModelWinService::deregisterModelForXWindow( const uno::Reference< awt::XWindow >& rWindow )
+{
+ Impl_ModelWinService::getSingleInstance(m_xServiceManager)->deregisterModelForXWindow( rWindow );
+}
+
+uno::Any SAL_CALL ModelWinService::getByName( const ::rtl::OUString& sName )
+throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
+{
+ return Impl_ModelWinService::getSingleInstance(m_xServiceManager)->getByName( sName );
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL ModelWinService::getElementNames()
+throw( uno::RuntimeException )
+{
+ return Impl_ModelWinService::getSingleInstance(m_xServiceManager)->getElementNames( );
+}
+
+sal_Bool SAL_CALL ModelWinService::hasByName( const ::rtl::OUString& sName )
+throw( uno::RuntimeException )
+{
+ return Impl_ModelWinService::getSingleInstance(m_xServiceManager)->hasByName( sName );
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XElementAccess
+//---------------------------------------------------------------------------------------------------------
+uno::Type SAL_CALL ModelWinService::getElementType()
+throw( uno::RuntimeException )
+{
+ return ::getCppuType( (const uno::Reference< awt::XControlModel > *)NULL );
+}
+
+sal_Bool SAL_CALL ModelWinService::hasElements()
+throw( uno::RuntimeException )
+{
+ return Impl_ModelWinService::getSingleInstance(m_xServiceManager)->hasElements();
+}
+
+}
diff --git a/framework/source/services/modulemanager.cxx b/framework/source/services/modulemanager.cxx
new file mode 100644
index 000000000000..f1ab43668bd6
--- /dev/null
+++ b/framework/source/services/modulemanager.cxx
@@ -0,0 +1,428 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "services/modulemanager.hxx"
+#include "services/frame.hxx"
+
+//_______________________________________________
+// own includes
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XModule.hpp>
+#include <comphelper/configurationhelper.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/sequenceasvector.hxx>
+#include <comphelper/enumhelper.hxx>
+
+//_______________________________________________
+// other includes
+#include <rtl/logfile.hxx>
+
+namespace framework
+{
+
+static const ::rtl::OUString CFGPATH_FACTORIES (RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Setup/Office/Factories"));
+static const ::rtl::OUString MODULEPROP_IDENTIFIER(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryModuleIdentifier"));
+
+/*-----------------------------------------------
+ 04.12.2003 09:32
+-----------------------------------------------*/
+DEFINE_XINTERFACE_7(ModuleManager ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::container::XNameReplace ),
+ DIRECT_INTERFACE(css::container::XNameAccess ),
+ DIRECT_INTERFACE(css::container::XElementAccess ),
+ DIRECT_INTERFACE(css::container::XContainerQuery),
+ DIRECT_INTERFACE(css::frame::XModuleManager ))
+
+/*-----------------------------------------------
+ 04.12.2003 09:32
+-----------------------------------------------*/
+DEFINE_XTYPEPROVIDER_7(ModuleManager ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::container::XNameReplace ,
+ css::container::XNameAccess ,
+ css::container::XElementAccess ,
+ css::container::XContainerQuery,
+ css::frame::XModuleManager )
+
+/*-----------------------------------------------
+ 04.12.2003 09:35
+-----------------------------------------------*/
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(ModuleManager ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_MODULEMANAGER ,
+ IMPLEMENTATIONNAME_MODULEMANAGER)
+
+/*-----------------------------------------------
+ 04.12.2003 09:35
+-----------------------------------------------*/
+DEFINE_INIT_SERVICE(
+ ModuleManager,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+ )
+
+/*-----------------------------------------------
+ 04.12.2003 09:30
+-----------------------------------------------*/
+ModuleManager::ModuleManager(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase( )
+ , m_xSMGR (xSMGR)
+{
+}
+
+/*-----------------------------------------------
+ 10.12.2003 11:59
+-----------------------------------------------*/
+ModuleManager::~ModuleManager()
+{
+ if (m_xCFG.is())
+ m_xCFG.clear();
+}
+
+/*-----------------------------------------------
+ 10.12.2003 11:02
+-----------------------------------------------*/
+::rtl::OUString SAL_CALL ModuleManager::identify(const css::uno::Reference< css::uno::XInterface >& xModule)
+ throw(css::lang::IllegalArgumentException,
+ css::frame::UnknownModuleException,
+ css::uno::RuntimeException )
+{
+ // valid parameter?
+ css::uno::Reference< css::frame::XFrame > xFrame (xModule, css::uno::UNO_QUERY);
+ css::uno::Reference< css::awt::XWindow > xWindow (xModule, css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XController > xController(xModule, css::uno::UNO_QUERY);
+ css::uno::Reference< css::frame::XModel > xModel (xModule, css::uno::UNO_QUERY);
+
+ if (
+ (!xFrame.is() ) &&
+ (!xWindow.is() ) &&
+ (!xController.is()) &&
+ (!xModel.is() )
+ )
+ {
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Given module is not a frame nor a window, controller or model.")),
+ static_cast< ::cppu::OWeakObject* >(this),
+ 1);
+ }
+
+ if (xFrame.is())
+ {
+ xController = xFrame->getController();
+ xWindow = xFrame->getComponentWindow();
+ }
+ if (xController.is())
+ xModel = xController->getModel();
+
+ // modules are implemented by the deepest component in hierarchy ...
+ // Means: model -> controller -> window
+ // No fallbacks to higher components are allowed !
+ // Note : A frame provides access to module components only ... but it's not a module by himself.
+
+ ::rtl::OUString sModule;
+ if (xModel.is())
+ sModule = implts_identify(xModel);
+ else
+ if (xController.is())
+ sModule = implts_identify(xController);
+ else
+ if (xWindow.is())
+ sModule = implts_identify(xWindow);
+
+ if (sModule.getLength() < 1)
+ throw css::frame::UnknownModuleException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cant find suitable module for the given component.")),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ return sModule;
+}
+
+/*-----------------------------------------------
+ 08.03.2007 09:55
+-----------------------------------------------*/
+void SAL_CALL ModuleManager::replaceByName(const ::rtl::OUString& sName ,
+ const css::uno::Any& aValue)
+ throw (css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ ::comphelper::SequenceAsHashMap lProps(aValue);
+ if (lProps.empty() )
+ {
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No properties given to replace part of module.")),
+ static_cast< css::container::XNameAccess* >(this),
+ 2);
+ }
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // get access to the element
+ // Note: Dont use impl_getConfig() method here. Because it creates a readonly access only, further
+ // it cache it as a member of this module manager instance. If we change some props there ... but dont
+ // flush changes (because an error occurred) we will read them later. If we use a different config access
+ // we can close it without a flush ... and our read data wont be affected .-)
+ css::uno::Reference< css::uno::XInterface > xCfg = ::comphelper::ConfigurationHelper::openConfig(
+ xSMGR,
+ CFGPATH_FACTORIES,
+ ::comphelper::ConfigurationHelper::E_STANDARD);
+ css::uno::Reference< css::container::XNameAccess > xModules (xCfg, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::container::XNameReplace > xModule ;
+
+ xModules->getByName(sName) >>= xModule;
+ if (!xModule.is())
+ {
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Was not able to get write access to the requested module entry inside configuration.")),
+ static_cast< css::container::XNameAccess* >(this));
+ }
+
+ ::comphelper::SequenceAsHashMap::const_iterator pProp;
+ for ( pProp = lProps.begin();
+ pProp != lProps.end() ;
+ ++pProp )
+ {
+ const ::rtl::OUString& sPropName = pProp->first;
+ const css::uno::Any& aPropValue = pProp->second;
+
+ // let "NoSuchElementException" out ! We support the same API ...
+ // and without a flush() at the end all changed data before will be ignored !
+ xModule->replaceByName(sPropName, aPropValue);
+ }
+
+ ::comphelper::ConfigurationHelper::flush(xCfg);
+}
+
+/*-----------------------------------------------
+ 10.12.2003 12:05
+-----------------------------------------------*/
+css::uno::Any SAL_CALL ModuleManager::getByName(const ::rtl::OUString& sName)
+ throw(css::container::NoSuchElementException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ // get access to the element
+ css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
+ css::uno::Reference< css::container::XNameAccess > xModule;
+ xCFG->getByName(sName) >>= xModule;
+ if (!xModule.is())
+ {
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Was not able to get write access to the requested module entry inside configuration.")),
+ static_cast< css::container::XNameAccess* >(this));
+ }
+
+ // convert it to seq< PropertyValue >
+ const css::uno::Sequence< ::rtl::OUString > lPropNames = xModule->getElementNames();
+ ::comphelper::SequenceAsHashMap lProps ;
+ sal_Int32 c = lPropNames.getLength();
+ sal_Int32 i = 0;
+
+ lProps[MODULEPROP_IDENTIFIER] <<= sName;
+ for (i=0; i<c; ++i)
+ {
+ const ::rtl::OUString& sPropName = lPropNames[i];
+ lProps[sPropName] = xModule->getByName(sPropName);
+ }
+
+ return css::uno::makeAny(lProps.getAsConstPropertyValueList());
+}
+
+/*-----------------------------------------------
+ 10.12.2003 11:58
+-----------------------------------------------*/
+css::uno::Sequence< ::rtl::OUString > SAL_CALL ModuleManager::getElementNames()
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
+ return xCFG->getElementNames();
+}
+
+/*-----------------------------------------------
+ 10.12.2003 11:57
+-----------------------------------------------*/
+sal_Bool SAL_CALL ModuleManager::hasByName(const ::rtl::OUString& sName)
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
+ return xCFG->hasByName(sName);
+}
+
+/*-----------------------------------------------
+ 10.12.2003 11:35
+-----------------------------------------------*/
+css::uno::Type SAL_CALL ModuleManager::getElementType()
+ throw(css::uno::RuntimeException)
+{
+ return ::getCppuType((const css::uno::Sequence< css::beans::PropertyValue >*)0);
+}
+
+/*-----------------------------------------------
+ 10.12.2003 11:56
+-----------------------------------------------*/
+sal_Bool SAL_CALL ModuleManager::hasElements()
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
+ return xCFG->hasElements();
+}
+
+/*-----------------------------------------------
+ 07.03.2007 12:55
+-----------------------------------------------*/
+css::uno::Reference< css::container::XEnumeration > SAL_CALL ModuleManager::createSubSetEnumerationByQuery(const ::rtl::OUString&)
+ throw(css::uno::RuntimeException)
+{
+ return css::uno::Reference< css::container::XEnumeration >();
+}
+
+/*-----------------------------------------------
+ 07.03.2007 12:55
+-----------------------------------------------*/
+css::uno::Reference< css::container::XEnumeration > SAL_CALL ModuleManager::createSubSetEnumerationByProperties(const css::uno::Sequence< css::beans::NamedValue >& lProperties)
+ throw(css::uno::RuntimeException)
+{
+ ::comphelper::SequenceAsHashMap lSearchProps (lProperties);
+ css::uno::Sequence< ::rtl::OUString > lModules = getElementNames();
+ sal_Int32 c = lModules.getLength();
+ sal_Int32 i = 0;
+ ::comphelper::SequenceAsVector< css::uno::Any > lResult ;
+
+ for (i=0; i<c; ++i)
+ {
+ try
+ {
+ const ::rtl::OUString& sModule = lModules[i];
+ ::comphelper::SequenceAsHashMap lModuleProps = getByName(sModule);
+
+ if (lModuleProps.match(lSearchProps))
+ lResult.push_back(css::uno::makeAny(lModuleProps.getAsConstPropertyValueList()));
+ }
+ catch(const css::uno::Exception&)
+ {}
+ }
+
+ ::comphelper::OAnyEnumeration* pEnum = new ::comphelper::OAnyEnumeration(lResult.getAsConstList());
+ css::uno::Reference< css::container::XEnumeration > xEnum(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY_THROW);
+ return xEnum;
+}
+
+/*-----------------------------------------------
+ 14.12.2003 09:45
+-----------------------------------------------*/
+css::uno::Reference< css::container::XNameAccess > ModuleManager::implts_getConfig()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ if (m_xCFG.is())
+ return m_xCFG;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::uno::XInterface > xCfg;
+ try
+ {
+ xCfg = ::comphelper::ConfigurationHelper::openConfig(
+ xSMGR,
+ CFGPATH_FACTORIES,
+ ::comphelper::ConfigurationHelper::E_READONLY);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { xCfg.clear(); }
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+ m_xCFG = css::uno::Reference< css::container::XNameAccess >(xCfg, css::uno::UNO_QUERY_THROW);
+ return m_xCFG;
+ // <- SAFE ----------------------------------
+}
+
+/*-----------------------------------------------
+ 30.01.2004 07:54
+-----------------------------------------------*/
+::rtl::OUString ModuleManager::implts_identify(const css::uno::Reference< css::uno::XInterface >& xComponent)
+{
+ // Search for an optional (!) interface XModule first.
+ // Its used to overrule an existing service name. Used e.g. by our database form designer
+ // which uses a writer module internaly.
+ css::uno::Reference< css::frame::XModule > xModule(xComponent, css::uno::UNO_QUERY);
+ if (xModule.is())
+ return xModule->getIdentifier();
+
+ // detect modules in a generic way ...
+ // comparing service names with configured entries ...
+ css::uno::Reference< css::lang::XServiceInfo > xInfo(xComponent, css::uno::UNO_QUERY);
+ if (!xInfo.is())
+ return ::rtl::OUString();
+
+ const css::uno::Sequence< ::rtl::OUString > lKnownModules = getElementNames();
+ const ::rtl::OUString* pKnownModules = lKnownModules.getConstArray();
+ sal_Int32 c = lKnownModules.getLength();
+ sal_Int32 i = 0;
+
+ for (i=0; i<c; ++i)
+ {
+ if (xInfo->supportsService(pKnownModules[i]))
+ return pKnownModules[i];
+ }
+
+ return ::rtl::OUString();
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/pathsettings.cxx b/framework/source/services/pathsettings.cxx
new file mode 100644
index 000000000000..88163253fc2c
--- /dev/null
+++ b/framework/source/services/pathsettings.cxx
@@ -0,0 +1,1183 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+// ______________________________________________
+// my own includes
+
+/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
+ with solaris headers ...
+*/
+#include <vector>
+#include <services/pathsettings.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <services.h>
+
+#include "helper/mischelper.hxx"
+
+// ______________________________________________
+// interface includes
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/XProperty.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+
+// ______________________________________________
+// includes of other projects
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+
+#include <comphelper/configurationhelper.hxx>
+#include <unotools/configpathes.hxx>
+
+#include <fwkdllapi.h>
+
+// ______________________________________________
+// non exported const
+
+#define CFG_READONLY_DEFAULT sal_False
+
+const ::rtl::OUString CFGPROP_USERPATHES(RTL_CONSTASCII_USTRINGPARAM("UserPaths"));
+const ::rtl::OUString CFGPROP_WRITEPATH(RTL_CONSTASCII_USTRINGPARAM("WritePath"));
+
+/*
+ 0 : old style "Template" string using ";" as seperator
+ 1 : internal paths "Template_internal" string list
+ 2 : user paths "Template_user" string list
+ 3 : write path "Template_write" string
+ */
+
+const ::rtl::OUString POSTFIX_INTERNAL_PATHES(RTL_CONSTASCII_USTRINGPARAM("_internal"));
+const ::rtl::OUString POSTFIX_USER_PATHES(RTL_CONSTASCII_USTRINGPARAM("_user"));
+const ::rtl::OUString POSTFIX_WRITE_PATH(RTL_CONSTASCII_USTRINGPARAM("_writable"));
+
+const sal_Int32 IDGROUP_OLDSTYLE = 0;
+const sal_Int32 IDGROUP_INTERNAL_PATHES = 1;
+const sal_Int32 IDGROUP_USER_PATHES = 2;
+const sal_Int32 IDGROUP_WRITE_PATH = 3;
+
+const sal_Int32 IDGROUP_COUNT = 4;
+
+sal_Int32 impl_getPropGroup(sal_Int32 nID)
+{
+ return (nID % IDGROUP_COUNT);
+}
+
+// ______________________________________________
+// namespace
+
+namespace framework
+{
+
+//-----------------------------------------------------------------------------
+// XInterface, XTypeProvider, XServiceInfo
+
+DEFINE_XINTERFACE_7 ( PathSettings ,
+ OWeakObject ,
+ DIRECT_INTERFACE ( css::lang::XTypeProvider ),
+ DIRECT_INTERFACE ( css::lang::XServiceInfo ),
+ DERIVED_INTERFACE( css::lang::XEventListener, css::util::XChangesListener),
+ DIRECT_INTERFACE ( css::util::XChangesListener ),
+ DIRECT_INTERFACE ( css::beans::XPropertySet ),
+ DIRECT_INTERFACE ( css::beans::XFastPropertySet ),
+ DIRECT_INTERFACE ( css::beans::XMultiPropertySet )
+ )
+
+DEFINE_XTYPEPROVIDER_7 ( PathSettings ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::lang::XEventListener ,
+ css::util::XChangesListener ,
+ css::beans::XPropertySet ,
+ css::beans::XFastPropertySet ,
+ css::beans::XMultiPropertySet
+ )
+
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( PathSettings ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_PATHSETTINGS ,
+ IMPLEMENTATIONNAME_PATHSETTINGS
+ )
+
+DEFINE_INIT_SERVICE ( PathSettings,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+
+ // fill cache
+ impl_readAll();
+ }
+ )
+
+//-----------------------------------------------------------------------------
+PathSettings::PathSettings( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ // Init baseclasses first
+ // Attention: Don't change order of initialization!
+ // ThreadHelpBase is a struct with a lock as member. We can't use a lock as direct member!
+ // We must garant right initialization and a valid value of this to initialize other baseclasses!
+ : ThreadHelpBase()
+ , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >(m_aLock.getShareableOslMutex())
+ , ::cppu::OPropertySetHelper(*(static_cast< ::cppu::OBroadcastHelper* >(this)))
+ , ::cppu::OWeakObject()
+ // Init member
+ , m_xSMGR (xSMGR)
+ , m_pPropHelp(0 )
+ , m_bIgnoreEvents(sal_False)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::PathSettings" );
+}
+
+//-----------------------------------------------------------------------------
+PathSettings::~PathSettings()
+{
+ css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(m_xCfgNew, css::uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->removeChangesListener(m_xCfgNewListener);
+ if (m_pPropHelp)
+ delete m_pPropHelp;
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PathSettings::changesOccurred(const css::util::ChangesEvent& aEvent)
+ throw (css::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::changesOccurred" );
+
+ sal_Int32 c = aEvent.Changes.getLength();
+ sal_Int32 i = 0;
+ sal_Bool bUpdateDescriptor = sal_False;
+
+ for (i=0; i<c; ++i)
+ {
+ const css::util::ElementChange& aChange = aEvent.Changes[i];
+
+ ::rtl::OUString sChanged;
+ aChange.Accessor >>= sChanged;
+
+ ::rtl::OUString sPath = ::utl::extractFirstFromConfigurationPath(sChanged);
+ if (sPath.getLength())
+ {
+ PathSettings::EChangeOp eOp = impl_updatePath(sPath, sal_True);
+ if (
+ (eOp == PathSettings::E_ADDED ) ||
+ (eOp == PathSettings::E_REMOVED)
+ )
+ bUpdateDescriptor = sal_True;
+ }
+ }
+
+ if (bUpdateDescriptor)
+ impl_rebuildPropertyDescriptor();
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PathSettings::disposing(const css::lang::EventObject& aSource)
+ throw(css::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::disposing" );
+ WriteGuard aWriteLock(m_aLock);
+
+ if (aSource.Source == m_xCfgNew)
+ m_xCfgNew.clear();
+
+ aWriteLock.unlock();
+}
+
+//-----------------------------------------------------------------------------
+void PathSettings::impl_readAll()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readAll" );
+ RTL_LOGFILE_CONTEXT(aLog, "framework (as96863) ::PathSettings::load config (all)");
+
+ try
+ {
+ // TODO think about me
+ css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
+ css::uno::Sequence< ::rtl::OUString > lPaths = xCfg->getElementNames();
+
+ sal_Int32 c = lPaths.getLength();
+ for (sal_Int32 i = 0; i < c; ++i)
+ {
+ const ::rtl::OUString& sPath = lPaths[i];
+ impl_updatePath(sPath, sal_False);
+ }
+ }
+ catch(const css::uno::RuntimeException& )
+ {
+ }
+
+ impl_rebuildPropertyDescriptor();
+}
+
+//-----------------------------------------------------------------------------
+// NO substitution here ! It's done outside ...
+OUStringList PathSettings::impl_readOldFormat(const ::rtl::OUString& sPath)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readOldFormat" );
+ css::uno::Reference< css::container::XNameAccess > xCfg( fa_getCfgOld() );
+ OUStringList aPathVal;
+
+ if( xCfg->hasByName(sPath) )
+ {
+ css::uno::Any aVal( xCfg->getByName(sPath) );
+
+ ::rtl::OUString sStringVal;
+ css::uno::Sequence< ::rtl::OUString > lStringListVal;
+
+ if (aVal >>= sStringVal)
+ {
+ aPathVal.push_back(sStringVal);
+ }
+ else if (aVal >>= lStringListVal)
+ {
+ aPathVal << lStringListVal;
+ }
+ }
+
+ return aPathVal;
+}
+
+//-----------------------------------------------------------------------------
+// NO substitution here ! It's done outside ...
+PathSettings::PathInfo PathSettings::impl_readNewFormat(const ::rtl::OUString& sPath)
+{
+ const static ::rtl::OUString CFGPROP_INTERNALPATHES(RTL_CONSTASCII_USTRINGPARAM("InternalPaths"));
+ const static ::rtl::OUString CFGPROP_ISSINGLEPATH(RTL_CONSTASCII_USTRINGPARAM("IsSinglePath"));
+
+ css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
+
+ // get access to the "queried" path
+ css::uno::Reference< css::container::XNameAccess > xPath;
+ xCfg->getByName(sPath) >>= xPath;
+
+ PathSettings::PathInfo aPathVal;
+
+ // read internal path list
+ css::uno::Reference< css::container::XNameAccess > xIPath;
+ xPath->getByName(CFGPROP_INTERNALPATHES) >>= xIPath;
+ aPathVal.lInternalPaths << xIPath->getElementNames();
+
+ // read user defined path list
+ aPathVal.lUserPaths << xPath->getByName(CFGPROP_USERPATHES);
+
+ // read the writeable path
+ xPath->getByName(CFGPROP_WRITEPATH) >>= aPathVal.sWritePath;
+
+ // read state props
+ xPath->getByName(CFGPROP_ISSINGLEPATH) >>= aPathVal.bIsSinglePath;
+
+ // analyze finalized/mandatory states
+ aPathVal.bIsReadonly = sal_False;
+ css::uno::Reference< css::beans::XProperty > xInfo(xPath, css::uno::UNO_QUERY);
+ if (xInfo.is())
+ {
+ css::beans::Property aInfo = xInfo->getAsProperty();
+ sal_Bool bFinalized = ((aInfo.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY );
+
+ // Note: Till we support finalized / mandatory on our API more in detail we handle
+ // all states simple as READONLY ! But because all realy needed pathes are "mandatory" by default
+ // we have to handle "finalized" as the real "readonly" indicator .
+ aPathVal.bIsReadonly = bFinalized;
+ }
+
+ return aPathVal;
+}
+
+//-----------------------------------------------------------------------------
+void PathSettings::impl_storePath(const PathSettings::PathInfo& aPath)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_storePath" );
+ m_bIgnoreEvents = sal_True;
+
+ css::uno::Reference< css::container::XNameAccess > xCfgNew = fa_getCfgNew();
+ css::uno::Reference< css::container::XNameAccess > xCfgOld = fa_getCfgOld();
+
+ // try to replace path-parts with well known and uspported variables.
+ // So an office can be moved easialy to another location without loosing
+ // it's related pathes.
+ PathInfo aResubstPath(aPath);
+ impl_subst(aResubstPath, sal_True);
+
+ // update new configuration
+ if (! aResubstPath.bIsSinglePath)
+ {
+ ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
+ aResubstPath.sPathName,
+ CFGPROP_USERPATHES,
+ css::uno::makeAny(aResubstPath.lUserPaths.getAsConstList()));
+ }
+
+ ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
+ aResubstPath.sPathName,
+ CFGPROP_WRITEPATH,
+ css::uno::makeAny(aResubstPath.sWritePath));
+
+ ::comphelper::ConfigurationHelper::flush(xCfgNew);
+
+ // remove the whole path from the old configuration !
+ // Otherwise we cant make sure that the diff between new and old configuration
+ // on loading time realy represent an user setting !!!
+
+ // Check if the given path exists inside the old configuration.
+ // Because our new configuration knows more then the list of old pathes ... !
+ if (xCfgOld->hasByName(aResubstPath.sPathName))
+ {
+ css::uno::Reference< css::beans::XPropertySet > xProps(xCfgOld, css::uno::UNO_QUERY_THROW);
+ xProps->setPropertyValue(aResubstPath.sPathName, css::uno::Any());
+ ::comphelper::ConfigurationHelper::flush(xCfgOld);
+ }
+
+ m_bIgnoreEvents = sal_False;
+}
+
+//-----------------------------------------------------------------------------
+#ifdef MIGRATE_OLD_USER_PATHES
+void PathSettings::impl_mergeOldUserPaths( PathSettings::PathInfo& rPath,
+ const OUStringList& lOld )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_mergeOldUserPaths" );
+ OUStringList::const_iterator pIt;
+ for ( pIt = lOld.begin();
+ pIt != lOld.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sOld = *pIt;
+
+ if (rPath.bIsSinglePath)
+ {
+ LOG_ASSERT2(lOld.size()>1, "PathSettings::impl_mergeOldUserPaths()", "Single path has more then one path value inside old configuration (Common.xcu)!")
+ if (! rPath.sWritePath.equals(sOld))
+ rPath.sWritePath = sOld;
+ }
+ else
+ {
+ if (
+ ( rPath.lInternalPaths.findConst(sOld) == rPath.lInternalPaths.end()) &&
+ ( rPath.lUserPaths.findConst(sOld) == rPath.lUserPaths.end() ) &&
+ (! rPath.sWritePath.equals(sOld) )
+ )
+ rPath.lUserPaths.push_back(sOld);
+ }
+ }
+}
+#endif // MIGRATE_OLD_USER_PATHES
+
+//-----------------------------------------------------------------------------
+PathSettings::EChangeOp PathSettings::impl_updatePath(const ::rtl::OUString& sPath ,
+ sal_Bool bNotifyListener)
+{
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+
+ PathSettings::PathInfo* pPathOld = 0;
+ PathSettings::PathInfo* pPathNew = 0;
+ PathSettings::EChangeOp eOp = PathSettings::E_UNDEFINED;
+ PathSettings::PathInfo aPath;
+
+ try
+ {
+ aPath = impl_readNewFormat(sPath);
+ aPath.sPathName = sPath;
+ // replace all might existing variables with real values
+ // Do it before these old pathes will be compared against the
+ // new path configuration. Otherwise some striungs uses different variables ... but substitution
+ // will produce strings with same content (because some variables are redundant!)
+ impl_subst(aPath, sal_False);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::container::NoSuchElementException&)
+ { eOp = PathSettings::E_REMOVED; }
+ catch(const css::uno::Exception& exAny)
+ { throw exAny; }
+
+ #ifdef MIGRATE_OLD_USER_PATHES
+ try
+ {
+ // migration of old user defined values on demand
+ // can be disabled for a new major
+ OUStringList lOldVals = impl_readOldFormat(sPath);
+ // replace all might existing variables with real values
+ // Do it before these old pathes will be compared against the
+ // new path configuration. Otherwise some striungs uses different variables ... but substitution
+ // will produce strings with same content (because some variables are redundant!)
+ impl_subst(lOldVals, fa_getSubstitution(), sal_False);
+ impl_mergeOldUserPaths(aPath, lOldVals);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ // Normal(!) exceptions can be ignored!
+ // E.g. in case an addon installs a new path, which was not well known for an OOo 1.x installation
+ // we cant find a value for it inside the "old" configuration. So a NoSuchElementException
+ // will be normal .-)
+ catch(const css::uno::Exception&)
+ {}
+ #endif // MIGRATE_OLD_USER_PATHES
+
+ PathSettings::PathHash::iterator pPath = m_lPaths.find(sPath);
+ if (eOp == PathSettings::E_UNDEFINED)
+ {
+ if (pPath != m_lPaths.end())
+ eOp = PathSettings::E_CHANGED;
+ else
+ eOp = PathSettings::E_ADDED;
+ }
+
+ switch(eOp)
+ {
+ case PathSettings::E_ADDED :
+ {
+ if (bNotifyListener)
+ {
+ pPathOld = 0;
+ pPathNew = &aPath;
+ impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
+ }
+ m_lPaths[sPath] = aPath;
+ }
+ break;
+
+ case PathSettings::E_CHANGED :
+ {
+ if (bNotifyListener)
+ {
+ pPathOld = &(pPath->second);
+ pPathNew = &aPath;
+ impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
+ }
+ m_lPaths[sPath] = aPath;
+ }
+ break;
+
+ case PathSettings::E_REMOVED :
+ {
+ if (pPath != m_lPaths.end())
+ {
+ if (bNotifyListener)
+ {
+ pPathOld = &(pPath->second);
+ pPathNew = 0;
+ impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
+ }
+ m_lPaths.erase(pPath);
+ }
+ }
+ break;
+
+ default: // to let compiler be happy
+ break;
+ }
+
+ return eOp;
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Sequence< sal_Int32 > PathSettings::impl_mapPathName2IDList(const ::rtl::OUString& sPath)
+{
+ ::rtl::OUString sOldStyleProp = sPath;
+ ::rtl::OUString sInternalProp = sPath+POSTFIX_INTERNAL_PATHES;
+ ::rtl::OUString sUserProp = sPath+POSTFIX_USER_PATHES;
+ ::rtl::OUString sWriteProp = sPath+POSTFIX_WRITE_PATH;
+
+ // Attention: The default set of IDs is fix and must follow these schema.
+ // Otherwhise the outside code ant work for new added properties.
+ // Why ?
+ // The outside code must fire N events for every changed property.
+ // And the knowing about packaging of variables of the structure PathInfo
+ // follow these group IDs ! But if such ID isnt in the range of [0..IDGROUP_COUNT]
+ // the outside cant determine the right group ... and cant fire the right events .-)
+
+ css::uno::Sequence< sal_Int32 > lIDs(IDGROUP_COUNT);
+ lIDs[0] = IDGROUP_OLDSTYLE ;
+ lIDs[1] = IDGROUP_INTERNAL_PATHES;
+ lIDs[2] = IDGROUP_USER_PATHES ;
+ lIDs[3] = IDGROUP_WRITE_PATH ;
+
+ sal_Int32 c = m_lPropDesc.getLength();
+ sal_Int32 i = 0;
+ for (i=0; i<c; ++i)
+ {
+ const css::beans::Property& rProp = m_lPropDesc[i];
+
+ if (rProp.Name.equals(sOldStyleProp))
+ lIDs[IDGROUP_OLDSTYLE] = rProp.Handle;
+ else
+ if (rProp.Name.equals(sInternalProp))
+ lIDs[IDGROUP_INTERNAL_PATHES] = rProp.Handle;
+ else
+ if (rProp.Name.equals(sUserProp))
+ lIDs[IDGROUP_USER_PATHES] = rProp.Handle;
+ else
+ if (rProp.Name.equals(sWriteProp))
+ lIDs[IDGROUP_WRITE_PATH] = rProp.Handle;
+ }
+
+ return lIDs;
+}
+
+//-----------------------------------------------------------------------------
+void PathSettings::impl_notifyPropListener( PathSettings::EChangeOp /*eOp*/ ,
+ const ::rtl::OUString& sPath ,
+ const PathSettings::PathInfo* pPathOld,
+ const PathSettings::PathInfo* pPathNew)
+{
+ css::uno::Sequence< sal_Int32 > lHandles(1);
+ css::uno::Sequence< css::uno::Any > lOldVals(1);
+ css::uno::Sequence< css::uno::Any > lNewVals(1);
+
+ css::uno::Sequence< sal_Int32 > lIDs = impl_mapPathName2IDList(sPath);
+ sal_Int32 c = lIDs.getLength();
+ sal_Int32 i = 0;
+ sal_Int32 nMaxID = m_lPropDesc.getLength()-1;
+ for (i=0; i<c; ++i)
+ {
+ sal_Int32 nID = lIDs[i];
+
+ if (
+ (nID < 0 ) ||
+ (nID > nMaxID)
+ )
+ continue;
+
+ lHandles[0] = nID;
+ switch(impl_getPropGroup(nID))
+ {
+ case IDGROUP_OLDSTYLE :
+ {
+ if (pPathOld)
+ {
+ ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPathOld);
+ lOldVals[0] <<= sVal;
+ }
+ if (pPathNew)
+ {
+ ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPathNew);
+ lNewVals[0] <<= sVal;
+ }
+ }
+ break;
+
+ case IDGROUP_INTERNAL_PATHES :
+ {
+ if (pPathOld)
+ lOldVals[0] <<= pPathOld->lInternalPaths.getAsConstList();
+ if (pPathNew)
+ lNewVals[0] <<= pPathNew->lInternalPaths.getAsConstList();
+ }
+ break;
+
+ case IDGROUP_USER_PATHES :
+ {
+ if (pPathOld)
+ lOldVals[0] <<= pPathOld->lUserPaths.getAsConstList();
+ if (pPathNew)
+ lNewVals[0] <<= pPathNew->lUserPaths.getAsConstList();
+ }
+ break;
+
+ case IDGROUP_WRITE_PATH :
+ {
+ if (pPathOld)
+ lOldVals[0] <<= pPathOld->sWritePath;
+ if (pPathNew)
+ lNewVals[0] <<= pPathNew->sWritePath;
+ }
+ break;
+ }
+
+ fire(lHandles.getArray(),
+ lNewVals.getArray(),
+ lOldVals.getArray(),
+ 1,
+ sal_False);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void PathSettings::impl_subst( OUStringList& lVals ,
+ const css::uno::Reference< css::util::XStringSubstitution >& xSubst ,
+ sal_Bool bReSubst)
+{
+ OUStringList::iterator pIt;
+
+ for ( pIt = lVals.begin();
+ pIt != lVals.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& sOld = *pIt;
+ ::rtl::OUString sNew ;
+ if (bReSubst)
+ sNew = xSubst->reSubstituteVariables(sOld);
+ else
+ sNew = xSubst->substituteVariables(sOld, sal_False);
+
+ *pIt = sNew;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void PathSettings::impl_subst(PathSettings::PathInfo& aPath ,
+ sal_Bool bReSubst)
+{
+ css::uno::Reference< css::util::XStringSubstitution > xSubst = fa_getSubstitution();
+
+ impl_subst(aPath.lInternalPaths, xSubst, bReSubst);
+ impl_subst(aPath.lUserPaths , xSubst, bReSubst);
+ if (bReSubst)
+ aPath.sWritePath = xSubst->reSubstituteVariables(aPath.sWritePath);
+ else
+ aPath.sWritePath = xSubst->substituteVariables(aPath.sWritePath, sal_False);
+}
+
+//-----------------------------------------------------------------------------
+::rtl::OUString PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath) const
+{
+ OUStringList::const_iterator pIt;
+ OUStringList lTemp;
+ lTemp.reserve(rPath.lInternalPaths.size() + rPath.lUserPaths.size() + 1);
+
+ for ( pIt = rPath.lInternalPaths.begin();
+ pIt != rPath.lInternalPaths.end() ;
+ ++pIt )
+ {
+ lTemp.push_back(*pIt);
+ }
+ for ( pIt = rPath.lUserPaths.begin();
+ pIt != rPath.lUserPaths.end() ;
+ ++pIt )
+ {
+ lTemp.push_back(*pIt);
+ }
+
+ if (rPath.sWritePath.getLength() > 0)
+ lTemp.push_back(rPath.sWritePath);
+
+ ::rtl::OUStringBuffer sPathVal(256);
+ for ( pIt = lTemp.begin();
+ pIt != lTemp.end() ;
+ )
+ {
+ sPathVal.append(*pIt);
+ ++pIt;
+ if (pIt != lTemp.end())
+ sPathVal.appendAscii(";");
+ }
+
+ return sPathVal.makeStringAndClear();
+}
+
+//-----------------------------------------------------------------------------
+OUStringList PathSettings::impl_convertOldStyle2Path(const ::rtl::OUString& sOldStylePath) const
+{
+ OUStringList lList;
+ sal_Int32 nToken = 0;
+ do
+ {
+ ::rtl::OUString sToken = sOldStylePath.getToken(0, ';', nToken);
+ if (sToken.getLength())
+ lList.push_back(sToken);
+ }
+ while(nToken >= 0);
+
+ return lList;
+}
+
+//-----------------------------------------------------------------------------
+void PathSettings::impl_purgeKnownPaths(const PathSettings::PathInfo& rPath,
+ OUStringList& lList)
+{
+ OUStringList::const_iterator pIt;
+ for ( pIt = rPath.lInternalPaths.begin();
+ pIt != rPath.lInternalPaths.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& rItem = *pIt;
+ OUStringList::iterator pItem = lList.find(rItem);
+ if (pItem != lList.end())
+ lList.erase(pItem);
+ }
+ for ( pIt = rPath.lUserPaths.begin();
+ pIt != rPath.lUserPaths.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& rItem = *pIt;
+ OUStringList::iterator pItem = lList.find(rItem);
+ if (pItem != lList.end())
+ lList.erase(pItem);
+ }
+
+ OUStringList::iterator pItem = lList.find(rPath.sWritePath);
+ if (pItem != lList.end())
+ lList.erase(pItem);
+}
+
+//-----------------------------------------------------------------------------
+void PathSettings::impl_rebuildPropertyDescriptor()
+{
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+
+ sal_Int32 c = (sal_Int32)m_lPaths.size();
+ sal_Int32 i = 0;
+ m_lPropDesc.realloc(c*IDGROUP_COUNT);
+
+ PathHash::const_iterator pIt;
+ for ( pIt = m_lPaths.begin();
+ pIt != m_lPaths.end() ;
+ ++pIt )
+ {
+ const PathSettings::PathInfo& rPath = pIt->second;
+ css::beans::Property* pProp = 0;
+
+ pProp = &(m_lPropDesc[i]);
+ pProp->Name = rPath.sPathName;
+ pProp->Handle = i;
+ pProp->Type = ::getCppuType((::rtl::OUString*)0);
+ pProp->Attributes = css::beans::PropertyAttribute::BOUND;
+ if (rPath.bIsReadonly)
+ pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
+ ++i;
+
+ pProp = &(m_lPropDesc[i]);
+ pProp->Name = rPath.sPathName+POSTFIX_INTERNAL_PATHES;
+ pProp->Handle = i;
+ pProp->Type = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
+ pProp->Attributes = css::beans::PropertyAttribute::BOUND |
+ css::beans::PropertyAttribute::READONLY;
+ ++i;
+
+ pProp = &(m_lPropDesc[i]);
+ pProp->Name = rPath.sPathName+POSTFIX_USER_PATHES;
+ pProp->Handle = i;
+ pProp->Type = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
+ pProp->Attributes = css::beans::PropertyAttribute::BOUND;
+ if (rPath.bIsReadonly)
+ pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
+ ++i;
+
+ pProp = &(m_lPropDesc[i]);
+ pProp->Name = rPath.sPathName+POSTFIX_WRITE_PATH;
+ pProp->Handle = i;
+ pProp->Type = ::getCppuType((::rtl::OUString*)0);
+ pProp->Attributes = css::beans::PropertyAttribute::BOUND;
+ if (rPath.bIsReadonly)
+ pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
+ ++i;
+ }
+
+ if (m_pPropHelp)
+ delete m_pPropHelp;
+ m_pPropHelp = new ::cppu::OPropertyArrayHelper(m_lPropDesc, sal_False); // false => not sorted ... must be done inside helper
+
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Any PathSettings::impl_getPathValue(sal_Int32 nID) const
+{
+ const PathSettings::PathInfo* pPath = impl_getPathAccessConst(nID);
+ if (! pPath)
+ throw css::container::NoSuchElementException();
+
+ css::uno::Any aVal;
+ switch(impl_getPropGroup(nID))
+ {
+ case IDGROUP_OLDSTYLE :
+ {
+ ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPath);
+ aVal <<= sVal;
+ }
+ break;
+
+ case IDGROUP_INTERNAL_PATHES :
+ {
+ aVal <<= pPath->lInternalPaths.getAsConstList();
+ }
+ break;
+
+ case IDGROUP_USER_PATHES :
+ {
+ aVal <<= pPath->lUserPaths.getAsConstList();
+ }
+ break;
+
+ case IDGROUP_WRITE_PATH :
+ {
+ aVal <<= pPath->sWritePath;
+ }
+ break;
+ }
+
+ return aVal;
+}
+
+//-----------------------------------------------------------------------------
+void PathSettings::impl_setPathValue( sal_Int32 nID ,
+ const css::uno::Any& aVal)
+{
+ PathSettings::PathInfo* pOrgPath = impl_getPathAccess(nID);
+ if (! pOrgPath)
+ throw css::container::NoSuchElementException();
+
+ // We work on a copied path ... so we can be sure that errors during this operation
+ // does not make our internal cache invalid .-)
+ PathSettings::PathInfo aChangePath(*pOrgPath);
+
+ switch(impl_getPropGroup(nID))
+ {
+ case IDGROUP_OLDSTYLE :
+ {
+ ::rtl::OUString sVal;
+ aVal >>= sVal;
+ OUStringList lList = impl_convertOldStyle2Path(sVal);
+ impl_subst(lList, fa_getSubstitution(), sal_False);
+ impl_purgeKnownPaths(aChangePath, lList);
+ if (! impl_isValidPath(lList))
+ throw css::lang::IllegalArgumentException();
+
+ if (aChangePath.bIsSinglePath)
+ {
+ LOG_ASSERT2(lList.size()>1, "PathSettings::impl_setPathValue()", "You try to set more then path value for a defined SINGLE_PATH!")
+ if ( !lList.empty() )
+ aChangePath.sWritePath = *(lList.begin());
+ else
+ aChangePath.sWritePath = ::rtl::OUString();
+ }
+ else
+ {
+ OUStringList::const_iterator pIt;
+ for ( pIt = lList.begin();
+ pIt != lList.end() ;
+ ++pIt )
+ {
+ aChangePath.lUserPaths.push_back(*pIt);
+ }
+ }
+ }
+ break;
+
+ case IDGROUP_INTERNAL_PATHES :
+ {
+ if (aChangePath.bIsSinglePath)
+ {
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("The path '" );
+ sMsg.append (aChangePath.sPathName);
+ sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal pathes cant be set.");
+ throw css::uno::Exception(sMsg.makeStringAndClear(),
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ OUStringList lList;
+ lList << aVal;
+ if (! impl_isValidPath(lList))
+ throw css::lang::IllegalArgumentException();
+ aChangePath.lInternalPaths = lList;
+ }
+ break;
+
+ case IDGROUP_USER_PATHES :
+ {
+ if (aChangePath.bIsSinglePath)
+ {
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("The path '" );
+ sMsg.append (aChangePath.sPathName);
+ sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal pathes cant be set.");
+ throw css::uno::Exception(sMsg.makeStringAndClear(),
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ OUStringList lList;
+ lList << aVal;
+ if (! impl_isValidPath(lList))
+ throw css::lang::IllegalArgumentException();
+ aChangePath.lUserPaths = lList;
+ }
+ break;
+
+ case IDGROUP_WRITE_PATH :
+ {
+ ::rtl::OUString sVal;
+ aVal >>= sVal;
+ if (! impl_isValidPath(sVal))
+ throw css::lang::IllegalArgumentException();
+ aChangePath.sWritePath = sVal;
+ }
+ break;
+ }
+
+ // TODO check if path has at least one path value set
+ // At least it depends from the feature using this path, if an empty path list is allowed.
+
+ // first we should try to store the changed (copied!) path ...
+ // In case an error occure on saving time an exception is thrown ...
+ // If no exception occures we can update our internal cache (means
+ // we can overwrite pOrgPath !
+ impl_storePath(aChangePath);
+ pOrgPath->takeOver(aChangePath);
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool PathSettings::impl_isValidPath(const OUStringList& lPath) const
+{
+ OUStringList::const_iterator pIt;
+ for ( pIt = lPath.begin();
+ pIt != lPath.end() ;
+ ++pIt )
+ {
+ const ::rtl::OUString& rVal = *pIt;
+ if (! impl_isValidPath(rVal))
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool PathSettings::impl_isValidPath(const ::rtl::OUString& sPath) const
+{
+ // allow empty path to reset a path.
+// idea by LLA to support empty pathes
+// if (sPath.getLength() == 0)
+// {
+// return sal_True;
+// }
+
+ return (! INetURLObject(sPath).HasError());
+}
+
+//-----------------------------------------------------------------------------
+::rtl::OUString impl_extractBaseFromPropName(const ::rtl::OUString& sPropName)
+{
+ sal_Int32 i = -1;
+
+ i = sPropName.indexOf(POSTFIX_INTERNAL_PATHES);
+ if (i > -1)
+ return sPropName.copy(0, i);
+ i = sPropName.indexOf(POSTFIX_USER_PATHES);
+ if (i > -1)
+ return sPropName.copy(0, i);
+ i = sPropName.indexOf(POSTFIX_WRITE_PATH);
+ if (i > -1)
+ return sPropName.copy(0, i);
+
+ return sPropName;
+}
+
+//-----------------------------------------------------------------------------
+PathSettings::PathInfo* PathSettings::impl_getPathAccess(sal_Int32 nHandle)
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ if (nHandle > (m_lPropDesc.getLength()-1))
+ return 0;
+
+ const css::beans::Property& rProp = m_lPropDesc[nHandle];
+ ::rtl::OUString sProp = impl_extractBaseFromPropName(rProp.Name);
+ PathSettings::PathHash::iterator rPath = m_lPaths.find(sProp);
+
+ if (rPath != m_lPaths.end())
+ return &(rPath->second);
+
+ return 0;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+const PathSettings::PathInfo* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle) const
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+
+ if (nHandle > (m_lPropDesc.getLength()-1))
+ return 0;
+
+ const css::beans::Property& rProp = m_lPropDesc[nHandle];
+ ::rtl::OUString sProp = impl_extractBaseFromPropName(rProp.Name);
+ PathSettings::PathHash::const_iterator rPath = m_lPaths.find(sProp);
+
+ if (rPath != m_lPaths.end())
+ return &(rPath->second);
+
+ return 0;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL PathSettings::convertFastPropertyValue( css::uno::Any& aConvertedValue,
+ css::uno::Any& aOldValue ,
+ sal_Int32 nHandle ,
+ const css::uno::Any& aValue )
+ throw(css::lang::IllegalArgumentException)
+{
+ // throws NoSuchElementException !
+ css::uno::Any aCurrentVal = impl_getPathValue(nHandle);
+
+ return PropHelper::willPropertyBeChanged(
+ aCurrentVal,
+ aValue,
+ aOldValue,
+ aConvertedValue);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PathSettings::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,
+ const css::uno::Any& aValue )
+ throw(css::uno::Exception)
+{
+ // throws NoSuchElement- and IllegalArgumentException !
+ impl_setPathValue(nHandle, aValue);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PathSettings::getFastPropertyValue(css::uno::Any& aValue ,
+ sal_Int32 nHandle) const
+{
+ aValue = impl_getPathValue(nHandle);
+}
+
+//-----------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& SAL_CALL PathSettings::getInfoHelper()
+{
+ return *m_pPropHelp;
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PathSettings::getPropertySetInfo()
+ throw(css::uno::RuntimeException)
+{
+ return css::uno::Reference< css::beans::XPropertySetInfo >(createPropertySetInfo(getInfoHelper()));
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::util::XStringSubstitution > PathSettings::fa_getSubstitution()
+{
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ css::uno::Reference< css::util::XStringSubstitution > xSubst = m_xSubstitution;
+ aReadLock.unlock();
+ // <- SAFE
+
+ if (! xSubst.is())
+ {
+ // create the needed substitution service.
+ // We must replace all used variables inside readed path values.
+ // In case we can't do so ... the whole office can't work realy.
+ // That's why it seams to be OK to throw a RuntimeException then.
+ xSubst = css::uno::Reference< css::util::XStringSubstitution >(
+ xSMGR->createInstance(SERVICENAME_SUBSTITUTEPATHVARIABLES),
+ css::uno::UNO_QUERY_THROW);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ m_xSubstitution = xSubst;
+ aWriteLock.unlock();
+ }
+
+ return xSubst;
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgOld()
+{
+ const static ::rtl::OUString CFG_NODE_OLD(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/Path/Current"));
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ css::uno::Reference< css::container::XNameAccess > xCfg = m_xCfgOld;
+ aReadLock.unlock();
+ // <- SAFE
+
+ if (! xCfg.is())
+ {
+ xCfg = css::uno::Reference< css::container::XNameAccess >(
+ ::comphelper::ConfigurationHelper::openConfig(
+ xSMGR,
+ CFG_NODE_OLD,
+ ::comphelper::ConfigurationHelper::E_STANDARD), // not readonly! Somtimes we need write access there !!!
+ css::uno::UNO_QUERY_THROW);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ m_xCfgOld = xCfg;
+ aWriteLock.unlock();
+ }
+
+ return xCfg;
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgNew()
+{
+ const static ::rtl::OUString CFG_NODE_NEW(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Paths/Paths"));
+
+ // SAFE ->
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ css::uno::Reference< css::container::XNameAccess > xCfg = m_xCfgNew;
+ aReadLock.unlock();
+ // <- SAFE
+
+ if (! xCfg.is())
+ {
+ xCfg = css::uno::Reference< css::container::XNameAccess >(
+ ::comphelper::ConfigurationHelper::openConfig(
+ xSMGR,
+ CFG_NODE_NEW,
+ ::comphelper::ConfigurationHelper::E_STANDARD),
+ css::uno::UNO_QUERY_THROW);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_aLock);
+ m_xCfgNew = xCfg;
+ m_xCfgNewListener = new WeakChangesListener(this);
+ aWriteLock.unlock();
+
+ css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(xCfg, css::uno::UNO_QUERY_THROW);
+ xBroadcaster->addChangesListener(m_xCfgNewListener);
+ }
+
+ return xCfg;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/sessionlistener.cxx b/framework/source/services/sessionlistener.cxx
new file mode 100644
index 000000000000..1adfea3af683
--- /dev/null
+++ b/framework/source/services/sessionlistener.cxx
@@ -0,0 +1,368 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+//_______________________________________________
+// my own includes
+
+#include <services/sessionlistener.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <protocols.h>
+#include <services.h>
+
+#include <osl/thread.h>
+
+
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/tempfile.hxx>
+#include <unotools/tempfile.hxx>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <osl/time.h>
+#include <comphelper/processfactory.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/internaloptions.hxx>
+#include <stdio.h>
+//_______________________________________________
+// interface includes
+#include <com/sun/star/uno/Any.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+//_______________________________________________
+// includes of other projects
+
+//_______________________________________________
+// namespace
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+
+using ::rtl::OUString;
+using ::rtl::OString;
+namespace framework{
+
+//_______________________________________________
+// non exported const
+
+//_______________________________________________
+// non exported definitions
+
+//_______________________________________________
+// declarations
+
+//***********************************************
+// XInterface, XTypeProvider, XServiceInfo
+
+DEFINE_XINTERFACE_6(
+ SessionListener,
+ OWeakObject,
+ DIRECT_INTERFACE(css::lang::XTypeProvider),
+ DIRECT_INTERFACE(css::lang::XInitialization),
+ DIRECT_INTERFACE(css::frame::XSessionManagerListener),
+ DIRECT_INTERFACE(css::frame::XSessionManagerListener2),
+ DIRECT_INTERFACE(css::frame::XStatusListener),
+ DIRECT_INTERFACE(css::lang::XServiceInfo))
+
+DEFINE_XTYPEPROVIDER_5(
+ SessionListener,
+ css::lang::XTypeProvider,
+ css::lang::XInitialization,
+ css::frame::XSessionManagerListener2,
+ css::frame::XStatusListener,
+ css::lang::XServiceInfo)
+
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(
+ SessionListener,
+ cppu::OWeakObject,
+ SERVICENAME_SESSIONLISTENER,
+ IMPLEMENTATIONNAME_SESSIONLISTENER)
+
+DEFINE_INIT_SERVICE(SessionListener,
+ {
+ /* Add special code for initialization here, if you have to use your own instance
+ during your ctor is still in progress! */
+ }
+ )
+
+SessionListener::SessionListener(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , OWeakObject ( )
+ , m_xSMGR (xSMGR )
+ , m_bRestored( sal_False )
+ , m_bSessionStoreRequested( sal_False )
+ , m_bAllowUserInteractionOnQuit( sal_False )
+ , m_bTerminated( sal_False )
+{
+}
+
+SessionListener::~SessionListener()
+{
+ if (m_rSessionManager.is())
+ {
+ css::uno::Reference< XSessionManagerListener> me(this);
+ m_rSessionManager->removeSessionManagerListener(me);
+ }
+}
+
+void SessionListener::StoreSession( sal_Bool bAsync )
+{
+ ResetableGuard aGuard(m_aLock);
+ try
+ {
+ // xd create SERVICENAME_AUTORECOVERY -> XDispatch
+ // xd->dispatch("vnd.sun.star.autorecovery:/doSessionSave, async=bAsync
+ // on stop event m_rSessionManager->saveDone(this); in case of asynchronous call
+ // in case of synchronous call the caller should do saveDone() call himself!
+
+ css::uno::Reference< XDispatch > xDispatch(m_xSMGR->createInstance(SERVICENAME_AUTORECOVERY), UNO_QUERY_THROW);
+ css::uno::Reference< XURLTransformer > xURLTransformer(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), UNO_QUERY_THROW);
+ URL aURL;
+ aURL.Complete = OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.autorecovery:/doSessionSave"));
+ xURLTransformer->parseStrict(aURL);
+
+ // in case of asynchronous call the notification will trigger saveDone()
+ if ( bAsync )
+ xDispatch->addStatusListener(this, aURL);
+
+ Sequence< PropertyValue > args(1);
+ args[0] = PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("DispatchAsynchron")),-1,makeAny(bAsync),PropertyState_DIRECT_VALUE);
+ xDispatch->dispatch(aURL, args);
+ } catch (com::sun::star::uno::Exception& e) {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8);
+ OSL_FAIL(aMsg.getStr());
+ // save failed, but tell manager to go on if we havent yet dispatched the request
+ // in case of synchronous saving the notification is done by the caller
+ if ( bAsync && m_rSessionManager.is() )
+ m_rSessionManager->saveDone(this);
+ }
+}
+
+void SessionListener::QuitSessionQuietly()
+{
+ ResetableGuard aGuard(m_aLock);
+ try
+ {
+ // xd create SERVICENAME_AUTORECOVERY -> XDispatch
+ // xd->dispatch("vnd.sun.star.autorecovery:/doSessionQuietQuit, async=false
+ // it is done synchronously to avoid conflict with normal quit process
+
+ css::uno::Reference< XDispatch > xDispatch(m_xSMGR->createInstance(SERVICENAME_AUTORECOVERY), UNO_QUERY_THROW);
+ css::uno::Reference< XURLTransformer > xURLTransformer(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), UNO_QUERY_THROW);
+ URL aURL;
+ aURL.Complete = OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.autorecovery:/doSessionQuietQuit"));
+ xURLTransformer->parseStrict(aURL);
+
+ Sequence< PropertyValue > args(1);
+ args[0] = PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("DispatchAsynchron")),-1,makeAny(sal_False),PropertyState_DIRECT_VALUE);
+ xDispatch->dispatch(aURL, args);
+ } catch (com::sun::star::uno::Exception& e) {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8);
+ OSL_FAIL(aMsg.getStr());
+ }
+}
+
+void SAL_CALL SessionListener::disposing(const com::sun::star::lang::EventObject&) throw (RuntimeException)
+{
+}
+
+void SAL_CALL SessionListener::initialize(const Sequence< Any >& args)
+ throw (RuntimeException)
+{
+
+ OUString aSMgr(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.SessionManagerClient"));
+ if (args.getLength() > 0)
+ {
+ NamedValue v;
+ for (int i = 0; i < args.getLength(); i++)
+ {
+ if (args[i] >>= v)
+ {
+ if (v.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SessionManagerName")))
+ v.Value >>= aSMgr;
+ else if (v.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SessionManager")))
+ v.Value >>= m_rSessionManager;
+ else if (v.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("AllowUserInteractionOnQuit")))
+ v.Value >>= m_bAllowUserInteractionOnQuit;
+ }
+ }
+ }
+ if (!m_rSessionManager.is())
+ m_rSessionManager = css::uno::Reference< XSessionManagerClient >
+ (m_xSMGR->createInstance(aSMgr), UNO_QUERY);
+
+ if (m_rSessionManager.is())
+ {
+ m_rSessionManager->addSessionManagerListener(this);
+ }
+}
+
+void SAL_CALL SessionListener::statusChanged(const FeatureStateEvent& event)
+ throw (css::uno::RuntimeException)
+{
+ if (event.FeatureURL.Complete.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.autorecovery:/doSessionRestore")))
+ {
+ if (event.FeatureDescriptor.compareToAscii("update")==0)
+ m_bRestored = sal_True; // a document was restored
+
+ }
+ else if (event.FeatureURL.Complete.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.autorecovery:/doSessionSave")))
+ {
+ if (event.FeatureDescriptor.compareToAscii("stop")==0)
+ {
+ if (m_rSessionManager.is())
+ m_rSessionManager->saveDone(this); // done with save
+ }
+ }
+}
+
+
+sal_Bool SAL_CALL SessionListener::doRestore()
+ throw (RuntimeException)
+{
+ ResetableGuard aGuard(m_aLock);
+ m_bRestored = sal_False;
+ try {
+ css::uno::Reference< XDispatch > xDispatch(m_xSMGR->createInstance(SERVICENAME_AUTORECOVERY), UNO_QUERY_THROW);
+
+ URL aURL;
+ aURL.Complete = OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.autorecovery:/doSessionRestore"));
+ css::uno::Reference< XURLTransformer > xURLTransformer(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), UNO_QUERY_THROW);
+ xURLTransformer->parseStrict(aURL);
+ Sequence< PropertyValue > args;
+ xDispatch->addStatusListener(this, aURL);
+ xDispatch->dispatch(aURL, args);
+ m_bRestored = sal_True;
+
+ } catch (com::sun::star::uno::Exception& e) {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8);
+ OSL_FAIL(aMsg.getStr());
+ }
+
+ return m_bRestored;
+}
+
+
+void SAL_CALL SessionListener::doSave( sal_Bool bShutdown, sal_Bool /*bCancelable*/ )
+ throw (RuntimeException)
+{
+ if (bShutdown)
+ {
+ m_bSessionStoreRequested = sal_True; // there is no need to protect it with mutex
+ if ( m_bAllowUserInteractionOnQuit && m_rSessionManager.is() )
+ m_rSessionManager->queryInteraction( static_cast< css::frame::XSessionManagerListener* >( this ) );
+ else
+ StoreSession( sal_True );
+ }
+ // we don't have anything to do so tell the session manager we're done
+ else if( m_rSessionManager.is() )
+ m_rSessionManager->saveDone( this );
+}
+
+void SAL_CALL SessionListener::approveInteraction( sal_Bool bInteractionGranted )
+ throw (RuntimeException)
+{
+ // do AutoSave as the first step
+ ResetableGuard aGuard(m_aLock);
+
+ if ( bInteractionGranted )
+ {
+ // close the office documents in normal way
+ try
+ {
+ // first of all let the session be stored to be sure that we lose no information
+ StoreSession( sal_False );
+
+ css::uno::Reference< css::frame::XDesktop > xDesktop( m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
+ m_bTerminated = xDesktop->terminate();
+
+ if ( m_rSessionManager.is() )
+ {
+ // false means that the application closing has been cancelled
+ if ( !m_bTerminated )
+ m_rSessionManager->cancelShutdown();
+ else
+ m_rSessionManager->interactionDone( this );
+ }
+ }
+ catch( css::uno::Exception& )
+ {
+ StoreSession( sal_True );
+ m_rSessionManager->interactionDone( this );
+ }
+
+ if ( m_rSessionManager.is() )
+ m_rSessionManager->saveDone(this);
+ }
+ else
+ {
+ StoreSession( sal_True );
+ }
+}
+
+void SessionListener::shutdownCanceled()
+ throw (RuntimeException)
+{
+ // set the state back
+ m_bSessionStoreRequested = sal_False; // there is no need to protect it with mutex
+}
+
+void SessionListener::doQuit()
+ throw (RuntimeException)
+{
+ if ( m_bSessionStoreRequested && !m_bTerminated )
+ {
+ // let the session be closed quietly in this case
+ QuitSessionQuietly();
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/substitutepathvars.cxx b/framework/source/services/substitutepathvars.cxx
new file mode 100644
index 000000000000..bded3d54af72
--- /dev/null
+++ b/framework/source/services/substitutepathvars.cxx
@@ -0,0 +1,1265 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "services/substitutepathvars.hxx"
+#include <threadhelp/resetableguard.hxx>
+#include <helper/networkdomain.hxx>
+#include "services.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <unotools/configitem.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <unotools/bootstrap.hxx>
+#include <osl/mutex.hxx>
+#include <osl/file.hxx>
+#include <osl/security.hxx>
+#include <osl/socket.hxx>
+#include <osl/process.h>
+#include <i18npool/mslangid.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/resmgr.hxx>
+#include <tools/debug.hxx>
+#include <tools/wldcrd.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/bootstrap.hxx>
+
+#include <comphelper/configurationhelper.hxx>
+
+#include <string.h>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+#define STRPOS_NOTFOUND (sal_Int32)-1
+
+#define ASCII_STR( val ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( val ))
+
+#define SEARCHPATH_DELIMITER ';'
+
+// Variable start/end characters
+#define SIGN_STARTVARIABLE ASCII_STR("$(")
+#define SIGN_ENDVARIABLE ASCII_STR(")")
+
+// Length of SUBSTITUTE_... to replace it with real values.
+#define REPLACELENGTH_INST 7
+#define REPLACELENGTH_PROG 7
+#define REPLACELENGTH_USER 7
+#define REPLACELENGTH_WORK 7
+#define REPLACELENGTH_HOME 7
+#define REPLACELENGTH_TEMP 7
+#define REPLACELENGTH_PATH 7
+#define REPLACELENGTH_INSTPATH 11
+#define REPLACELENGTH_PROGPATH 11
+#define REPLACELENGTH_USERPATH 11
+#define REPLACELENGTH_INSTURL 10
+#define REPLACELENGTH_PROGURL 10
+#define REPLACELENGTH_USERURL 10
+#define REPLACELENGTH_PATH 7
+#define REPLACELENGTH_LANG 7
+#define REPLACELENGTH_LANGID 9
+#define REPLACELENGTH_VLANG 8
+#define REPLACELENGTH_WORKDIRURL 13
+// New variable of hierachy service (#i32656#)
+#define REPLACELENGTH_BASEINSTURL 14
+#define REPLACELENGTH_USERDATAURL 14
+
+// Name of the pre defined path variables
+#define VARIABLE_INST "$(inst)"
+#define VARIABLE_PROG "$(prog)"
+#define VARIABLE_USER "$(user)"
+#define VARIABLE_WORK "$(work)"
+#define VARIABLE_HOME "$(home)"
+#define VARIABLE_TEMP "$(temp)"
+#define VARIABLE_PATH "$(path)"
+#define VARIABLE_LANG "$(lang)"
+#define VARIABLE_LANGID "$(langid)"
+#define VARIABLE_VLANG "$(vlang)"
+#define VARIABLE_INSTPATH "$(instpath)"
+#define VARIABLE_PROGPATH "$(progpath)"
+#define VARIABLE_USERPATH "$(userpath)"
+#define VARIABLE_INSTURL "$(insturl)"
+#define VARIABLE_PROGURL "$(progurl)"
+#define VARIABLE_USERURL "$(userurl)"
+#define VARIABLE_WORKDIRURL "$(workdirurl)"
+// New variable of hierachy service (#i32656#)
+#define VARIABLE_BASEINSTURL "$(baseinsturl)"
+#define VARIABLE_USERDATAURL "$(userdataurl)"
+#define VARIABLE_BRANDBASEURL "$(brandbaseurl)"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+
+struct FixedVariable
+{
+ const char* pVarName;
+ PreDefVariable nEnumValue;
+ int nStrLen;
+ bool bAbsPath;
+};
+
+struct TableEntry
+{
+ const char* pOSString;
+ int nStrLen;
+};
+
+// Table with valid operating system strings
+// Name of the os as char* and the length
+// of the string
+static TableEntry aOSTable[OS_COUNT] =
+{
+ { "WINDOWS" , 7 },
+ { "UNIX" , 4 },
+ { "SOLARIS" , 7 },
+ { "LINUX" , 5 },
+ { "" , 0 } // unknown
+};
+
+// Table with valid environment variables
+// Name of the environment type as a char* and
+// the length of the string.
+static TableEntry aEnvTable[ET_COUNT] =
+{
+ { "HOST" , 4 },
+ { "YPDOMAIN" , 8 },
+ { "DNSDOMAIN" , 9 },
+ { "NTDOMAIN" , 8 },
+ { "OS" , 2 },
+ { "" , 0 } // unknown
+};
+
+// Priority table for the environment types. Lower numbers define
+// a higher priority. Equal numbers has the same priority that means
+// that the first match wins!!
+static sal_Int16 aEnvPrioTable[ET_COUNT] =
+{
+ 1, // ET_HOST
+ 2, // ET_IPDOMAIN
+ 2, // ET_DNSDOMAIN
+ 2, // ET_NTDOMAIN
+ 3, // ET_OS
+ 99, // ET_UNKNOWN
+};
+
+// Table with all fixed/predefined variables supported.
+static FixedVariable aFixedVarTable[] =
+{
+ { VARIABLE_INST, PREDEFVAR_INST, REPLACELENGTH_INST, true },
+ { VARIABLE_PROG, PREDEFVAR_PROG, REPLACELENGTH_PROG, true },
+ { VARIABLE_USER, PREDEFVAR_USER, REPLACELENGTH_USER, true },
+ { VARIABLE_WORK, PREDEFVAR_WORK, REPLACELENGTH_WORK, true }, // Special variable (transient)!
+ { VARIABLE_HOME, PREDEFVAR_HOME, REPLACELENGTH_HOME, true },
+ { VARIABLE_TEMP, PREDEFVAR_TEMP, REPLACELENGTH_TEMP, true },
+ { VARIABLE_PATH, PREDEFVAR_PATH, REPLACELENGTH_PATH, true },
+ { VARIABLE_LANG, PREDEFVAR_LANG, REPLACELENGTH_LANG, false },
+ { VARIABLE_LANGID, PREDEFVAR_LANGID, REPLACELENGTH_LANGID, false },
+ { VARIABLE_VLANG, PREDEFVAR_VLANG, REPLACELENGTH_VLANG, false },
+ { VARIABLE_INSTPATH, PREDEFVAR_INSTPATH, REPLACELENGTH_INSTPATH, true },
+ { VARIABLE_PROGPATH, PREDEFVAR_PROGPATH, REPLACELENGTH_PROGPATH, true },
+ { VARIABLE_USERPATH, PREDEFVAR_USERPATH, REPLACELENGTH_USERPATH, true },
+ { VARIABLE_INSTURL, PREDEFVAR_INSTURL, REPLACELENGTH_INSTURL, true },
+ { VARIABLE_PROGURL, PREDEFVAR_PROGURL, REPLACELENGTH_PROGURL, true },
+ { VARIABLE_USERURL, PREDEFVAR_USERURL, REPLACELENGTH_USERURL, true },
+ { VARIABLE_WORKDIRURL, PREDEFVAR_WORKDIRURL, REPLACELENGTH_WORKDIRURL,true }, // Special variable (transient) and don't use for resubstitution!
+ // New variable of hierachy service (#i32656#)
+ { VARIABLE_BASEINSTURL, PREDEFVAR_BASEINSTURL, REPLACELENGTH_BASEINSTURL,true },
+ { VARIABLE_USERDATAURL, PREDEFVAR_USERDATAURL, REPLACELENGTH_USERDATAURL,true },
+ { VARIABLE_BRANDBASEURL,PREDEFVAR_BRANDBASEURL, RTL_CONSTASCII_LENGTH(VARIABLE_BRANDBASEURL), true }
+};
+
+//_________________________________________________________________________________________________________________
+// Implementation helper classes
+//_________________________________________________________________________________________________________________
+
+OperatingSystem SubstitutePathVariables_Impl::GetOperatingSystemFromString( const rtl::OUString& aOSString )
+{
+ for ( int i = 0; i < OS_COUNT; i++ )
+ {
+ if ( aOSString.equalsIgnoreAsciiCaseAsciiL( aOSTable[i].pOSString, aOSTable[i].nStrLen ))
+ return (OperatingSystem)i;
+ }
+
+ return OS_UNKNOWN;
+}
+
+EnvironmentType SubstitutePathVariables_Impl::GetEnvTypeFromString( const rtl::OUString& aEnvTypeString )
+{
+ for ( int i = 0; i < ET_COUNT; i++ )
+ {
+ if ( aEnvTypeString.equalsIgnoreAsciiCaseAsciiL( aEnvTable[i].pOSString, aEnvTable[i].nStrLen ))
+ return (EnvironmentType)i;
+ }
+
+ return ET_UNKNOWN;
+}
+
+SubstitutePathVariables_Impl::SubstitutePathVariables_Impl( const Link& aNotifyLink ) :
+ utl::ConfigItem( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.Substitution" ))),
+ m_bYPDomainRetrieved( false ),
+ m_bDNSDomainRetrieved( false ),
+ m_bNTDomainRetrieved( false ),
+ m_bHostRetrieved( false ),
+ m_bOSRetrieved( false ),
+ m_aListenerNotify( aNotifyLink ),
+ m_aSharePointsNodeName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SharePoints" ))),
+ m_aDirPropertyName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/Directory" ))),
+ m_aEnvPropertyName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/Environment" ))),
+ m_aLevelSep( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" )))
+{
+ // Enable notification mechanism
+ // We need it to get information about changes outside these class on our configuration branch
+ Sequence< rtl::OUString > aNotifySeq( 1 );
+ aNotifySeq[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SharePoints" ));
+ EnableNotification( aNotifySeq, sal_True );
+}
+
+SubstitutePathVariables_Impl::~SubstitutePathVariables_Impl()
+{
+}
+
+void SubstitutePathVariables_Impl::GetSharePointsRules( SubstituteVariables& aSubstVarMap )
+{
+ Sequence< rtl::OUString > aSharePointNames;
+ ReadSharePointsFromConfiguration( aSharePointNames );
+
+ if ( aSharePointNames.getLength() > 0 )
+ {
+ sal_Int32 nSharePoints = 0;
+
+ // Read SharePoints container from configuration
+ while ( nSharePoints < aSharePointNames.getLength() )
+ {
+ rtl::OUString aSharePointNodeName( m_aSharePointsNodeName );
+ aSharePointNodeName += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+ aSharePointNodeName += aSharePointNames[ nSharePoints ];
+
+ SubstituteRuleVector aRuleSet;
+ ReadSharePointRuleSetFromConfiguration( aSharePointNames[ nSharePoints ], aSharePointNodeName, aRuleSet );
+ if ( !aRuleSet.empty() )
+ {
+ // We have at minimum one rule. Filter the correct rule out of the rule set
+ // and put into our SubstituteVariable map
+ SubstituteRule aActiveRule;
+ if ( FilterRuleSet( aRuleSet, aActiveRule ))
+ {
+ // We have found an active rule
+ aActiveRule.aSubstVariable = aSharePointNames[ nSharePoints ];
+ aSubstVarMap.insert( SubstituteVariables::value_type(
+ aActiveRule.aSubstVariable, aActiveRule ));
+ }
+ }
+ ++nSharePoints;
+ }
+ }
+}
+
+void SubstitutePathVariables_Impl::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& /*aPropertyNames*/ )
+{
+ // NOT implemented yet!
+}
+
+void SubstitutePathVariables_Impl::Commit()
+{
+}
+
+
+//_________________________________________________________________________________________________________________
+// private methods
+//_________________________________________________________________________________________________________________
+
+OperatingSystem SubstitutePathVariables_Impl::GetOperatingSystem()
+{
+ if ( !m_bOSRetrieved )
+ {
+#ifdef SOLARIS
+ m_eOSType = OS_SOLARIS;
+#elif defined LINUX
+ m_eOSType = OS_LINUX;
+#elif defined WIN32
+ m_eOSType = OS_WINDOWS;
+#elif defined UNIX
+ m_eOSType = OS_UNIX;
+#else
+ m_eOSType = OS_UNKNOWN;
+#endif
+ m_bOSRetrieved = sal_True;
+ }
+
+ return m_eOSType;
+}
+
+const rtl::OUString& SubstitutePathVariables_Impl::GetYPDomainName()
+{
+ if ( !m_bYPDomainRetrieved )
+ {
+ m_aYPDomain = NetworkDomain::GetYPDomainName().toAsciiLowerCase();
+ m_bYPDomainRetrieved = sal_True;
+ }
+
+ return m_aYPDomain;
+}
+
+const rtl::OUString& SubstitutePathVariables_Impl::GetDNSDomainName()
+{
+ if ( !m_bDNSDomainRetrieved )
+ {
+ rtl::OUString aTemp;
+ osl::SocketAddr aSockAddr;
+ oslSocketResult aResult;
+
+ rtl::OUString aHostName = GetHostName();
+ osl::SocketAddr::resolveHostname( aHostName, aSockAddr );
+ aTemp = aSockAddr.getHostname( &aResult );
+
+ // DNS domain name begins after the first "."
+ sal_Int32 nIndex = aTemp.indexOf( '.' );
+ if ( nIndex >= 0 && aTemp.getLength() > nIndex+1 )
+ m_aDNSDomain = aTemp.copy( nIndex+1 ).toAsciiLowerCase();
+ else
+ m_aDNSDomain = rtl::OUString();
+
+ m_bDNSDomainRetrieved = sal_True;
+ }
+
+ return m_aDNSDomain;
+}
+
+const rtl::OUString& SubstitutePathVariables_Impl::GetNTDomainName()
+{
+ if ( !m_bNTDomainRetrieved )
+ {
+ m_aNTDomain = NetworkDomain::GetNTDomainName().toAsciiLowerCase();
+ m_bNTDomainRetrieved = sal_True;
+ }
+
+ return m_aNTDomain;
+}
+
+const rtl::OUString& SubstitutePathVariables_Impl::GetHostName()
+{
+ if ( !m_bHostRetrieved )
+ {
+ rtl::OUString aHostName;
+ oslSocketResult aSocketResult;
+
+ m_aHost = osl::SocketAddr::getLocalHostname( &aSocketResult ).toAsciiLowerCase();
+ }
+
+ return m_aHost;
+}
+
+bool SubstitutePathVariables_Impl::FilterRuleSet( const SubstituteRuleVector& aRuleSet, SubstituteRule& aActiveRule )
+{
+ bool bResult = sal_False;
+
+ if ( !aRuleSet.empty() )
+ {
+ const sal_uInt32 nCount = aRuleSet.size();
+
+ sal_Int16 nPrioCurrentRule = aEnvPrioTable[ ET_UNKNOWN ];
+ for ( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ const SubstituteRule& aRule = aRuleSet[nIndex];
+ EnvironmentType eEnvType = aRule.aEnvType;
+
+ // Check if environment type has a higher priority than current one!
+ if ( nPrioCurrentRule > aEnvPrioTable[eEnvType] )
+ {
+ switch ( eEnvType )
+ {
+ case ET_HOST:
+ {
+ rtl::OUString aHost = GetHostName();
+ rtl::OUString aHostStr;
+ aRule.aEnvValue >>= aHostStr;
+ aHostStr = aHostStr.toAsciiLowerCase();
+
+ // Pattern match if domain environment match
+ WildCard aPattern(aHostStr);
+ bool bMatch = aPattern.Matches(aHost);
+ if ( bMatch )
+ {
+ aActiveRule = aRule;
+ bResult = true;
+ nPrioCurrentRule = aEnvPrioTable[eEnvType];
+ }
+ }
+ break;
+
+ case ET_YPDOMAIN:
+ case ET_DNSDOMAIN:
+ case ET_NTDOMAIN:
+ {
+ rtl::OUString aDomain;
+ rtl::OUString aDomainStr;
+ aRule.aEnvValue >>= aDomainStr;
+ aDomainStr = aDomainStr.toAsciiLowerCase();
+
+ // Retrieve the correct domain value
+ if ( eEnvType == ET_YPDOMAIN )
+ aDomain = GetYPDomainName();
+ else if ( eEnvType == ET_DNSDOMAIN )
+ aDomain = GetDNSDomainName();
+ else
+ aDomain = GetNTDomainName();
+
+ // Pattern match if domain environment match
+ WildCard aPattern(aDomainStr);
+ bool bMatch = aPattern.Matches(aDomain);
+ if ( bMatch )
+ {
+ aActiveRule = aRule;
+ bResult = true;
+ nPrioCurrentRule = aEnvPrioTable[eEnvType];
+ }
+ }
+ break;
+
+ case ET_OS:
+ {
+ // No pattern matching for OS type
+ OperatingSystem eOSType = GetOperatingSystem();
+
+ sal_Int16 nValue = 0;
+ aRule.aEnvValue >>= nValue;
+
+ bool bUnix = ( eOSType == OS_LINUX ) || ( eOSType == OS_SOLARIS );
+ OperatingSystem eRuleOSType = (OperatingSystem)nValue;
+
+ // Match if OS identical or rule is set to UNIX and OS is LINUX/SOLARIS!
+ if (( eRuleOSType == eOSType ) || ( eRuleOSType == OS_UNIX && bUnix ))
+ {
+ aActiveRule = aRule;
+ bResult = true;
+ nPrioCurrentRule = aEnvPrioTable[eEnvType];
+ }
+ }
+ break;
+
+ case ET_UNKNOWN: // nothing to do
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return bResult;
+}
+
+void SubstitutePathVariables_Impl::ReadSharePointsFromConfiguration( Sequence< rtl::OUString >& aSharePointsSeq )
+{
+ //returns all the names of all share point nodes
+ aSharePointsSeq = GetNodeNames( m_aSharePointsNodeName );
+}
+
+void SubstitutePathVariables_Impl::ReadSharePointRuleSetFromConfiguration(
+ const rtl::OUString& aSharePointName,
+ const rtl::OUString& aSharePointNodeName,
+ SubstituteRuleVector& rRuleSet )
+{
+ Sequence< rtl::OUString > aSharePointMappingsNodeNames = GetNodeNames( aSharePointNodeName, utl::CONFIG_NAME_LOCAL_PATH );
+
+ sal_Int32 nSharePointMapping = 0;
+ while ( nSharePointMapping < aSharePointMappingsNodeNames.getLength() )
+ {
+ rtl::OUString aSharePointMapping( aSharePointNodeName );
+ aSharePointMapping += m_aLevelSep;
+ aSharePointMapping += aSharePointMappingsNodeNames[ nSharePointMapping ];
+
+ // Read SharePointMapping
+ rtl::OUString aDirValue;
+ rtl::OUString aDirProperty( aSharePointMapping );
+ aDirProperty += m_aDirPropertyName;
+
+ // Read only the directory property
+ Sequence< rtl::OUString > aDirPropertySeq( 1 );
+ aDirPropertySeq[0] = aDirProperty;
+
+ Sequence< Any > aValueSeq = GetProperties( aDirPropertySeq );
+ if ( aValueSeq.getLength() == 1 )
+ aValueSeq[0] >>= aDirValue;
+
+ // Read the environment setting
+ rtl::OUString aEnvUsed;
+ rtl::OUString aEnvProperty( aSharePointMapping );
+ aEnvProperty += m_aEnvPropertyName;
+ Sequence< rtl::OUString > aEnvironmentVariable = GetNodeNames( aEnvProperty );
+
+ // Filter the property which has a value set
+ Sequence< rtl::OUString > aEnvUsedPropertySeq( aEnvironmentVariable.getLength() );
+
+ rtl::OUString aEnvUsePropNameTemplate( aEnvProperty );
+ aEnvUsePropNameTemplate += m_aLevelSep;
+
+ for ( sal_Int32 nProperty = 0; nProperty < aEnvironmentVariable.getLength(); nProperty++ )
+ aEnvUsedPropertySeq[nProperty] = rtl::OUString( aEnvUsePropNameTemplate + aEnvironmentVariable[nProperty] );
+
+ Sequence< Any > aEnvUsedValueSeq;
+ aEnvUsedValueSeq = GetProperties( aEnvUsedPropertySeq );
+
+ rtl::OUString aEnvUsedValue;
+ for ( sal_Int32 nIndex = 0; nIndex < aEnvironmentVariable.getLength(); nIndex++ )
+ {
+ if ( aEnvUsedValueSeq[nIndex] >>= aEnvUsedValue )
+ {
+ aEnvUsed = aEnvironmentVariable[nIndex];
+ break;
+ }
+ }
+
+ // Decode the environment and optional the operatng system settings
+ Any aEnvValue;
+ EnvironmentType eEnvType = GetEnvTypeFromString( aEnvUsed );
+ if ( eEnvType == ET_OS )
+ {
+ OperatingSystem eOSType = GetOperatingSystemFromString( aEnvUsedValue );
+ aEnvValue <<= (sal_Int16)eOSType;
+ }
+ else
+ aEnvValue <<= aEnvUsedValue;
+
+ // Create rule struct and push it into the rule set
+ SubstituteRule aRule( aSharePointName, aDirValue, aEnvValue, eEnvType );
+ rRuleSet.push_back( aRule );
+
+ ++nSharePointMapping;
+ }
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( SubstitutePathVariables ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_SUBSTITUTEPATHVARIABLES ,
+ IMPLEMENTATIONNAME_SUBSTITUTEPATHVARIABLES )
+
+DEFINE_INIT_SERVICE ( SubstitutePathVariables, {} )
+
+
+SubstitutePathVariables::SubstitutePathVariables( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase(),
+ m_aVarStart( SIGN_STARTVARIABLE ),
+ m_aVarEnd( SIGN_ENDVARIABLE ),
+ m_aImpl( LINK( this, SubstitutePathVariables, implts_ConfigurationNotify )),
+ m_xServiceManager( xServiceManager )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::SubstitutePathVariables" );
+ int i;
+
+ SetPredefinedPathVariables( m_aPreDefVars );
+ m_aImpl.GetSharePointsRules( m_aSubstVarMap );
+
+ // Init the predefined/fixed variable to index hash map
+ for ( i = 0; i < PREDEFVAR_COUNT; i++ )
+ {
+ // Store variable name into struct of predefined/fixed variables
+ m_aPreDefVars.m_FixedVarNames[i] = rtl::OUString::createFromAscii( aFixedVarTable[i].pVarName );
+
+ // Create hash map entry
+ m_aPreDefVarMap.insert( VarNameToIndexMap::value_type(
+ m_aPreDefVars.m_FixedVarNames[i], aFixedVarTable[i].nEnumValue ) );
+ }
+
+ // Sort predefined/fixed variable to path length
+ for ( i = 0; i < PREDEFVAR_COUNT; i++ )
+ {
+ if (( i != PREDEFVAR_WORKDIRURL ) && ( i != PREDEFVAR_PATH ))
+ {
+ // Special path variables, don't include into automatic resubstituion search!
+ // $(workdirurl) is not allowed to resubstitute! This variable is the value of path settings entry
+ // and it could be possible that it will be resubstituted by itself!!
+ // Example: WORK_PATH=c:\test, $(workdirurl)=WORK_PATH => WORK_PATH=$(workdirurl) and this cannot be substituted!
+ ReSubstFixedVarOrder aFixedVar;
+ aFixedVar.eVariable = aFixedVarTable[i].nEnumValue;
+ aFixedVar.nVarValueLength = m_aPreDefVars.m_FixedVar[(sal_Int32)aFixedVar.eVariable].getLength();
+ m_aReSubstFixedVarOrder.push_back( aFixedVar );
+ }
+ }
+ m_aReSubstFixedVarOrder.sort();
+
+ // Sort user variables to path length
+ SubstituteVariables::const_iterator pIter;
+ for ( pIter = m_aSubstVarMap.begin(); pIter != m_aSubstVarMap.end(); ++pIter )
+ {
+ ReSubstUserVarOrder aUserOrderVar;
+ rtl::OUStringBuffer aStrBuffer( pIter->second.aSubstVariable.getLength() );
+ aStrBuffer.append( m_aVarStart );
+ aStrBuffer.append( pIter->second.aSubstVariable );
+ aStrBuffer.append( m_aVarEnd );
+ aUserOrderVar.aVarName = aStrBuffer.makeStringAndClear();
+ aUserOrderVar.nVarValueLength = pIter->second.aSubstVariable.getLength();
+ m_aReSubstUserVarOrder.push_back( aUserOrderVar );
+ }
+ m_aReSubstUserVarOrder.sort();
+}
+
+SubstitutePathVariables::~SubstitutePathVariables()
+{
+}
+
+// XStringSubstitution
+rtl::OUString SAL_CALL SubstitutePathVariables::substituteVariables( const ::rtl::OUString& aText, sal_Bool bSubstRequired )
+throw ( NoSuchElementException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::substituteVariables" );
+ ResetableGuard aLock( m_aLock );
+ return impl_substituteVariable( aText, bSubstRequired );
+}
+
+rtl::OUString SAL_CALL SubstitutePathVariables::reSubstituteVariables( const ::rtl::OUString& aText )
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::reSubstituteVariables" );
+ ResetableGuard aLock( m_aLock );
+ return impl_reSubstituteVariables( aText );
+}
+
+rtl::OUString SAL_CALL SubstitutePathVariables::getSubstituteVariableValue( const ::rtl::OUString& aVariable )
+throw ( NoSuchElementException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::getSubstituteVariableValue" );
+ ResetableGuard aLock( m_aLock );
+ return impl_getSubstituteVariableValue( aVariable );
+}
+
+//_________________________________________________________________________________________________________________
+// protected methods
+//_________________________________________________________________________________________________________________
+
+IMPL_LINK( SubstitutePathVariables, implts_ConfigurationNotify, SubstitutePathNotify*, EMPTYARG )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+
+ return 0;
+}
+
+rtl::OUString SubstitutePathVariables::ConvertOSLtoUCBURL( const rtl::OUString& aOSLCompliantURL ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::ConvertOSLtoUCBURL" );
+ String aResult;
+ rtl::OUString aTemp;
+
+ osl::FileBase::getSystemPathFromFileURL( aOSLCompliantURL, aTemp );
+ utl::LocalFileHelper::ConvertPhysicalNameToURL( aTemp, aResult );
+
+ // Not all OSL URL's can be mapped to UCB URL's!
+ if ( aResult.Len() == 0 )
+ return aOSLCompliantURL;
+ else
+ return rtl::OUString( aResult );
+}
+
+rtl::OUString SubstitutePathVariables::GetWorkPath() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::GetWorkPath" );
+ rtl::OUString aWorkPath;
+
+ try
+ {
+ ::comphelper::ConfigurationHelper::readDirectKey(
+ m_xServiceManager,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Paths")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Paths/Work")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("WritePath")),
+ ::comphelper::ConfigurationHelper::E_READONLY) >>= aWorkPath;
+ }
+ catch(RuntimeException &)
+ {
+ }
+
+ // fallback in case config layer does not return an useable work dir value.
+ if (aWorkPath.getLength() < 1)
+ aWorkPath = GetWorkVariableValue();
+
+ return aWorkPath;
+}
+
+rtl::OUString SubstitutePathVariables::GetWorkVariableValue() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::GetWorkVariableValue" );
+ ::rtl::OUString aWorkPath;
+
+ try
+ {
+ ::comphelper::ConfigurationHelper::readDirectKey(
+ m_xServiceManager,
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Paths")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Variables")),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Work")),
+ ::comphelper::ConfigurationHelper::E_READONLY) >>= aWorkPath;
+ }
+ catch(RuntimeException &)
+ {
+ }
+
+ // fallback to $HOME in case platform dependend config layer does not return
+ // an usuable work dir value.
+ if (aWorkPath.getLength() < 1)
+ {
+ osl::Security aSecurity;
+ aSecurity.getHomeDir( aWorkPath );
+ }
+ return ConvertOSLtoUCBURL( aWorkPath );
+}
+
+rtl::OUString SubstitutePathVariables::GetHomeVariableValue() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::GetHomeVariableValue" );
+ osl::Security aSecurity;
+ rtl::OUString aHomePath;
+
+ aSecurity.getHomeDir( aHomePath );
+ return ConvertOSLtoUCBURL( aHomePath );
+}
+
+rtl::OUString SubstitutePathVariables::GetPathVariableValue() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::GetPathVariableValue" );
+ const int PATH_EXTEND_FACTOR = 120;
+
+ rtl::OUString aRetStr;
+ const char* pEnv = getenv( "PATH" );
+
+ if ( pEnv )
+ {
+ rtl::OUString aTmp;
+ rtl::OUString aPathList( pEnv, strlen( pEnv ), gsl_getSystemTextEncoding() );
+ rtl::OUStringBuffer aPathStrBuffer( aPathList.getLength() * PATH_EXTEND_FACTOR / 100 );
+
+ bool bAppendSep = false;
+ sal_Int32 nToken = 0;
+ do
+ {
+ ::rtl::OUString sToken = aPathList.getToken(0, SAL_PATHSEPARATOR, nToken);
+ if (sToken.getLength())
+ {
+ osl::FileBase::getFileURLFromSystemPath( sToken, aTmp );
+ if ( bAppendSep )
+ aPathStrBuffer.appendAscii( ";" ); // Office uses ';' as path separator
+ aPathStrBuffer.append( aTmp );
+ bAppendSep = true;
+ }
+ }
+ while(nToken>=0);
+
+ aRetStr = aPathStrBuffer.makeStringAndClear();
+ }
+
+ return aRetStr;
+}
+
+rtl::OUString SubstitutePathVariables::impl_substituteVariable( const ::rtl::OUString& rText, bool bSubstRequired )
+throw ( NoSuchElementException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::impl_substituteVariable" );
+ // This is maximal recursive depth supported!
+ const sal_Int32 nMaxRecursiveDepth = 8;
+
+ rtl::OUString aWorkText = rText;
+ rtl::OUString aResult;
+
+ // Use vector with strings to detect endless recursions!
+ std::vector< rtl::OUString > aEndlessRecursiveDetector;
+
+ // Search for first occure of "$(...".
+ sal_Int32 nDepth = 0;
+ sal_Int32 bSubstitutionCompleted = sal_False;
+ sal_Int32 nPosition = aWorkText.indexOf( m_aVarStart ); // = first position of "$(" in string
+ sal_Int32 nLength = 0; // = count of letters from "$(" to ")" in string
+ bool bVarNotSubstituted = false;
+
+ // Have we found any variable like "$(...)"?
+ if ( nPosition != STRPOS_NOTFOUND )
+ {
+ // Yes; Get length of found variable.
+ // If no ")" was found - nLength is set to 0 by default! see before.
+ sal_Int32 nEndPosition = aWorkText.indexOf( m_aVarEnd, nPosition );
+ if ( nEndPosition != STRPOS_NOTFOUND )
+ nLength = nEndPosition - nPosition + 1;
+ }
+
+ // Is there something to replace ?
+ bool bWorkRetrieved = false;
+ bool bWorkDirURLRetrieved = false;
+ while ( !bSubstitutionCompleted && nDepth < nMaxRecursiveDepth )
+ {
+ while ( ( nPosition != STRPOS_NOTFOUND ) && ( nLength > 3 ) ) // "$(" ")"
+ {
+ // YES; Get the next variable for replace.
+ sal_Int32 nReplaceLength = 0;
+ rtl::OUString aReplacement;
+ rtl::OUString aSubString = aWorkText.copy( nPosition, nLength );
+ rtl::OUString aSubVarString;
+
+ // Path variables are not case sensitive!
+ aSubVarString = aSubString.toAsciiLowerCase();
+ VarNameToIndexMap::const_iterator pNTOIIter = m_aPreDefVarMap.find( aSubVarString );
+ if ( pNTOIIter != m_aPreDefVarMap.end() )
+ {
+ // Fixed/Predefined variable found
+ PreDefVariable nIndex = (PreDefVariable)pNTOIIter->second;
+
+ // Determine variable value and length from array/table
+ if ( nIndex == PREDEFVAR_WORK && !bWorkRetrieved )
+ {
+ // Transient value, retrieve it again
+ m_aPreDefVars.m_FixedVar[ (PreDefVariable)nIndex ] = GetWorkVariableValue();
+ bWorkRetrieved = true;
+ }
+ else if ( nIndex == PREDEFVAR_WORKDIRURL && !bWorkDirURLRetrieved )
+ {
+ // Transient value, retrieve it again
+ m_aPreDefVars.m_FixedVar[ (PreDefVariable)nIndex ] = GetWorkPath();
+ bWorkDirURLRetrieved = true;
+ }
+
+ // Check preconditions to substitue path variables.
+ // 1. A path variable can only be substituted if it follows a SEARCHPATH_DELIMITER ';'!
+ // 2. It's located exactly at the start of the string being substituted!
+ if (( aFixedVarTable[ int( nIndex ) ].bAbsPath && (( nPosition == 0 ) || (( nPosition > 0 ) && ( aWorkText[nPosition-1] == ';')))) ||
+ ( !aFixedVarTable[ int( nIndex ) ].bAbsPath ))
+ {
+ aReplacement = m_aPreDefVars.m_FixedVar[ (PreDefVariable)nIndex ];
+ nReplaceLength = nLength;
+ }
+ }
+ else
+ {
+ // Extract the variable name and try to find in the user defined variable set
+ rtl::OUString aVarName = aSubString.copy( 2, nLength-3 );
+ SubstituteVariables::const_iterator pIter = m_aSubstVarMap.find( aVarName );
+ if ( pIter != m_aSubstVarMap.end() )
+ {
+ // Found.
+ aReplacement = pIter->second.aSubstValue;
+ nReplaceLength = nLength;
+ }
+ }
+
+ // Have we found something to replace?
+ if ( nReplaceLength > 0 )
+ {
+ // Yes ... then do it.
+ aWorkText = aWorkText.replaceAt( nPosition, nReplaceLength, aReplacement );
+ }
+ else
+ {
+ // Variable not known
+ bVarNotSubstituted = false;
+ nPosition += nLength;
+ }
+
+ // Step after replaced text! If no text was replaced (unknown variable!),
+ // length of aReplacement is 0 ... and we don't step then.
+ nPosition += aReplacement.getLength();
+
+ // We must control index in string before call something at OUString!
+ // The OUString-implementation don't do it for us :-( but the result is not defined otherwise.
+ if ( nPosition + 1 > aWorkText.getLength() )
+ {
+ // Position is out of range. Break loop!
+ nPosition = STRPOS_NOTFOUND;
+ nLength = 0;
+ }
+ else
+ {
+ // Else; Position is valid. Search for next variable to replace.
+ nPosition = aWorkText.indexOf( m_aVarStart, nPosition );
+ // Have we found any variable like "$(...)"?
+ if ( nPosition != STRPOS_NOTFOUND )
+ {
+ // Yes; Get length of found variable. If no ")" was found - nLength must set to 0!
+ nLength = 0;
+ sal_Int32 nEndPosition = aWorkText.indexOf( m_aVarEnd, nPosition );
+ if ( nEndPosition != STRPOS_NOTFOUND )
+ nLength = nEndPosition - nPosition + 1;
+ }
+ }
+ }
+
+ nPosition = aWorkText.indexOf( m_aVarStart );
+ if ( nPosition == -1 )
+ {
+ bSubstitutionCompleted = sal_True;
+ break; // All variables are substituted
+ }
+ else
+ {
+ // Check for recursion
+ const sal_uInt32 nCount = aEndlessRecursiveDetector.size();
+ for ( sal_uInt32 i=0; i < nCount; i++ )
+ {
+ if ( aEndlessRecursiveDetector[i] == aWorkText )
+ {
+ if ( bVarNotSubstituted )
+ break; // Not all variables could be substituted!
+ else
+ {
+ nDepth = nMaxRecursiveDepth;
+ break; // Recursion detected!
+ }
+ }
+ }
+
+ aEndlessRecursiveDetector.push_back( aWorkText );
+
+ // Initialize values for next
+ sal_Int32 nEndPosition = aWorkText.indexOf( m_aVarEnd, nPosition );
+ if ( nEndPosition != STRPOS_NOTFOUND )
+ nLength = nEndPosition - nPosition + 1;
+ bVarNotSubstituted = sal_False;
+ ++nDepth;
+ }
+ }
+
+ // Fill return value with result
+ if ( bSubstitutionCompleted )
+ {
+ // Substitution successfull!
+ aResult = aWorkText;
+ }
+ else
+ {
+ // Substitution not successfull!
+ if ( nDepth == nMaxRecursiveDepth )
+ {
+ // recursion depth reached!
+ if ( bSubstRequired )
+ {
+ rtl::OUString aMsg( RTL_CONSTASCII_USTRINGPARAM( "Endless recursion detected. Cannot substitute variables!" ));
+ throw NoSuchElementException( aMsg, (cppu::OWeakObject *)this );
+ }
+ else
+ aResult = rText;
+ }
+ else
+ {
+ // variable in text but unknwon!
+ if ( bSubstRequired )
+ {
+ rtl::OUString aMsg( RTL_CONSTASCII_USTRINGPARAM( "Unknown variable found!" ));
+ throw NoSuchElementException( aMsg, (cppu::OWeakObject *)this );
+ }
+ else
+ aResult = aWorkText;
+ }
+ }
+
+ return aResult;
+}
+
+rtl::OUString SubstitutePathVariables::impl_reSubstituteVariables( const ::rtl::OUString& rURL )
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::impl_reSubstituteVariables" );
+ rtl::OUString aURL;
+
+ INetURLObject aUrl( rURL );
+ if ( !aUrl.HasError() )
+ aURL = aUrl.GetMainURL( INetURLObject::NO_DECODE );
+ else
+ {
+ // Convert a system path to a UCB compliant URL before resubstitution
+ rtl::OUString aTemp;
+ if ( osl::FileBase::getFileURLFromSystemPath( rURL, aTemp ) == osl::FileBase::E_None )
+ {
+ aTemp = ConvertOSLtoUCBURL( aTemp );
+ if ( aTemp.getLength() )
+ aURL = INetURLObject( aTemp ).GetMainURL( INetURLObject::NO_DECODE );
+ else
+ return rURL;
+ }
+ else
+ {
+ // rURL is not a valid URL nor a osl system path. Give up and return error!
+ return rURL;
+ }
+ }
+
+ // Due to a recursive definition this code must exchange variables with variables!
+ bool bResubstitutionCompleted = false;
+ bool bVariableFound = false;
+
+ // Get transient predefined path variable $(work) value before starting resubstitution
+ m_aPreDefVars.m_FixedVar[ PREDEFVAR_WORK ] = GetWorkVariableValue();
+
+ while ( !bResubstitutionCompleted )
+ {
+ ReSubstFixedVarOrderVector::const_iterator pIterFixed;
+ for ( pIterFixed = m_aReSubstFixedVarOrder.begin(); pIterFixed != m_aReSubstFixedVarOrder.end(); ++pIterFixed )
+ {
+ rtl::OUString aValue = m_aPreDefVars.m_FixedVar[ (sal_Int32)pIterFixed->eVariable ];
+ sal_Int32 nPos = aURL.indexOf( aValue );
+ if ( nPos >= 0 )
+ {
+ bool bMatch = true;
+ if ( pIterFixed->eVariable == PREDEFVAR_LANG ||
+ pIterFixed->eVariable == PREDEFVAR_LANGID ||
+ pIterFixed->eVariable == PREDEFVAR_VLANG )
+ {
+ // Special path variables as they can occur in the middle of a path. Only match if they
+ // describe a whole directory and not only a substring of a directory!
+ const sal_Unicode* pStr = aURL.getStr();
+
+ if ( nPos > 0 )
+ bMatch = ( aURL[ nPos-1 ] == '/' );
+
+ if ( bMatch )
+ {
+ if ( nPos + aValue.getLength() < aURL.getLength() )
+ bMatch = ( pStr[ nPos + aValue.getLength() ] == '/' );
+ }
+ }
+
+ if ( bMatch )
+ {
+ rtl::OUStringBuffer aStrBuffer( aURL.getLength() );
+ aStrBuffer.append( aURL.copy( 0, nPos ) );
+ aStrBuffer.append( m_aPreDefVars.m_FixedVarNames[ (sal_Int32)pIterFixed->eVariable ] ); // Get the variable name for struct var name array!
+ aStrBuffer.append( aURL.copy( nPos + aValue.getLength(), ( aURL.getLength() - ( nPos + aValue.getLength() )) ));
+ aURL = aStrBuffer.makeStringAndClear();
+ bVariableFound = true; // Resubstitution not finished yet!
+ break;
+ }
+ }
+ }
+
+ // This part can be iteratered more than one time as variables can contain variables again!
+ ReSubstUserVarOrderVector::const_iterator pIterUser;
+ for ( pIterUser = m_aReSubstUserVarOrder.begin(); pIterUser != m_aReSubstUserVarOrder.end(); ++pIterUser )
+ {
+ rtl::OUString aVarValue = pIterUser->aVarName;
+ sal_Int32 nPos = aURL.indexOf( aVarValue );
+ if ( nPos >= 0 )
+ {
+ rtl::OUStringBuffer aStrBuffer( aURL.getLength() );
+ aStrBuffer.append( aURL.copy( 0, nPos ) );
+ aStrBuffer.append( m_aVarStart );
+ aStrBuffer.append( aVarValue );
+ aStrBuffer.append( m_aVarEnd );
+ aStrBuffer.append( aURL.copy( nPos + aVarValue.getLength(), ( aURL.getLength() - ( nPos + aVarValue.getLength() )) ));
+ aURL = aStrBuffer.makeStringAndClear();
+ bVariableFound = true; // Resubstitution not finished yet!
+ }
+ }
+
+ if ( !bVariableFound )
+ bResubstitutionCompleted = true;
+ else
+ bVariableFound = sal_False; // Next resubstitution
+ }
+
+ return aURL;
+}
+
+// This method support both request schemes "$("<varname>")" or "<varname>".
+::rtl::OUString SubstitutePathVariables::impl_getSubstituteVariableValue( const ::rtl::OUString& rVariable )
+throw ( NoSuchElementException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::impl_getSubstituteVariableValue" );
+ rtl::OUString aVariable;
+
+ sal_Int32 nPos = rVariable.indexOf( m_aVarStart );
+ if ( nPos == -1 )
+ {
+ // Prepare variable name before hash map access
+ rtl::OUStringBuffer aStrBuffer( rVariable.getLength() + m_aVarStart.getLength() + m_aVarEnd.getLength() );
+ aStrBuffer.append( m_aVarStart );
+ aStrBuffer.append( rVariable );
+ aStrBuffer.append( m_aVarEnd );
+ aVariable = aStrBuffer.makeStringAndClear();
+ }
+
+ VarNameToIndexMap::const_iterator pNTOIIter = m_aPreDefVarMap.find( ( nPos == -1 ) ? aVariable : rVariable );
+
+ // Fixed/Predefined variable
+ if ( pNTOIIter != m_aPreDefVarMap.end() )
+ {
+ PreDefVariable nIndex = (PreDefVariable)pNTOIIter->second;
+ return m_aPreDefVars.m_FixedVar[(sal_Int32)nIndex];
+ }
+ else
+ {
+ // Prepare variable name before hash map access
+ if ( nPos >= 0 )
+ {
+ if ( rVariable.getLength() > 3 )
+ aVariable = rVariable.copy( 2, rVariable.getLength() - 3 );
+ else
+ {
+ rtl::OUString aExceptionText( RTL_CONSTASCII_USTRINGPARAM( "Unknown variable!" ));
+ throw NoSuchElementException();
+ }
+ }
+ else
+ aVariable = rVariable;
+
+ // User defined variable
+ SubstituteVariables::const_iterator pIter = m_aSubstVarMap.find( aVariable );
+ if ( pIter != m_aSubstVarMap.end() )
+ {
+ // found!
+ return pIter->second.aSubstValue;
+ }
+
+ rtl::OUString aExceptionText( RTL_CONSTASCII_USTRINGPARAM( "Unknown variable!" ));
+ throw NoSuchElementException( aExceptionText, (cppu::OWeakObject *)this );
+ }
+}
+
+void SubstitutePathVariables::SetPredefinedPathVariables( PredefinedPathVariables& aPreDefPathVariables )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "SubstitutePathVariables::SetPredefinedPathVariables" );
+ Any aAny;
+ ::rtl::OUString aOfficePath;
+ ::rtl::OUString aUserPath;
+ ::rtl::OUString aTmp;
+ ::rtl::OUString aTmp2;
+ String aResult;
+
+ // Get inspath and userpath from bootstrap mechanism in every case as file URL
+ ::utl::Bootstrap::PathStatus aState;
+ ::rtl::OUString sVal ;
+
+ aState = utl::Bootstrap::locateBaseInstallation( sVal );
+ if( aState==::utl::Bootstrap::PATH_EXISTS ) {
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTPATH ] = ConvertOSLtoUCBURL( sVal );
+ }
+ else {
+ LOG_ERROR( "SubstitutePathVariables::SetPredefinedPathVariables", "Bootstrap code has no value for instpath!");
+ }
+
+ aState = utl::Bootstrap::locateUserData( sVal );
+ //There can be the valid case that there is no user installation. For example, "unopkg sync"
+ //is currently (OOo3.4) run as part of the setup. Then no user installation is required.
+ //Therefore we do not assert here.
+ if( aState == ::utl::Bootstrap::PATH_EXISTS ) {
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERPATH ] = ConvertOSLtoUCBURL( sVal );
+ }
+
+ // Set $(inst), $(instpath), $(insturl)
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTURL ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTPATH ];
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INST ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTPATH ];
+ // New variable of hierachy service (#i32656#)
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_BASEINSTURL ]= aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTPATH ];
+
+ // Set $(user), $(userpath), $(userurl)
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERURL ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERPATH ];
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USER ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERPATH ];
+ // New variable of hierachy service (#i32656#)
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERDATAURL ]= aPreDefPathVariables.m_FixedVar[ PREDEFVAR_USERPATH ];
+
+ // Detect the program directory
+ // Set $(prog), $(progpath), $(progurl)
+ INetURLObject aProgObj(
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_INSTPATH ] );
+ if ( !aProgObj.HasError() && aProgObj.insertName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("program")) ) )
+ {
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PROGPATH ] = aProgObj.GetMainURL(INetURLObject::NO_DECODE);
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PROGURL ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PROGPATH ];
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PROG ] = aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PROGPATH ];
+ }
+
+ // Detect the language type of the current office
+ aPreDefPathVariables.m_eLanguageType = LANGUAGE_ENGLISH_US;
+ rtl::OUString aLocaleStr;
+ if ( utl::ConfigManager::GetConfigManager().GetDirectConfigProperty( utl::ConfigManager::LOCALE ) >>= aLocaleStr )
+ aPreDefPathVariables.m_eLanguageType = MsLangId::convertIsoStringToLanguage( aLocaleStr );
+ // We used to have an else branch here with a LOG_ERROR, but that
+ // always fired in some unit tests when this code was built with
+ // debug=t, so it seems fairly pointless, especially as
+ // aPreDefPathVariables.m_eLanguageType has been initialized to a
+ // default value above anyway.
+
+ // Set $(lang)
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_LANG ] = ConvertOSLtoUCBURL(
+ rtl::OUString::createFromAscii( ResMgr::GetLang( aPreDefPathVariables.m_eLanguageType, 0 ) ));
+
+ // Set $(vlang)
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_VLANG ] = aLocaleStr;
+
+ // Set $(langid)
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_LANGID ] = rtl::OUString::valueOf( (sal_Int32)aPreDefPathVariables.m_eLanguageType );
+
+ // Set the other pre defined path variables
+ // Set $(work)
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_WORK ] = GetWorkVariableValue();
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_HOME ] = GetHomeVariableValue();
+
+ // Set $(workdirurl) this is the value of the path PATH_WORK which doesn't make sense
+ // anymore because the path settings service has this value! It can deliver this value more
+ // quickly than the substitution service!
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_WORKDIRURL ] = GetWorkPath();
+
+ // Set $(path) variable
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_PATH ] = GetPathVariableValue();
+
+ // Set $(temp)
+ osl::FileBase::getTempDirURL( aTmp );
+ aPreDefPathVariables.m_FixedVar[ PREDEFVAR_TEMP ] = ConvertOSLtoUCBURL( aTmp );
+
+ aPreDefPathVariables.m_FixedVar[PREDEFVAR_BRANDBASEURL] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR"));
+ rtl::Bootstrap::expandMacros(
+ aPreDefPathVariables.m_FixedVar[PREDEFVAR_BRANDBASEURL]);
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/tabwindowservice.cxx b/framework/source/services/tabwindowservice.cxx
new file mode 100644
index 000000000000..2677ca60fbfd
--- /dev/null
+++ b/framework/source/services/tabwindowservice.cxx
@@ -0,0 +1,488 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <services/tabwindowservice.hxx>
+#include <classes/fwktabwindow.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <services.h>
+#include <properties.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// css::uno::XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+
+DEFINE_XINTERFACE_6 ( TabWindowService ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::lang::XComponent),
+ DIRECT_INTERFACE(css::awt::XSimpleTabController),
+ DIRECT_INTERFACE(css::beans::XPropertySet ),
+ DIRECT_INTERFACE(css::beans::XPropertySetInfo )
+ )
+
+DEFINE_XTYPEPROVIDER_6 ( TabWindowService ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::lang::XComponent ,
+ css::awt::XSimpleTabController ,
+ css::beans::XPropertySet ,
+ css::beans::XPropertySetInfo
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( TabWindowService ,
+ OWeakObject ,
+ SERVICENAME_TABWINDOWSERVICE ,
+ IMPLEMENTATIONNAME_TABWINDOWSERVICE
+ )
+
+DEFINE_INIT_SERVICE ( TabWindowService,
+ {
+ impl_initializePropInfo();
+ m_aTransactionManager.setWorkingMode( E_WORK );
+ }
+ )
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+TabWindowService::TabWindowService( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
+ // Init baseclasses first
+ // Attention:
+ // Don't change order of initialization!
+ // ThreadHelpBase is a struct with a mutex as member. We can't use a mutex as member, while
+ // we must garant right initialization and a valid value of this! First initialize
+ // baseclasses and then members. And we need the mutex for other baseclasses !!!
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , TransactionBase ( )
+ , PropertySetHelper ( xFactory ,
+ &m_aLock ,
+ &m_aTransactionManager ,
+ sal_False ) // sal_False => dont release shared mutex on calling us!
+ , OWeakObject ( )
+
+ // Init member
+ , m_xFactory ( xFactory )
+ , m_xTabWin ( )
+ , m_pTabWin ( NULL )
+ , m_lTabPageInfos ( )
+ , m_lListener ( m_aLock.getShareableOslMutex())
+ , m_nPageIndexCounter ( 1 )
+ , m_nCurrentPageIndex ( 0 )
+{
+ // Safe impossible cases.
+ // Method not defined for all incoming parameter.
+ LOG_ASSERT( xFactory.is(), "TabWindowService::TabWindowService()\nInvalid parameter detected!\n" )
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+TabWindowService::~TabWindowService()
+{
+ // SAFE->
+ ResetableGuard aGuard(m_aLock);
+
+ if (m_pTabWin)
+ m_pTabWin->RemoveEventListener( LINK( this, TabWindowService, EventListener ) );
+}
+
+//*****************************************************************************************************************
+// XSimpleTabController
+//*****************************************************************************************************************
+::sal_Int32 SAL_CALL TabWindowService::insertTab()
+ throw ( css::uno::RuntimeException )
+{
+ // SAFE ->
+ ResetableGuard aGuard( m_aLock );
+
+ ::sal_Int32 nID = m_nPageIndexCounter++;
+ TTabPageInfo aInfo(nID);
+
+ m_lTabPageInfos[nID] = aInfo;
+
+ return nID;
+}
+
+//*****************************************************************************************************************
+// XSimpleTabController
+//*****************************************************************************************************************
+void SAL_CALL TabWindowService::removeTab(::sal_Int32 nID)
+ throw (css::lang::IndexOutOfBoundsException,
+ css::uno::RuntimeException )
+{
+ // SAFE ->
+ ResetableGuard aGuard(m_aLock);
+
+ // throws suitable IndexOutOfBoundsException .-)
+ TTabPageInfoHash::iterator pIt = impl_getTabPageInfo (nID);
+ m_lTabPageInfos.erase(pIt);
+
+ FwkTabWindow* pTabWin = mem_TabWin ();
+ if (pTabWin)
+ pTabWin->RemovePage(nID);
+}
+
+//*****************************************************************************************************************
+// XSimpleTabController
+//*****************************************************************************************************************
+void SAL_CALL TabWindowService::setTabProps( ::sal_Int32 nID ,
+ const css::uno::Sequence< css::beans::NamedValue >& lProperties)
+ throw (css::lang::IndexOutOfBoundsException,
+ css::uno::RuntimeException )
+{
+ // SAFE ->
+ ResetableGuard aGuard(m_aLock);
+
+ // throws suitable IndexOutOfBoundsException .-)
+ TTabPageInfoHash::iterator pIt = impl_getTabPageInfo (nID);
+ TTabPageInfo& rInfo = pIt->second;
+ rInfo.m_lProperties = lProperties;
+
+ if ( ! rInfo.m_bCreated)
+ {
+ FwkTabWindow* pTabWin = mem_TabWin ();
+ if (pTabWin)
+ {
+ pTabWin->AddTabPage(rInfo.m_nIndex, rInfo.m_lProperties);
+ rInfo.m_bCreated = sal_True;
+ }
+ }
+}
+
+//*****************************************************************************************************************
+// XSimpleTabController
+//*****************************************************************************************************************
+css::uno::Sequence< css::beans::NamedValue > SAL_CALL TabWindowService::getTabProps(::sal_Int32 nID)
+ throw (css::lang::IndexOutOfBoundsException,
+ css::uno::RuntimeException )
+{
+ // SAFE ->
+ ResetableGuard aGuard(m_aLock);
+
+ // throws suitable IndexOutOfBoundsException .-)
+ TTabPageInfoHash::const_iterator pIt = impl_getTabPageInfo (nID);
+ const TTabPageInfo& rInfo = pIt->second;
+
+ return rInfo.m_lProperties;
+}
+
+//*****************************************************************************************************************
+// XSimpleTabController
+//*****************************************************************************************************************
+void SAL_CALL TabWindowService::activateTab(::sal_Int32 nID)
+ throw (css::lang::IndexOutOfBoundsException,
+ css::uno::RuntimeException )
+{
+ // SAFE ->
+ ResetableGuard aGuard(m_aLock);
+
+ // throws suitable IndexOutOfBoundsException .-)
+ impl_checkTabIndex (nID);
+ m_nCurrentPageIndex = nID;
+
+ FwkTabWindow* pTabWin = mem_TabWin ();
+ if (pTabWin)
+ pTabWin->ActivatePage(nID);
+}
+
+//*****************************************************************************************************************
+// XSimpleTabController
+//*****************************************************************************************************************
+::sal_Int32 SAL_CALL TabWindowService::getActiveTabID()
+ throw (css::uno::RuntimeException)
+{
+ // SAFE->
+ ResetableGuard aGuard( m_aLock );
+ return m_nCurrentPageIndex;
+}
+
+//*****************************************************************************************************************
+// XSimpleTabController
+//*****************************************************************************************************************
+void SAL_CALL TabWindowService::addTabListener(const css::uno::Reference< css::awt::XTabListener >& xListener)
+ throw (css::uno::RuntimeException)
+{
+ m_lListener.addInterface(::getCppuType((const css::uno::Reference< css::awt::XTabListener >*)NULL), xListener);
+}
+
+//*****************************************************************************************************************
+// XSimpleTabController
+//*****************************************************************************************************************
+void SAL_CALL TabWindowService::removeTabListener(const css::uno::Reference< css::awt::XTabListener >& xListener)
+ throw (css::uno::RuntimeException)
+{
+ m_lListener.removeInterface(::getCppuType((const css::uno::Reference< css::awt::XTabListener >*)NULL), xListener);
+}
+
+//*****************************************************************************************************************
+// XComponent
+//*****************************************************************************************************************
+void SAL_CALL TabWindowService::dispose()
+ throw (css::uno::RuntimeException)
+{
+ // SAFE->
+ ResetableGuard aGuard(m_aLock);
+
+ css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ css::lang::EventObject aEvent(xThis);
+
+ m_lListener.disposeAndClear (aEvent);
+
+ if (m_pTabWin)
+ m_pTabWin->RemoveEventListener( LINK( this, TabWindowService, EventListener ) );
+
+ m_pTabWin = NULL;
+ m_xTabWin.clear();
+}
+
+//*****************************************************************************************************************
+// XComponent
+//*****************************************************************************************************************
+void SAL_CALL TabWindowService::addEventListener(const css::uno::Reference< css::lang::XEventListener >& xListener)
+ throw (css::uno::RuntimeException)
+{
+ m_lListener.addInterface(::getCppuType((const css::uno::Reference< css::lang::XEventListener >*)NULL), xListener);
+}
+
+//*****************************************************************************************************************
+// XComponent
+//*****************************************************************************************************************
+void SAL_CALL TabWindowService::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener)
+ throw (css::uno::RuntimeException)
+{
+ m_lListener.removeInterface(::getCppuType((const css::uno::Reference< css::lang::XEventListener >*)NULL), xListener);
+}
+
+//*****************************************************************************************************************
+void TabWindowService::impl_initializePropInfo()
+{
+ impl_setPropertyChangeBroadcaster(static_cast< css::awt::XSimpleTabController* >(this));
+
+ impl_addPropertyInfo(
+ css::beans::Property(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Window")),
+ TABWINDOWSERVICE_PROPHANDLE_WINDOW,
+ ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
+ css::beans::PropertyAttribute::TRANSIENT));
+}
+
+//*****************************************************************************************************************
+void SAL_CALL TabWindowService::impl_setPropertyValue(const ::rtl::OUString& /*sProperty*/,
+ sal_Int32 /*nHandle */,
+ const css::uno::Any& /*aValue */)
+
+{
+}
+
+//*****************************************************************************************************************
+css::uno::Any SAL_CALL TabWindowService::impl_getPropertyValue(const ::rtl::OUString& /*sProperty*/,
+ sal_Int32 nHandle )
+{
+ /* There is no need to lock any mutex here. Because we share the
+ solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
+ see ctor of PropertySetHelper for further informations.
+ */
+ css::uno::Any aValue;
+
+ switch (nHandle)
+ {
+ case TABWINDOWSERVICE_PROPHANDLE_WINDOW:
+ {
+ mem_TabWin (); // force "creation on demand" of m_xTabWin :-)
+ aValue <<= m_xTabWin;
+ }
+ break;
+ }
+
+ return aValue;
+}
+
+//*****************************************************************************************************************
+// TabWindowService
+//*****************************************************************************************************************
+IMPL_LINK( TabWindowService, EventListener, VclSimpleEvent*, pEvent )
+{
+
+ if ( !pEvent && !pEvent->ISA(VclWindowEvent))
+ return 0;
+
+ sal_uLong nEventId = pEvent->GetId();
+ VclWindowEvent* pWinEvt = static_cast< VclWindowEvent* >(pEvent);
+
+ css::uno::Reference< css::uno::XInterface > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::lang::EventObject aEvent( xThis );
+
+ if (nEventId == VCLEVENT_OBJECT_DYING)
+ {
+ m_lListener.disposeAndClear (aEvent);
+
+ m_pTabWin->RemoveEventListener( LINK( this, TabWindowService, EventListener ) );
+ m_pTabWin = NULL;
+ m_xTabWin.clear();
+
+ return 0;
+ }
+
+ ::cppu::OInterfaceContainerHelper* pContainer = m_lListener.getContainer(::getCppuType((const css::uno::Reference< css::awt::XTabListener >*) NULL));
+ if ( ! pContainer)
+ return 0;
+
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ css::awt::XTabListener* pListener = (css::awt::XTabListener*)pIterator.next();
+
+ switch (nEventId)
+ {
+ case VCLEVENT_TABPAGE_ACTIVATE :
+ pListener->activated( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
+ break;
+
+ case VCLEVENT_TABPAGE_DEACTIVATE :
+ pListener->deactivated( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
+ break;
+
+ case VCLEVENT_TABPAGE_INSERTED :
+ pListener->inserted( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
+ break;
+
+ case VCLEVENT_TABPAGE_REMOVED :
+ pListener->removed( (sal_Int32)(sal_uLong)pWinEvt->GetData() );
+ break;
+
+ case VCLEVENT_TABPAGE_PAGETEXTCHANGED :
+ case VCLEVENT_TABPAGE_REMOVEDALL :
+ break;
+ }
+ }
+ catch(const css::uno::RuntimeException&)
+ {
+ pIterator.remove();
+ }
+ }
+
+ return 0;
+}
+
+//*****************************************************************************************************************
+// TabWindowService
+//*****************************************************************************************************************
+void TabWindowService::impl_checkTabIndex (::sal_Int32 nID)
+ throw (css::lang::IndexOutOfBoundsException)
+{
+ if (
+ (nID <= 0 ) ||
+ (nID > m_nPageIndexCounter)
+ )
+ {
+ throw css::lang::IndexOutOfBoundsException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tab index out of bounds.")),
+ css::uno::Reference< css::uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY ));
+ }
+}
+
+//*****************************************************************************************************************
+// TabWindowService
+//*****************************************************************************************************************
+TTabPageInfoHash::iterator TabWindowService::impl_getTabPageInfo(::sal_Int32 nID)
+ throw (css::lang::IndexOutOfBoundsException)
+{
+ TTabPageInfoHash::iterator pIt = m_lTabPageInfos.find(nID);
+ if (pIt == m_lTabPageInfos.end ())
+ throw css::lang::IndexOutOfBoundsException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tab index out of bounds.")),
+ css::uno::Reference< css::uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY ));
+ return pIt;
+}
+
+//*****************************************************************************************************************
+// TabWindowService
+//*****************************************************************************************************************
+FwkTabWindow* TabWindowService::mem_TabWin ()
+{
+ FwkTabWindow* pWin = NULL;
+
+ if ( ! m_xTabWin.is ())
+ {
+ Window* pFakeParent = dynamic_cast< Window* >(Application::GetDefaultDevice ());
+
+ m_pTabWin = new FwkTabWindow (pFakeParent);
+ m_xTabWin = VCLUnoHelper::GetInterface (m_pTabWin);
+
+ m_pTabWin->AddEventListener( LINK( this, TabWindowService, EventListener ) );
+ }
+
+ if (m_xTabWin.is ())
+ pWin = m_pTabWin;
+
+ return pWin;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/taskcreatorsrv.cxx b/framework/source/services/taskcreatorsrv.cxx
new file mode 100644
index 000000000000..bacbd8e74ee3
--- /dev/null
+++ b/framework/source/services/taskcreatorsrv.cxx
@@ -0,0 +1,403 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include "services/taskcreatorsrv.hxx"
+
+//_______________________________________________
+// own includes
+#include <helper/persistentwindowstate.hxx>
+#include <helper/tagwindowasmodified.hxx>
+#include <helper/titlebarupdate.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <loadenv/targethelper.hxx>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/WindowDescriptor.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
+
+//_______________________________________________
+// other includes
+#include <svtools/colorcfg.hxx>
+#include <vcl/svapp.hxx>
+
+#include <toolkit/unohlp.hxx>
+#include <vcl/window.hxx>
+
+//_______________________________________________
+// namespaces
+
+namespace framework
+{
+
+//-----------------------------------------------
+const ::rtl::OUString TaskCreatorService::ARGUMENT_PARENTFRAME(RTL_CONSTASCII_USTRINGPARAM("ParentFrame")); // XFrame
+const ::rtl::OUString TaskCreatorService::ARGUMENT_FRAMENAME(RTL_CONSTASCII_USTRINGPARAM("FrameName")); // OUString
+const ::rtl::OUString TaskCreatorService::ARGUMENT_MAKEVISIBLE(RTL_CONSTASCII_USTRINGPARAM("MakeVisible")); // sal_Bool
+const ::rtl::OUString TaskCreatorService::ARGUMENT_CREATETOPWINDOW(RTL_CONSTASCII_USTRINGPARAM("CreateTopWindow")); // sal_Bool
+const ::rtl::OUString TaskCreatorService::ARGUMENT_POSSIZE(RTL_CONSTASCII_USTRINGPARAM("PosSize")); // Rectangle
+const ::rtl::OUString TaskCreatorService::ARGUMENT_CONTAINERWINDOW(RTL_CONSTASCII_USTRINGPARAM("ContainerWindow")); // XWindow
+const ::rtl::OUString TaskCreatorService::ARGUMENT_SUPPORTPERSISTENTWINDOWSTATE(RTL_CONSTASCII_USTRINGPARAM("SupportPersistentWindowState")); // sal_Bool
+const ::rtl::OUString TaskCreatorService::ARGUMENT_ENABLE_TITLEBARUPDATE(RTL_CONSTASCII_USTRINGPARAM("EnableTitleBarUpdate")); // sal_Bool
+
+//-----------------------------------------------
+DEFINE_XINTERFACE_3(TaskCreatorService ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::lang::XTypeProvider ),
+ DIRECT_INTERFACE(css::lang::XServiceInfo ),
+ DIRECT_INTERFACE(css::lang::XSingleServiceFactory))
+
+//-----------------------------------------------
+DEFINE_XTYPEPROVIDER_3(TaskCreatorService ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::lang::XSingleServiceFactory)
+
+//-----------------------------------------------
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(TaskCreatorService ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_TASKCREATOR ,
+ IMPLEMENTATIONNAME_FWK_TASKCREATOR)
+
+//-----------------------------------------------
+DEFINE_INIT_SERVICE(
+ TaskCreatorService,
+ {
+ /*Attention
+ I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
+ to create a new instance of this class by our own supported service factory.
+ see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
+ */
+ }
+ )
+
+//-----------------------------------------------
+TaskCreatorService::TaskCreatorService(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , ::cppu::OWeakObject( )
+ , m_xSMGR (xSMGR )
+{
+}
+
+//-----------------------------------------------
+TaskCreatorService::~TaskCreatorService()
+{
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::uno::XInterface > SAL_CALL TaskCreatorService::createInstance()
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ return createInstanceWithArguments(css::uno::Sequence< css::uno::Any >());
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::uno::XInterface > SAL_CALL TaskCreatorService::createInstanceWithArguments(const css::uno::Sequence< css::uno::Any >& lArguments)
+ throw(css::uno::Exception ,
+ css::uno::RuntimeException)
+{
+ static ::rtl::OUString DEFAULTVAL_FRAMENAME = ::rtl::OUString();
+ static sal_Bool DEFAULTVAL_MAKEVISIBLE = sal_False;
+ static sal_Bool DEFAULTVAL_CREATETOPWINDOW = sal_True;
+ static css::awt::Rectangle DEFAULTVAL_POSSIZE = css::awt::Rectangle(0, 0, 0, 0); // only possize=[0,0,0,0] triggers default handling of vcl !
+ static sal_Bool DEFAULTVAL_SUPPORTPERSSISTENTWINDOWSTATE = sal_False;
+ static sal_Bool DEFAULTVAL_ENABLE_TITLEBARUPDATE = sal_True;
+
+ ::comphelper::SequenceAsHashMap lArgs(lArguments);
+
+ css::uno::Reference< css::frame::XFrame > xParentFrame = lArgs.getUnpackedValueOrDefault(TaskCreatorService::ARGUMENT_PARENTFRAME , css::uno::Reference< css::frame::XFrame >());
+ ::rtl::OUString sFrameName = lArgs.getUnpackedValueOrDefault(TaskCreatorService::ARGUMENT_FRAMENAME , DEFAULTVAL_FRAMENAME );
+ sal_Bool bVisible = lArgs.getUnpackedValueOrDefault(TaskCreatorService::ARGUMENT_MAKEVISIBLE , DEFAULTVAL_MAKEVISIBLE );
+ sal_Bool bCreateTopWindow = lArgs.getUnpackedValueOrDefault(TaskCreatorService::ARGUMENT_CREATETOPWINDOW , DEFAULTVAL_CREATETOPWINDOW );
+ css::awt::Rectangle aPosSize = lArgs.getUnpackedValueOrDefault(TaskCreatorService::ARGUMENT_POSSIZE , DEFAULTVAL_POSSIZE );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow = lArgs.getUnpackedValueOrDefault(TaskCreatorService::ARGUMENT_CONTAINERWINDOW , css::uno::Reference< css::awt::XWindow >() );
+ sal_Bool bSupportPersistentWindowState = lArgs.getUnpackedValueOrDefault(TaskCreatorService::ARGUMENT_SUPPORTPERSISTENTWINDOWSTATE , DEFAULTVAL_SUPPORTPERSSISTENTWINDOWSTATE );
+ sal_Bool bEnableTitleBarUpdate = lArgs.getUnpackedValueOrDefault(TaskCreatorService::ARGUMENT_ENABLE_TITLEBARUPDATE , DEFAULTVAL_ENABLE_TITLEBARUPDATE );
+
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ // We use FrameName property to set it as API name of the new created frame later.
+ // But those frame names must be different from the set of special target names as e.g. _blank, _self etcpp !
+ ::rtl::OUString sRightName = impl_filterNames(sFrameName);
+
+ // if no external frame window was given ... create a new one.
+ if ( ! xContainerWindow.is())
+ {
+ css::uno::Reference< css::awt::XWindow > xParentWindow;
+ if (xParentFrame.is())
+ xParentWindow = xParentFrame->getContainerWindow();
+
+ // Parent has no own window ...
+ // So we have to create a top level window always !
+ if ( ! xParentWindow.is())
+ bCreateTopWindow = sal_True;
+
+ xContainerWindow = implts_createContainerWindow(xParentWindow, aPosSize, bCreateTopWindow);
+ }
+
+ // #i53630#
+ // Mark all document windows as "special ones", so VCL can bind
+ // special features to it. Because VCL doesnt know anything about documents ...
+ // Note: Doing so it's no longer supported, that e.g. our wizards can use findFrame(_blank)
+ // to create it's previes frames. They must do it manually by using WindowDescriptor+Toolkit!
+ css::uno::Reference< css::frame::XDesktop > xDesktop(xParentFrame, css::uno::UNO_QUERY);
+ ::sal_Bool bTopLevelDocumentWindow = (
+ (sRightName.getLength () < 1) &&
+ (
+ (! xParentFrame.is() ) ||
+ ( xDesktop.is() )
+ )
+ );
+ if (bTopLevelDocumentWindow)
+ implts_applyDocStyleToWindow(xContainerWindow);
+ //------------------->
+
+ // create the new frame
+ css::uno::Reference< css::frame::XFrame > xFrame = implts_createFrame(xParentFrame, xContainerWindow, sRightName);
+
+ // special freature:
+ // A special listener will restore pos/size states in case
+ // a component was loaded into the frame first time.
+ if (bSupportPersistentWindowState)
+ implts_establishWindowStateListener(xFrame);
+
+ // special feature: On Mac we need tagging the window in case
+ // the underlying model was modified.
+ // VCL will ignore our calls in case different platform then Mac
+ // is used ...
+ if (bTopLevelDocumentWindow)
+ implts_establishDocModifyListener (xFrame);
+
+ // special freature:
+ // A special listener will update title bar (text and icon)
+ // if component of frame will be changed.
+ if (bEnableTitleBarUpdate)
+ implts_establishTitleBarUpdate(xFrame);
+
+ // Make it visible directly here ...
+ // if its required from outside.
+ if (bVisible)
+ xContainerWindow->setVisible(bVisible);
+
+ return css::uno::Reference< css::uno::XInterface >(xFrame, css::uno::UNO_QUERY_THROW);
+}
+
+//-----------------------------------------------
+void TaskCreatorService::implts_applyDocStyleToWindow(const css::uno::Reference< css::awt::XWindow >& xWindow) const
+{
+ // SYNCHRONIZED ->
+ SolarMutexGuard aSolarGuard;
+ Window* pVCLWindow = VCLUnoHelper::GetWindow(xWindow);
+ if (pVCLWindow)
+ pVCLWindow->SetExtendedStyle(WB_EXT_DOCUMENT);
+ // <- SYNCHRONIZED
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::awt::XWindow > TaskCreatorService::implts_createContainerWindow( const css::uno::Reference< css::awt::XWindow >& xParentWindow ,
+ const css::awt::Rectangle& aPosSize ,
+ sal_Bool bTopWindow )
+{
+ // SAFE ->
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE
+
+ // get toolkit to create task container window
+ css::uno::Reference< css::awt::XToolkit > xToolkit( xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY_THROW);
+
+ // Check if child frames can be created realy. We need at least a valid window at the parent frame ...
+ css::uno::Reference< css::awt::XWindowPeer > xParentWindowPeer;
+ if ( ! bTopWindow)
+ {
+ if ( ! xParentWindow.is())
+ bTopWindow = sal_False;
+ else
+ xParentWindowPeer = css::uno::Reference< css::awt::XWindowPeer >(xParentWindow, css::uno::UNO_QUERY_THROW);
+ }
+
+ // describe window properties.
+ css::awt::WindowDescriptor aDescriptor;
+ if (bTopWindow)
+ {
+ aDescriptor.Type = css::awt::WindowClass_TOP ;
+ aDescriptor.WindowServiceName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("window"));
+ aDescriptor.ParentIndex = -1 ;
+ aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >() ;
+ aDescriptor.Bounds = aPosSize ;
+ aDescriptor.WindowAttributes = css::awt::WindowAttribute::BORDER |
+ css::awt::WindowAttribute::MOVEABLE |
+ css::awt::WindowAttribute::SIZEABLE |
+ css::awt::WindowAttribute::CLOSEABLE |
+ css::awt::VclWindowPeerAttribute::CLIPCHILDREN ;
+ }
+ else
+ {
+ aDescriptor.Type = css::awt::WindowClass_TOP ;
+ aDescriptor.WindowServiceName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("dockingwindow"));
+ aDescriptor.ParentIndex = 1 ;
+ aDescriptor.Parent = xParentWindowPeer ;
+ aDescriptor.Bounds = aPosSize ;
+ aDescriptor.WindowAttributes = css::awt::VclWindowPeerAttribute::CLIPCHILDREN ;
+ }
+
+ // create a new blank container window and get access to parent container to append new created task.
+ css::uno::Reference< css::awt::XWindowPeer > xPeer = xToolkit->createWindow( aDescriptor );
+ css::uno::Reference< css::awt::XWindow > xWindow ( xPeer, css::uno::UNO_QUERY );
+ if ( ! xWindow.is())
+ throw css::uno::Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TaskCreator service was not able to create suitable frame window.")),
+ static_cast< ::cppu::OWeakObject* >(this));
+ if (bTopWindow)
+ xPeer->setBackground(::svtools::ColorConfig().GetColorValue(::svtools::APPBACKGROUND).nColor);
+ else
+ xPeer->setBackground(0xffffffff);
+
+ return xWindow;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::frame::XFrame > TaskCreatorService::implts_createFrame( const css::uno::Reference< css::frame::XFrame >& xParentFrame ,
+ const css::uno::Reference< css::awt::XWindow >& xContainerWindow,
+ const ::rtl::OUString& sName )
+{
+ // SAFE ->
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE
+
+ // create new frame.
+ css::uno::Reference< css::frame::XFrame > xNewFrame( xSMGR->createInstance( SERVICENAME_FRAME ), css::uno::UNO_QUERY_THROW );
+
+ // Set window on frame.
+ // Do it before calling any other interface methods ...
+ // The new created frame must be initialized before you can do anything else there.
+ xNewFrame->initialize( xContainerWindow );
+
+ // Put frame to the frame tree.
+ // Note: The property creator/parent will be set on the new putted frame automaticly ... by the parent container.
+ if (xParentFrame.is())
+ {
+ css::uno::Reference< css::frame::XFramesSupplier > xSupplier (xParentFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::frame::XFrames > xContainer = xSupplier->getFrames();
+ xContainer->append( xNewFrame );
+ }
+
+ // Set it's API name (if there is one from outside)
+ if (sName.getLength())
+ xNewFrame->setName( sName );
+
+ return xNewFrame;
+}
+
+//-----------------------------------------------
+void TaskCreatorService::implts_establishWindowStateListener( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ // SAFE ->
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE
+
+ // Special feature: It's allowed for frames using a top level window only!
+ // We must create a special listener service and couple it with the new created task frame.
+ // He will restore or save the window state of it ...
+ // See used classes for further informations too.
+ PersistentWindowState* pPersistentStateHandler = new PersistentWindowState(xSMGR);
+ css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pPersistentStateHandler), css::uno::UNO_QUERY_THROW);
+
+ css::uno::Sequence< css::uno::Any > lInitData(1);
+ lInitData[0] <<= xFrame;
+ xInit->initialize(lInitData);
+}
+
+//-----------------------------------------------
+void TaskCreatorService::implts_establishDocModifyListener( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ // SAFE ->
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE
+
+ // Special feature: It's allowed for frames using a top level window only!
+ // We must create a special listener service and couple it with the new created task frame.
+ // It will tag the window as modified if the underlying model was modified ...
+ TagWindowAsModified* pTag = new TagWindowAsModified(xSMGR);
+ css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pTag), css::uno::UNO_QUERY_THROW);
+
+ css::uno::Sequence< css::uno::Any > lInitData(1);
+ lInitData[0] <<= xFrame;
+ xInit->initialize(lInitData);
+}
+
+//-----------------------------------------------
+void TaskCreatorService::implts_establishTitleBarUpdate( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ // SAFE ->
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE
+
+ TitleBarUpdate* pHelper = new TitleBarUpdate (xSMGR);
+ css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW);
+
+ css::uno::Sequence< css::uno::Any > lInitData(1);
+ lInitData[0] <<= xFrame;
+ xInit->initialize(lInitData);
+}
+
+//-----------------------------------------------
+::rtl::OUString TaskCreatorService::impl_filterNames( const ::rtl::OUString& sName )
+{
+ ::rtl::OUString sFiltered;
+ if (TargetHelper::isValidNameForFrame(sName))
+ sFiltered = sName;
+ return sFiltered;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/uriabbreviation.cxx b/framework/source/services/uriabbreviation.cxx
new file mode 100644
index 000000000000..31bf228b0c8e
--- /dev/null
+++ b/framework/source/services/uriabbreviation.cxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "services/uriabbreviation.hxx"
+#include "services.h"
+
+#include "sal/config.h"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implementationentry.hxx"
+
+#include "tools/urlobj.hxx"
+
+// component helper namespace
+namespace css = ::com::sun::star;
+
+// framework namespace
+namespace framework
+{
+
+namespace css = ::com::sun::star;
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_MULTISERVICE_2 ( UriAbbreviation ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_STRINGABBREVIATION ,
+ IMPLEMENTATIONNAME_URIABBREVIATION
+ )
+
+DEFINE_INIT_SERVICE ( UriAbbreviation,
+ {
+ }
+ )
+
+UriAbbreviation::UriAbbreviation(css::uno::Reference< css::uno::XComponentContext > const & context) :
+ m_xContext(context)
+{
+}
+
+// ::com::sun::star::util::XStringAbbreviation:
+::rtl::OUString SAL_CALL UriAbbreviation::abbreviateString(const css::uno::Reference< css::util::XStringWidth > & xStringWidth, ::sal_Int32 nWidth, const ::rtl::OUString & aString) throw (css::uno::RuntimeException)
+{
+ ::rtl::OUString aResult( aString );
+ if ( xStringWidth.is() )
+ {
+ // Use INetURLObject to abbreviate URLs
+ INetURLObject aURL( aString );
+ aResult = aURL.getAbbreviated( xStringWidth, nWidth, INetURLObject::DECODE_UNAMBIGUOUS );
+ }
+
+ return aResult;
+}
+
+} // namespace framework
+
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/services/urltransformer.cxx b/framework/source/services/urltransformer.cxx
new file mode 100644
index 000000000000..01e52f0f30cd
--- /dev/null
+++ b/framework/source/services/urltransformer.cxx
@@ -0,0 +1,374 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <services/urltransformer.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <macros/debug.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+using namespace ::osl ;
+using namespace ::cppu ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star::lang ;
+using namespace ::com::sun::star::util ;
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+URLTransformer::URLTransformer( const Reference< XMultiServiceFactory >& /*xFactory*/ )
+{
+ // Safe impossible cases.
+ // Method not defined for all incoming parameter.
+ //LOG_ASSERT( xFactory.is(), "URLTransformer::URLTransformer()\nInvalid parameter detected!\n" )
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+URLTransformer::~URLTransformer()
+{
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( URLTransformer ,
+ OWeakObject ,
+ SERVICENAME_URLTRANSFORMER ,
+ IMPLEMENTATIONNAME_URLTRANSFORMER
+ )
+
+DEFINE_INIT_SERVICE ( URLTransformer,
+ {
+ }
+ )
+
+namespace
+{
+ void lcl_ParserHelper(INetURLObject& _rParser,URL& _rURL,bool _bUseIntern)
+ {
+ // Get all information about this URL.
+ _rURL.Protocol = INetURLObject::GetScheme( _rParser.GetProtocol() );
+ _rURL.User = _rParser.GetUser ( INetURLObject::DECODE_WITH_CHARSET );
+ _rURL.Password = _rParser.GetPass ( INetURLObject::DECODE_WITH_CHARSET );
+ _rURL.Server = _rParser.GetHost ( INetURLObject::DECODE_WITH_CHARSET );
+ _rURL.Port = (sal_Int16)_rParser.GetPort();
+
+ sal_Int32 nCount = _rParser.getSegmentCount( false );
+ if ( nCount > 0 )
+ {
+ // Don't add last segment as it is the name!
+ --nCount;
+
+ rtl::OUStringBuffer aPath;
+ for ( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ aPath.append( sal_Unicode( '/' ));
+ aPath.append( _rParser.getName( nIndex, false, INetURLObject::NO_DECODE ));
+ }
+
+ if ( nCount > 0 )
+ aPath.append( sal_Unicode( '/' )); // final slash!
+
+ _rURL.Path = aPath.makeStringAndClear();
+ _rURL.Name = _rParser.getName( INetURLObject::LAST_SEGMENT, false, INetURLObject::NO_DECODE );
+ }
+ else
+ {
+ _rURL.Path = _rParser.GetURLPath( INetURLObject::NO_DECODE );
+ _rURL.Name = _rParser.GetName ( );
+ }
+
+ _rURL.Arguments = _rParser.GetParam ( INetURLObject::NO_DECODE );
+ _rURL.Mark = _rParser.GetMark ( INetURLObject::DECODE_WITH_CHARSET );
+
+ // INetURLObject supports only an intelligent method of parsing URL's. So write
+ // back Complete to have a valid encoded URL in all cases!
+ _rURL.Complete = _rParser.GetMainURL( INetURLObject::NO_DECODE );
+ if ( _bUseIntern )
+ _rURL.Complete = _rURL.Complete.intern();
+
+ _rParser.SetMark ( ::rtl::OUString() );
+ _rParser.SetParam( ::rtl::OUString() );
+
+ _rURL.Main = _rParser.GetMainURL( INetURLObject::NO_DECODE );
+ }
+}
+//*****************************************************************************************************************
+// XURLTransformer
+//*****************************************************************************************************************
+sal_Bool SAL_CALL URLTransformer::parseStrict( URL& aURL ) throw( RuntimeException )
+{
+ // Safe impossible cases.
+ if (( &aURL == NULL ) ||
+ ( aURL.Complete.getLength() < 1 ) )
+ {
+ return sal_False;
+ }
+ // Try to extract the protocol
+ sal_Int32 nURLIndex = aURL.Complete.indexOf( sal_Unicode( ':' ));
+ ::rtl::OUString aProtocol;
+ if ( nURLIndex > 1 )
+ {
+ aProtocol = aURL.Complete.copy( 0, nURLIndex+1 );
+
+ // If INetURLObject knows this protocol let it parse
+ if ( INetURLObject::CompareProtocolScheme( aProtocol ) != INET_PROT_NOT_VALID )
+ {
+ // Initialize parser with given URL.
+ INetURLObject aParser( aURL.Complete );
+
+ // Get all information about this URL.
+ INetProtocol eINetProt = aParser.GetProtocol();
+ if ( eINetProt == INET_PROT_NOT_VALID )
+ {
+ return sal_False;
+ }
+ else if ( !aParser.HasError() )
+ {
+ lcl_ParserHelper(aParser,aURL,false);
+ // Return "URL is parsed".
+ return sal_True;
+ }
+ }
+ else
+ {
+ // Minmal support for unknown protocols. This is mandatory to support the "Protocol Handlers" implemented
+ // in framework!
+ aURL.Protocol = aProtocol;
+ aURL.Main = aURL.Complete;
+ aURL.Path = aURL.Complete.copy( nURLIndex+1 );;
+
+ // Return "URL is parsed".
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+//*****************************************************************************************************************
+// XURLTransformer
+//*****************************************************************************************************************
+sal_Bool SAL_CALL URLTransformer::parseSmart( URL& aURL ,
+ const ::rtl::OUString& sSmartProtocol ) throw( RuntimeException )
+{
+ // Safe impossible cases.
+ if (( &aURL == NULL ) ||
+ ( aURL.Complete.getLength() < 1 ) )
+ {
+ return sal_False;
+ }
+
+ // Initialize parser with given URL.
+ INetURLObject aParser;
+
+ aParser.SetSmartProtocol( INetURLObject::CompareProtocolScheme( sSmartProtocol ));
+ bool bOk = aParser.SetSmartURL( aURL.Complete );
+ if ( bOk )
+ {
+ lcl_ParserHelper(aParser,aURL,true);
+ // Return "URL is parsed".
+ return sal_True;
+ }
+ else
+ {
+ // Minmal support for unknown protocols. This is mandatory to support the "Protocol Handlers" implemented
+ // in framework!
+ if ( INetURLObject::CompareProtocolScheme( sSmartProtocol ) == INET_PROT_NOT_VALID )
+ {
+ // Try to extract the protocol
+ sal_Int32 nIndex = aURL.Complete.indexOf( sal_Unicode( ':' ));
+ ::rtl::OUString aProtocol;
+ if ( nIndex > 1 )
+ {
+ aProtocol = aURL.Complete.copy( 0, nIndex+1 );
+
+ // If INetURLObject knows this protocol something is wrong as detected before =>
+ // give up and return false!
+ if ( INetURLObject::CompareProtocolScheme( aProtocol ) != INET_PROT_NOT_VALID )
+ return sal_False;
+ else
+ aURL.Protocol = aProtocol;
+ }
+ else
+ return sal_False;
+
+ aURL.Main = aURL.Complete;
+ aURL.Path = aURL.Complete.copy( nIndex+1 );
+ return sal_True;
+ }
+ else
+ return sal_False;
+ }
+}
+
+//*****************************************************************************************************************
+// XURLTransformer
+//*****************************************************************************************************************
+sal_Bool SAL_CALL URLTransformer::assemble( URL& aURL ) throw( RuntimeException )
+{
+ // Safe impossible cases.
+ if ( &aURL == NULL )
+ return sal_False ;
+
+ // Initialize parser.
+ INetURLObject aParser;
+
+ if ( INetURLObject::CompareProtocolScheme( aURL.Protocol ) != INET_PROT_NOT_VALID )
+ {
+ ::rtl::OUStringBuffer aCompletePath( aURL.Path );
+
+ // Concat the name if it is provided, just support a final slash
+ if ( aURL.Name.getLength() > 0 )
+ {
+ sal_Int32 nIndex = aURL.Path.lastIndexOf( sal_Unicode('/') );
+ if ( nIndex == ( aURL.Path.getLength() -1 ))
+ aCompletePath.append( aURL.Name );
+ else
+ {
+ aCompletePath.append( sal_Unicode( '/' ) );
+ aCompletePath.append( aURL.Name );
+ }
+ }
+
+ bool bResult = aParser.ConcatData(
+ INetURLObject::CompareProtocolScheme( aURL.Protocol ) ,
+ aURL.User ,
+ aURL.Password ,
+ aURL.Server ,
+ aURL.Port ,
+ aCompletePath.makeStringAndClear() );
+
+ if ( !bResult )
+ return sal_False;
+
+ // First parse URL WITHOUT ...
+ aURL.Main = aParser.GetMainURL( INetURLObject::NO_DECODE );
+ // ...and then WITH parameter and mark.
+ aParser.SetParam( aURL.Arguments);
+ aParser.SetMark ( aURL.Mark, INetURLObject::ENCODE_ALL );
+ aURL.Complete = aParser.GetMainURL( INetURLObject::NO_DECODE );
+
+ // Return "URL is assembled".
+ return sal_True;
+ }
+ else if ( aURL.Protocol.getLength() > 0 )
+ {
+ // Minimal support for unknown protocols
+ ::rtl::OUStringBuffer aBuffer( aURL.Protocol );
+ aBuffer.append( aURL.Path );
+ aURL.Complete = aBuffer.makeStringAndClear();
+ aURL.Main = aURL.Complete;
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//*****************************************************************************************************************
+// XURLTransformer
+//*****************************************************************************************************************
+::rtl::OUString SAL_CALL URLTransformer::getPresentation( const URL& aURL ,
+ sal_Bool bWithPassword ) throw( RuntimeException )
+{
+ // Safe impossible cases.
+ if (( &aURL == NULL ) ||
+ ( aURL.Complete.getLength() < 1 ) ||
+ (( bWithPassword != sal_True ) &&
+ ( bWithPassword != sal_False ) ) )
+ {
+ return ::rtl::OUString();
+ }
+
+ // Check given URL
+ URL aTestURL = aURL;
+ sal_Bool bParseResult = parseSmart( aTestURL, aTestURL.Protocol );
+ if ( bParseResult )
+ {
+ if ( !bWithPassword && aTestURL.Password.getLength() > 0 )
+ {
+ // Exchange password text with other placeholder string
+ aTestURL.Password = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<******>"));
+ assemble( aTestURL );
+ }
+
+ // Convert internal URLs to "praesentation"-URLs!
+ rtl::OUString sPraesentationURL;
+ INetURLObject::translateToExternal( aTestURL.Complete, sPraesentationURL, INetURLObject::DECODE_UNAMBIGUOUS );
+
+ return sPraesentationURL;
+ }
+ else
+ return ::rtl::OUString();
+}
+
+//_________________________________________________________________________________________________________________
+// debug methods
+//_________________________________________________________________________________________________________________
+
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/tabwin/tabwindow.cxx b/framework/source/tabwin/tabwindow.cxx
new file mode 100644
index 000000000000..143faff001d6
--- /dev/null
+++ b/framework/source/tabwin/tabwindow.cxx
@@ -0,0 +1,976 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <tabwin/tabwindow.hxx>
+#include <properties.h>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/WindowDescriptor.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/wrkwin.hxx>
+#include <toolkit/unohlp.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using ::rtl::OUString;
+using namespace com::sun::star;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_11 ( TabWindow ,
+ ::cppu::OWeakObject ,
+ DIRECT_INTERFACE( css::lang::XTypeProvider ),
+ DIRECT_INTERFACE( css::lang::XServiceInfo ),
+ DIRECT_INTERFACE( css::lang::XInitialization ),
+ DIRECT_INTERFACE( css::lang::XComponent ),
+ DIRECT_INTERFACE( css::awt::XWindowListener ),
+ DIRECT_INTERFACE( css::awt::XTopWindowListener ),
+ DIRECT_INTERFACE( css::awt::XSimpleTabController ),
+ DERIVED_INTERFACE( css::lang::XEventListener, css::awt::XWindowListener ),
+ DIRECT_INTERFACE( css::beans::XMultiPropertySet ),
+ DIRECT_INTERFACE( css::beans::XFastPropertySet ),
+ DIRECT_INTERFACE( css::beans::XPropertySet )
+ )
+
+DEFINE_XTYPEPROVIDER_11 ( TabWindow ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::lang::XInitialization ,
+ css::lang::XComponent ,
+ css::awt::XWindowListener ,
+ css::awt::XTopWindowListener ,
+ css::awt::XSimpleTabController ,
+ css::lang::XEventListener ,
+ css::beans::XMultiPropertySet ,
+ css::beans::XFastPropertySet ,
+ css::beans::XPropertySet
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( TabWindow ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_TABWINDOW ,
+ IMPLEMENTATIONNAME_TABWINDOW
+ )
+
+DEFINE_INIT_SERVICE ( TabWindow, {} )
+
+TabWindow::TabWindow( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase( &Application::GetSolarMutex() )
+ , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
+ , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
+ , m_bInitialized( sal_False )
+ , m_bDisposed( sal_False )
+ , m_nNextTabID( 1 )
+ , m_aTitlePropName( RTL_CONSTASCII_USTRINGPARAM( "Title" ))
+ , m_aPosPropName( RTL_CONSTASCII_USTRINGPARAM( "Position" ))
+ , m_xServiceManager( xServiceManager )
+ , m_aListenerContainer( m_aLock.getShareableOslMutex() )
+{
+}
+
+TabWindow::~TabWindow()
+{
+}
+
+//---------------------------------------------------------------------------------------------------------
+// Helper
+//---------------------------------------------------------------------------------------------------------
+
+void TabWindow::implts_LayoutWindows() const
+{
+ const sal_Int32 nTabControlHeight = 30;
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+ css::uno::Reference< css::awt::XDevice > xDevice( m_xTopWindow, css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XWindow > xWindow( m_xTopWindow, css::uno::UNO_QUERY );
+ css::uno::Reference< css::awt::XWindow > xTabControlWindow( m_xTabControlWindow );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow );
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ // Convert relativ size to output size.
+ if ( xWindow.is() && xDevice.is() )
+ {
+ css::awt::Rectangle aRectangle = xWindow->getPosSize();
+ css::awt::DeviceInfo aInfo = xDevice->getInfo();
+ css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
+ aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
+
+ css::awt::Size aContainerWindowSize;
+ css::awt::Size aTabControlSize;
+
+ aContainerWindowSize.Width = aSize.Width;
+ aTabControlSize.Width = aSize.Width;
+
+ aContainerWindowSize.Height = std::max( sal_Int32( 0 ), aSize.Height - nTabControlHeight );
+ aTabControlSize.Height = nTabControlHeight;
+
+ xContainerWindow->setPosSize( 0, 0,
+ aContainerWindowSize.Width, aContainerWindowSize.Height,
+ css::awt::PosSize::POSSIZE );
+ xTabControlWindow->setPosSize( 0, std::max( nTabControlHeight, sal_Int32( aSize.Height - nTabControlHeight)),
+ aTabControlSize.Width, aTabControlSize.Height,
+ css::awt::PosSize::POSSIZE );
+ }
+}
+
+TabControl* TabWindow::impl_GetTabControl( const css::uno::Reference< css::awt::XWindow >& rTabControlWindow ) const
+{
+ Window* pWindow = VCLUnoHelper::GetWindow( rTabControlWindow );
+ if ( pWindow )
+ return (TabControl *)pWindow;
+ else
+ return NULL;
+}
+
+void TabWindow::impl_SetTitle( const ::rtl::OUString& rTitle )
+{
+ if ( m_xTopWindow.is() )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow(
+ css::uno::Reference< css::awt::XWindow >(
+ m_xTopWindow, css::uno::UNO_QUERY ));
+ if ( pWindow )
+ pWindow->SetText( rTitle );
+ }
+}
+
+void TabWindow::implts_SendNotification( Notification eNotify, sal_Int32 ID ) const
+{
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer(
+ ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >*) NULL ) );
+ if (pContainer!=NULL)
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ switch ( eNotify )
+ {
+ case NOTIFY_INSERTED:
+ ((css::awt::XTabListener*)pIterator.next())->inserted( ID );
+ break;
+ case NOTIFY_REMOVED:
+ ((css::awt::XTabListener*)pIterator.next())->removed( ID );
+ break;
+ case NOTIFY_ACTIVATED:
+ ((css::awt::XTabListener*)pIterator.next())->activated( ID );
+ break;
+ case NOTIFY_DEACTIVATED:
+ ((css::awt::XTabListener*)pIterator.next())->deactivated( ID );
+ break;
+ default:
+ break;
+ }
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+}
+
+void TabWindow::implts_SendNotification( Notification eNotify, sal_Int32 ID, const css::uno::Sequence< css::beans::NamedValue >& rSeq ) const
+{
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer(
+ ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >*) NULL ) );
+ if (pContainer!=NULL)
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
+ while (pIterator.hasMoreElements())
+ {
+ try
+ {
+ switch ( eNotify )
+ {
+ case NOTIFY_CHANGED:
+ ((css::awt::XTabListener*)pIterator.next())->changed( ID, rSeq );
+ break;
+ default:
+ break;
+ }
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------
+// Links
+//---------------------------------------------------------------------------------------------------------
+
+IMPL_LINK( TabWindow, Activate, TabControl*, pTabControl )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+
+ sal_Int32 nPageId = pTabControl->GetCurPageId();
+
+ rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( nPageId ));
+ impl_SetTitle( aTitle );
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ implts_SendNotification( NOTIFY_ACTIVATED, nPageId );
+
+ return 1;
+}
+
+IMPL_LINK( TabWindow, Deactivate, TabControl*, pTabControl )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+ sal_Int32 nPageId = pTabControl->GetCurPageId();
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ implts_SendNotification( NOTIFY_DEACTIVATED, nPageId );
+
+ return 1;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XInitilization
+//---------------------------------------------------------------------------------------------------------
+
+void SAL_CALL TabWindow::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
+throw (css::uno::Exception, css::uno::RuntimeException)
+{
+ const rtl::OUString aTopWindowArgName( RTL_CONSTASCII_USTRINGPARAM( "TopWindow" ));
+ const rtl::OUString aSizeArgName( RTL_CONSTASCII_USTRINGPARAM( "Size" ));
+
+ css::awt::Size aDefaultSize( 500, 500 );
+ css::awt::Size aSize( aDefaultSize );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+ sal_Bool bInitalized( m_bInitialized );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xServiceManager );
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ if ( !bInitalized )
+ {
+ css::beans::PropertyValue aPropValue;
+ css::uno::Reference< css::awt::XTopWindow > xTopWindow;
+ css::uno::Reference< css::awt::XToolkit > xToolkit;
+ css::awt::WindowDescriptor aDescriptor;
+
+ if ( xSMGR.is() )
+ {
+ try
+ {
+ xToolkit = css::uno::Reference< css::awt::XToolkit >(
+ xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
+ }
+ catch ( css::uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+ }
+
+ for ( int i = 0; i < aArguments.getLength(); i++ )
+ {
+ if ( aArguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name == aTopWindowArgName )
+ aPropValue.Value >>= xTopWindow;
+ else if ( aPropValue.Name == aSizeArgName )
+ {
+ aPropValue.Value >>= aSize;
+ if ( aSize.Width <= 0 )
+ aSize.Width = aDefaultSize.Width;
+ if ( aSize.Height <= 0 )
+ aSize.Height = aDefaultSize.Height;
+ }
+ }
+ }
+
+ if ( xToolkit.is() )
+ {
+ if ( !xTopWindow.is() )
+ {
+ // describe top window properties.
+ aDescriptor.Type = css::awt::WindowClass_TOP;
+ aDescriptor.ParentIndex = -1;
+ aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >();
+ aDescriptor.Bounds = css::awt::Rectangle( 0, 0, aSize.Width, aSize.Height );
+ aDescriptor.WindowAttributes = 0;
+
+ try
+ {
+ xTopWindow = css::uno::Reference< css::awt::XTopWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
+ }
+ catch ( css::uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+ }
+
+ if ( xTopWindow.is() )
+ {
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ aLock.lock();
+ m_bInitialized = sal_True;
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ css::uno::Reference< css::awt::XWindow > xWindow( xTopWindow, css::uno::UNO_QUERY );
+ xWindow->addWindowListener( css::uno::Reference< css::awt::XWindowListener >(
+ static_cast< ::cppu::OWeakObject* >( this ), css::uno::UNO_QUERY_THROW ));
+
+ xTopWindow->addTopWindowListener( css::uno::Reference< css::awt::XTopWindowListener >(
+ static_cast< ::cppu::OWeakObject* >( this ), css::uno::UNO_QUERY_THROW ));
+
+ css::uno::Reference< css::awt::XWindow > xContainerWindow;
+ css::uno::Reference< css::awt::XWindow > xTabControl;
+
+ // describe container window properties.
+ aDescriptor.Type = css::awt::WindowClass_SIMPLE;
+ aDescriptor.ParentIndex = -1;
+ aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >( xTopWindow, css::uno::UNO_QUERY );
+ aDescriptor.Bounds = css::awt::Rectangle(0,0,0,0);
+ aDescriptor.WindowAttributes = 0;
+
+ xContainerWindow = css::uno::Reference< css::awt::XWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
+
+ // create a tab control window properties
+ aDescriptor.Type = css::awt::WindowClass_SIMPLE;
+ aDescriptor.WindowServiceName = DECLARE_ASCII("tabcontrol");
+ aDescriptor.ParentIndex = -1;
+ aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >( xTopWindow, css::uno::UNO_QUERY );
+ aDescriptor.Bounds = css::awt::Rectangle( 0,0,0,0 );
+ aDescriptor.WindowAttributes = 0;
+
+ xTabControl = css::uno::Reference< css::awt::XWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
+
+ if ( xContainerWindow.is() && xTabControl.is() )
+ {
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ aLock.lock();
+ m_xTopWindow = xTopWindow;
+ m_xContainerWindow = xContainerWindow;
+ m_xTabControlWindow = xTabControl;
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ xWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE );
+
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if( pWindow )
+ pWindow->Show( sal_True );
+
+ pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
+ if ( pWindow )
+ pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+
+ pWindow = VCLUnoHelper::GetWindow( xTabControl );
+ if ( pWindow )
+ {
+ pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ TabControl* pTabControl = (TabControl *)pWindow;
+ pTabControl->SetActivatePageHdl( LINK( this, TabWindow, Activate ));
+ pTabControl->SetDeactivatePageHdl( LINK( this, TabWindow, Deactivate ));
+ }
+
+ implts_LayoutWindows();
+ }
+ }
+ }
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XComponent
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL TabWindow::dispose() throw (css::uno::RuntimeException)
+{
+ // Send message to all listener and forget her references.
+ css::uno::Reference< css::lang::XComponent > xThis(
+ static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
+ css::lang::EventObject aEvent( xThis );
+
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+ css::uno::Reference< css::awt::XWindow > xTabControlWindow( m_xTabControlWindow );
+ css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow );
+ css::uno::Reference< css::awt::XTopWindow > xTopWindow( m_xTopWindow );
+ m_xTabControlWindow.clear();
+ m_xContainerWindow.clear();
+ m_xTopWindow.clear();
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ css::uno::Reference< css::lang::XComponent > xComponent( xTabControlWindow, css::uno::UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+
+ xComponent = css::uno::Reference< css::lang::XComponent >( xContainerWindow, css::uno::UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+
+ xComponent = css::uno::Reference< css::lang::XComponent >( xTopWindow, css::uno::UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ aLock.lock();
+ m_bDisposed = sal_True;
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+}
+
+void SAL_CALL TabWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+throw (css::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+ if ( m_bDisposed )
+ return;
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL TabWindow::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
+throw (css::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+ if ( m_bDisposed )
+ return;
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XEventListener
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL TabWindow::disposing( const css::lang::EventObject& )
+throw( css::uno::RuntimeException )
+{
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XWindowListener
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL TabWindow::windowResized( const css::awt::WindowEvent& )
+throw( css::uno::RuntimeException )
+{
+ implts_LayoutWindows();
+}
+
+void SAL_CALL TabWindow::windowMoved( const css::awt::WindowEvent& )
+throw( css::uno::RuntimeException )
+{
+}
+
+void SAL_CALL TabWindow::windowShown( const css::lang::EventObject& )
+throw( css::uno::RuntimeException )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+
+ TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
+ if ( pTabControl )
+ pTabControl->Show();
+
+ if ( m_xContainerWindow.is() )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
+ if ( pWindow )
+ pWindow->Show();
+ }
+}
+
+void SAL_CALL TabWindow::windowHidden( const css::lang::EventObject& )
+throw( css::uno::RuntimeException )
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+ if ( m_xContainerWindow.is() )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
+ if ( pWindow )
+ pWindow->Hide();
+ }
+
+ TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
+ if ( pTabControl )
+ pTabControl->Hide();
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XTopWindowListener
+//---------------------------------------------------------------------------------------------------------
+void SAL_CALL TabWindow::windowOpened( const css::lang::EventObject& )
+throw (css::uno::RuntimeException)
+{
+}
+
+void SAL_CALL TabWindow::windowClosing( const css::lang::EventObject& )
+throw (css::uno::RuntimeException)
+{
+ css::uno::Reference< css::lang::XComponent > xComponent( (OWeakObject *)this, css::uno::UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+}
+
+void SAL_CALL TabWindow::windowClosed( const css::lang::EventObject& )
+throw (css::uno::RuntimeException)
+{
+}
+
+void SAL_CALL TabWindow::windowMinimized( const css::lang::EventObject& )
+throw (css::uno::RuntimeException)
+{
+}
+
+void SAL_CALL TabWindow::windowNormalized( const css::lang::EventObject& )
+throw (css::uno::RuntimeException)
+{
+}
+
+void SAL_CALL TabWindow::windowActivated( const css::lang::EventObject& )
+throw (css::uno::RuntimeException)
+{
+}
+
+void SAL_CALL TabWindow::windowDeactivated( const css::lang::EventObject& )
+throw (css::uno::RuntimeException)
+{
+}
+
+//---------------------------------------------------------------------------------------------------------
+// XSimpleTabController
+//---------------------------------------------------------------------------------------------------------
+
+::sal_Int32 SAL_CALL TabWindow::insertTab()
+throw (css::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw css::lang::DisposedException();
+
+ sal_Int32 nNextTabID( m_nNextTabID++ );
+
+ rtl::OUString aTitle;
+ TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
+ if ( pTabControl )
+ pTabControl->InsertPage( sal_uInt16( nNextTabID ), aTitle );
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ implts_SendNotification( NOTIFY_INSERTED, nNextTabID );
+
+ return nNextTabID;
+}
+
+void SAL_CALL TabWindow::removeTab( ::sal_Int32 ID )
+throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw css::lang::DisposedException();
+
+ TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
+ if ( pTabControl )
+ {
+ sal_uInt16 nCurTabId = pTabControl->GetCurPageId();
+ sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
+ if ( nPos == TAB_PAGE_NOTFOUND )
+ throw css::lang::IndexOutOfBoundsException();
+ else
+ {
+ pTabControl->RemovePage( sal_uInt16( ID ));
+ nCurTabId = pTabControl->GetCurPageId();
+ }
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ implts_SendNotification( NOTIFY_REMOVED, ID );
+
+ // activate new tab if old tab was active!
+ nPos = pTabControl->GetPagePos( sal_uInt16( nCurTabId ));
+ if ( nPos != TAB_PAGE_NOTFOUND && nCurTabId != ID )
+ activateTab( nCurTabId );
+ }
+}
+
+void SAL_CALL TabWindow::setTabProps( ::sal_Int32 ID, const css::uno::Sequence< css::beans::NamedValue >& Properties )
+throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw css::lang::DisposedException();
+
+ TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
+ if ( pTabControl )
+ {
+ sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
+ if ( nPos == TAB_PAGE_NOTFOUND )
+ throw css::lang::IndexOutOfBoundsException();
+ else
+ {
+ comphelper::SequenceAsHashMap aSeqHashMap( Properties );
+
+ ::rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID ));
+ sal_Int32 nNewPos = nPos;
+
+ aTitle = aSeqHashMap.getUnpackedValueOrDefault< ::rtl::OUString >(
+ m_aTitlePropName, aTitle );
+ pTabControl->SetPageText( sal_uInt16( ID ), aTitle );
+ nNewPos = aSeqHashMap.getUnpackedValueOrDefault< sal_Int32 >(
+ m_aPosPropName, nNewPos );
+ if ( nNewPos != sal_Int32( nPos ))
+ {
+ nPos = sal_uInt16( nNewPos );
+ if ( nPos >= pTabControl->GetPageCount() )
+ nPos = TAB_APPEND;
+
+ pTabControl->RemovePage( sal_uInt16( ID ));
+ pTabControl->InsertPage( sal_uInt16( ID ), aTitle, nPos );
+ }
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ aLock.unlock();
+
+ css::uno::Sequence< css::beans::NamedValue > aNamedValueSeq = getTabProps( ID );
+ implts_SendNotification( NOTIFY_CHANGED, ID, aNamedValueSeq );
+ }
+ }
+}
+
+css::uno::Sequence< css::beans::NamedValue > SAL_CALL TabWindow::getTabProps( ::sal_Int32 ID )
+throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw css::lang::DisposedException();
+
+ css::uno::Sequence< css::beans::NamedValue > aNamedValueSeq;
+
+ TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
+ if ( pTabControl )
+ {
+ sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
+ if ( nPos == TAB_PAGE_NOTFOUND )
+ throw css::lang::IndexOutOfBoundsException();
+ else
+ {
+ rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID ));
+ nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
+
+ css::uno::Sequence< css::beans::NamedValue > aSeq( 2 );
+ aSeq[0].Name = m_aTitlePropName;
+ aSeq[0].Value = css::uno::makeAny( aTitle );
+ aSeq[1].Name = m_aPosPropName;
+ aSeq[1].Value = css::uno::makeAny( sal_Int32( nPos ));
+ return aSeq;
+ }
+ }
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ return aNamedValueSeq;
+}
+
+void SAL_CALL TabWindow::activateTab( ::sal_Int32 ID )
+throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw css::lang::DisposedException();
+
+ TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
+ if ( pTabControl )
+ {
+ sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
+ if ( nPos == TAB_PAGE_NOTFOUND )
+ throw css::lang::IndexOutOfBoundsException();
+ else
+ {
+ sal_Int32 nOldID = pTabControl->GetCurPageId();
+ rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID ));
+ pTabControl->SetCurPageId( sal_uInt16( ID ));
+ pTabControl->SelectTabPage( sal_uInt16( ID ));
+ impl_SetTitle( aTitle );
+
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ if ( nOldID != TAB_PAGE_NOTFOUND )
+ implts_SendNotification( NOTIFY_DEACTIVATED, nOldID );
+ implts_SendNotification( NOTIFY_ACTIVATED, ID );
+ }
+ }
+}
+
+::sal_Int32 SAL_CALL TabWindow::getActiveTabID()
+throw (css::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw css::lang::DisposedException();
+
+ TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
+ if ( pTabControl )
+ {
+ sal_uInt16 nID = pTabControl->GetCurPageId();
+ if ( nID == TAB_PAGE_NOTFOUND )
+ return -1;
+ else
+ return sal_Int32( nID );
+ }
+
+ return -1;
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+}
+
+void SAL_CALL TabWindow::addTabListener(
+ const css::uno::Reference< css::awt::XTabListener >& xListener )
+throw (css::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+ if ( m_bDisposed )
+ return;
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ m_aListenerContainer.addInterface(
+ ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL TabWindow::removeTabListener( const css::uno::Reference< css::awt::XTabListener >& xListener )
+throw (css::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+ if ( m_bDisposed )
+ return;
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ m_aListenerContainer.removeInterface(
+ ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >* ) NULL ), xListener );
+}
+
+//---------------------------------------------------------------------------------------------------------
+// OPropertySetHelper
+//---------------------------------------------------------------------------------------------------------
+
+// XPropertySet helper
+sal_Bool SAL_CALL TabWindow::convertFastPropertyValue( css::uno::Any& aConvertedValue ,
+ css::uno::Any& aOldValue ,
+ sal_Int32 nHandle ,
+ const css::uno::Any& aValue )
+throw( css::lang::IllegalArgumentException )
+{
+ // Initialize state with sal_False !!!
+ // (Handle can be invalid)
+ sal_Bool bReturn = sal_False;
+
+ switch( nHandle )
+ {
+ case TABWINDOW_PROPHANDLE_PARENTWINDOW :
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny( m_xContainerWindow ),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+
+ case TABWINDOW_PROPHANDLE_TOPWINDOW :
+ bReturn = PropHelper::willPropertyBeChanged(
+ com::sun::star::uno::makeAny( m_xTopWindow ),
+ aValue,
+ aOldValue,
+ aConvertedValue);
+ break;
+ }
+
+ // Return state of operation.
+ return bReturn ;
+}
+
+void SAL_CALL TabWindow::setFastPropertyValue_NoBroadcast( sal_Int32,
+ const css::uno::Any&)
+throw( css::uno::Exception )
+{
+}
+
+void SAL_CALL TabWindow::getFastPropertyValue( css::uno::Any& aValue ,
+ sal_Int32 nHandle ) const
+{
+ switch( nHandle )
+ {
+ case TABWINDOW_PROPHANDLE_PARENTWINDOW:
+ aValue <<= m_xContainerWindow;
+ break;
+ case TABWINDOW_PROPHANDLE_TOPWINDOW:
+ aValue <<= m_xTopWindow;
+ break;
+ }
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL TabWindow::getInfoHelper()
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
+ static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ // Ready for multithreading
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfoHelper == NULL )
+ {
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
+ // "sal_True" say: Table is sorted by name.
+ static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return(*pInfoHelper);
+}
+
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL TabWindow::getPropertySetInfo()
+throw ( css::uno::RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
+ static css::uno::Reference< css::beans::XPropertySetInfo >* pInfo = NULL;
+
+ if( pInfo == NULL )
+ {
+ // Ready for multithreading
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfo == NULL )
+ {
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+const css::uno::Sequence< css::beans::Property > TabWindow::impl_getStaticPropertyDescriptor()
+{
+ // Create a new static property array to initialize sequence!
+ // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
+ // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
+ // It's necessary for methods of OPropertySetHelper.
+ // ATTENTION:
+ // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
+
+ static const com::sun::star::beans::Property pProperties[] =
+ {
+ com::sun::star::beans::Property( TABWINDOW_PROPNAME_PARENTWINDOW,
+ TABWINDOW_PROPHANDLE_PARENTWINDOW,
+ ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
+ com::sun::star::beans::PropertyAttribute::READONLY ),
+ com::sun::star::beans::Property( TABWINDOW_PROPNAME_TOPWINDOW,
+ TABWINDOW_PROPHANDLE_TOPWINDOW,
+ ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
+ com::sun::star::beans::PropertyAttribute::READONLY )
+ }; // Use it to initialize sequence!
+ static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, TABWINDOW_PROPCOUNT );
+
+ // Return static "PropertyDescriptor"
+ return lPropertyDescriptor;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/tabwin/tabwinfactory.cxx b/framework/source/tabwin/tabwinfactory.cxx
new file mode 100644
index 000000000000..2c4710209f7c
--- /dev/null
+++ b/framework/source/tabwin/tabwinfactory.cxx
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <tabwin/tabwinfactory.hxx>
+#include <tabwin/tabwindow.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using ::rtl::OUString;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( TabWinFactory ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_TABWINFACTORY ,
+ IMPLEMENTATIONNAME_TABWINFACTORY
+ )
+
+DEFINE_INIT_SERVICE ( TabWinFactory, {} )
+
+TabWinFactory::TabWinFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_xServiceManager( xServiceManager )
+{
+}
+
+TabWinFactory::~TabWinFactory()
+{
+}
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL TabWinFactory::createInstanceWithContext(
+ const css::uno::Reference< css::uno::XComponentContext >& Context )
+throw ( css::uno::Exception, css::uno::RuntimeException )
+{
+ css::uno::Sequence< css::uno::Any > aArgs;
+
+ return createInstanceWithArgumentsAndContext( aArgs, Context );
+}
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL TabWinFactory::createInstanceWithArgumentsAndContext(
+ const css::uno::Sequence< css::uno::Any >& Arguments, const css::uno::Reference< css::uno::XComponentContext >& )
+throw ( css::uno::Exception, css::uno::RuntimeException )
+{
+ const rtl::OUString aTopWindowArgName( RTL_CONSTASCII_USTRINGPARAM( "TopWindow" ));
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aLock( m_aLock );
+ css::uno::Reference< css::awt::XToolkit > xToolkit = m_xToolkit;
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xServiceManager );
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ css::uno::Reference< css::uno::XInterface > xReturn;
+ css::uno::Reference< css::awt::XTopWindow > xTopWindow;
+ css::beans::PropertyValue aPropValue;
+
+ for ( sal_Int32 i = 0; i < Arguments.getLength(); i++ )
+ {
+ if ( Arguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name == aTopWindowArgName )
+ aPropValue.Value >>= xTopWindow;
+ }
+ }
+
+ if ( !xToolkit.is() && xSMGR.is() )
+ {
+ xToolkit = css::uno::Reference< css::awt::XToolkit >( xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
+ if ( xToolkit.is() )
+ {
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ aLock.lock();
+ m_xToolkit = xToolkit;
+ aLock.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ }
+ }
+
+ if ( !xTopWindow.is() )
+ {
+ if ( xToolkit.is() )
+ {
+ // describe window properties.
+ css::awt::WindowDescriptor aDescriptor;
+ aDescriptor.Type = css::awt::WindowClass_TOP ;
+ aDescriptor.ParentIndex = -1 ;
+ aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >() ;
+ aDescriptor.Bounds = css::awt::Rectangle(0,0,0,0) ;
+ aDescriptor.WindowAttributes = css::awt::WindowAttribute::BORDER|
+ css::awt::WindowAttribute::SIZEABLE|
+ css::awt::WindowAttribute::MOVEABLE|
+ css::awt::WindowAttribute::CLOSEABLE|
+ css::awt::WindowAttribute::MINSIZE;
+
+ // create a parent window
+ xTopWindow = css::uno::Reference< css::awt::XTopWindow >(
+ xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
+ }
+ }
+
+ if ( xTopWindow.is() )
+ {
+ TabWindow* pTabWindow = new TabWindow( xSMGR );
+
+ css::uno::Sequence< css::uno::Any > aArgs( 1 );
+
+ aPropValue.Name = aTopWindowArgName;
+ aPropValue.Value = css::uno::makeAny( xTopWindow );
+ aArgs[0] = css::uno::makeAny( aPropValue );
+ pTabWindow->initialize( aArgs );
+
+ xReturn = css::uno::Reference< css::uno::XInterface >(
+ static_cast< OWeakObject* >( pTabWindow ), css::uno::UNO_QUERY );
+ }
+
+ return xReturn;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/globalsettings.cxx b/framework/source/uiconfiguration/globalsettings.cxx
new file mode 100644
index 000000000000..f246cb9365a0
--- /dev/null
+++ b/framework/source/uiconfiguration/globalsettings.cxx
@@ -0,0 +1,358 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "uiconfiguration/globalsettings.hxx"
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <rtl/instance.hxx>
+#include <cppuhelper/weak.hxx>
+#include <tools/debug.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star;
+
+using ::rtl::OUString;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+static const char GLOBALSETTINGS_ROOT_ACCESS[] = "/org.openoffice.Office.UI.GlobalSettings/Toolbars";
+
+static const char GLOBALSETTINGS_NODEREF_STATES[] = "States";
+static const char GLOBALSETTINGS_PROPERTY_LOCKED[] = "Locked";
+static const char GLOBALSETTINGS_PROPERTY_DOCKED[] = "Docked";
+static const char GLOBALSETTINGS_PROPERTY_STATESENABLED[] = "StatesEnabled";
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// Configuration access class for WindowState supplier implementation
+//*****************************************************************************************************************
+
+class GlobalSettings_Access : public ::com::sun::star::lang::XComponent ,
+ public ::com::sun::star::lang::XEventListener ,
+ private ThreadHelpBase , // Struct for right initalization of mutex member! Must be first of baseclasses.
+ public ::cppu::OWeakObject
+{
+ public:
+ GlobalSettings_Access( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager );
+ virtual ~GlobalSettings_Access();
+
+ // XInterface, XTypeProvider, XServiceInfo
+ FWK_DECLARE_XINTERFACE
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ // settings access
+ sal_Bool HasStatesInfo( GlobalSettings::UIElementType eElementType );
+ sal_Bool GetStateInfo( GlobalSettings::UIElementType eElementType, GlobalSettings::StateInfo eStateInfo, ::com::sun::star::uno::Any& aValue );
+
+ private:
+ sal_Bool impl_initConfigAccess();
+
+ sal_Bool m_bDisposed : 1,
+ m_bConfigRead : 1;
+ rtl::OUString m_aConfigSettingsAccess;
+ rtl::OUString m_aNodeRefStates;
+ rtl::OUString m_aPropStatesEnabled;
+ rtl::OUString m_aPropLocked;
+ rtl::OUString m_aPropDocked;
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xConfigAccess;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager;
+};
+
+
+//*****************************************************************************************************************
+// XInterface
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_2 ( GlobalSettings_Access ,
+ OWeakObject ,
+ DIRECT_INTERFACE ( css::lang::XComponent ),
+ DIRECT_INTERFACE ( css::lang::XEventListener )
+ )
+
+GlobalSettings_Access::GlobalSettings_Access( const css::uno::Reference< css::lang::XMultiServiceFactory >& rServiceManager ) :
+ ThreadHelpBase(),
+ m_bDisposed( sal_False ),
+ m_bConfigRead( sal_False ),
+ m_aConfigSettingsAccess( RTL_CONSTASCII_USTRINGPARAM( GLOBALSETTINGS_ROOT_ACCESS )),
+ m_aNodeRefStates( RTL_CONSTASCII_USTRINGPARAM( GLOBALSETTINGS_NODEREF_STATES )),
+ m_aPropStatesEnabled( RTL_CONSTASCII_USTRINGPARAM( GLOBALSETTINGS_PROPERTY_STATESENABLED )),
+ m_aPropLocked( RTL_CONSTASCII_USTRINGPARAM( GLOBALSETTINGS_PROPERTY_LOCKED )),
+ m_aPropDocked( RTL_CONSTASCII_USTRINGPARAM( GLOBALSETTINGS_PROPERTY_DOCKED )),
+ m_xServiceManager( rServiceManager )
+{
+}
+
+GlobalSettings_Access::~GlobalSettings_Access()
+{
+}
+
+// XComponent
+void SAL_CALL GlobalSettings_Access::dispose()
+throw ( css::uno::RuntimeException )
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ m_xConfigAccess.clear();
+ m_bDisposed = sal_True;
+}
+
+void SAL_CALL GlobalSettings_Access::addEventListener( const css::uno::Reference< css::lang::XEventListener >& )
+throw (css::uno::RuntimeException)
+{
+}
+
+void SAL_CALL GlobalSettings_Access::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& )
+throw (css::uno::RuntimeException)
+{
+}
+
+// XEventListener
+void SAL_CALL GlobalSettings_Access::disposing( const css::lang::EventObject& )
+throw (css::uno::RuntimeException)
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+ m_xConfigAccess.clear();
+}
+
+// settings access
+sal_Bool GlobalSettings_Access::HasStatesInfo( GlobalSettings::UIElementType eElementType )
+{
+ ResetableGuard aLock( m_aLock );
+ if ( eElementType == GlobalSettings::UIELEMENT_TYPE_DOCKWINDOW )
+ return sal_False;
+ else if ( eElementType == GlobalSettings::UIELEMENT_TYPE_STATUSBAR )
+ return sal_False;
+
+ if ( m_bDisposed )
+ return sal_False;
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ impl_initConfigAccess();
+ }
+
+ if ( m_xConfigAccess.is() )
+ {
+ try
+ {
+ css::uno::Any a;
+ sal_Bool bValue = sal_Bool();
+ a = m_xConfigAccess->getByName( m_aPropStatesEnabled );
+ if ( a >>= bValue )
+ return bValue;
+ }
+ catch ( css::container::NoSuchElementException& )
+ {
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+ }
+
+ return sal_False;
+}
+
+sal_Bool GlobalSettings_Access::GetStateInfo( GlobalSettings::UIElementType eElementType, GlobalSettings::StateInfo eStateInfo, ::com::sun::star::uno::Any& aValue )
+{
+ ResetableGuard aLock( m_aLock );
+ if ( eElementType == GlobalSettings::UIELEMENT_TYPE_DOCKWINDOW )
+ return sal_False;
+ else if ( eElementType == GlobalSettings::UIELEMENT_TYPE_STATUSBAR )
+ return sal_False;
+
+ if ( m_bDisposed )
+ return sal_False;
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ impl_initConfigAccess();
+ }
+
+ if ( m_xConfigAccess.is() )
+ {
+ try
+ {
+ css::uno::Any a;
+ a = m_xConfigAccess->getByName( m_aNodeRefStates );
+ css::uno::Reference< css::container::XNameAccess > xNameAccess;
+ if ( a >>= xNameAccess )
+ {
+ if ( eStateInfo == GlobalSettings::STATEINFO_LOCKED )
+ a = xNameAccess->getByName( m_aPropLocked );
+ else if ( eStateInfo == GlobalSettings::STATEINFO_DOCKED )
+ a = xNameAccess->getByName( m_aPropDocked );
+
+ aValue = a;
+ return sal_True;
+ }
+ }
+ catch ( css::container::NoSuchElementException& )
+ {
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+ }
+
+ return sal_False;
+}
+
+sal_Bool GlobalSettings_Access::impl_initConfigAccess()
+{
+ css::uno::Sequence< css::uno::Any > aArgs( 2 );
+ css::beans::PropertyValue aPropValue;
+
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider;
+ if ( m_xServiceManager.is() )
+ xConfigProvider = css::uno::Reference< css::lang::XMultiServiceFactory >(
+ m_xServiceManager->createInstance( SERVICENAME_CFGPROVIDER ),
+ css::uno::UNO_QUERY );
+
+ if ( xConfigProvider.is() )
+ {
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
+ aPropValue.Value = css::uno::makeAny( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( GLOBALSETTINGS_ROOT_ACCESS )));
+ aArgs[0] = css::uno::makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "lazywrite" ));
+ aPropValue.Value = css::uno::makeAny( sal_True );
+ aArgs[1] = css::uno::makeAny( aPropValue );
+
+ m_xConfigAccess = css::uno::Reference< css::container::XNameAccess >(
+ xConfigProvider->createInstanceWithArguments(
+ SERVICENAME_CFGREADACCESS, aArgs ),
+ css::uno::UNO_QUERY );
+
+ css::uno::Reference< css::lang::XComponent > xComponent( xConfigProvider, css::uno::UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->addEventListener(
+ css::uno::Reference< css::lang::XEventListener >(
+ static_cast< cppu::OWeakObject* >( this ),
+ css::uno::UNO_QUERY ));
+ }
+
+ return m_xConfigAccess.is();
+ }
+ catch ( css::lang::WrappedTargetException& )
+ {
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+
+ return sal_False;
+}
+
+//*****************************************************************************************************************
+// global class
+//*****************************************************************************************************************
+
+struct mutexGlobalSettings : public rtl::Static< osl::Mutex, mutexGlobalSettings > {};
+static GlobalSettings_Access* pStaticSettings = 0;
+
+static GlobalSettings_Access* GetGlobalSettings( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSrvMgr )
+{
+ osl::MutexGuard aGuard(mutexGlobalSettings::get());
+ if ( !pStaticSettings )
+ pStaticSettings = new GlobalSettings_Access( rSrvMgr );
+ return pStaticSettings;
+}
+
+GlobalSettings::GlobalSettings( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSrvMgr ) :
+ m_xSrvMgr( rSrvMgr )
+{
+}
+
+GlobalSettings::~GlobalSettings()
+{
+}
+
+// settings access
+sal_Bool GlobalSettings::HasStatesInfo( UIElementType eElementType )
+{
+ GlobalSettings_Access* pSettings( GetGlobalSettings( m_xSrvMgr ));
+
+ if ( pSettings )
+ return pSettings->HasStatesInfo( eElementType );
+ else
+ return sal_False;
+}
+
+sal_Bool GlobalSettings::GetStateInfo( UIElementType eElementType, StateInfo eStateInfo, ::com::sun::star::uno::Any& aValue )
+{
+ GlobalSettings_Access* pSettings( GetGlobalSettings( m_xSrvMgr ));
+
+ if ( pSettings )
+ return pSettings->GetStateInfo( eElementType, eStateInfo, aValue );
+ else
+ return sal_False;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/graphicnameaccess.cxx b/framework/source/uiconfiguration/graphicnameaccess.cxx
new file mode 100644
index 000000000000..802a6507a1fa
--- /dev/null
+++ b/framework/source/uiconfiguration/graphicnameaccess.cxx
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uiconfiguration/graphicnameaccess.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <comphelper/sequence.hxx>
+
+using namespace ::com::sun::star;
+
+namespace framework
+{
+
+GraphicNameAccess::GraphicNameAccess()
+{
+}
+
+GraphicNameAccess::~GraphicNameAccess()
+{
+}
+
+void GraphicNameAccess::addElement( const rtl::OUString& rName, const uno::Reference< graphic::XGraphic >& rElement )
+{
+ m_aNameToElementMap.insert( NameGraphicHashMap::value_type( rName, rElement ));
+}
+
+// XNameAccess
+uno::Any SAL_CALL GraphicNameAccess::getByName( const ::rtl::OUString& aName )
+throw( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ NameGraphicHashMap::const_iterator pIter = m_aNameToElementMap.find( aName );
+ if ( pIter != m_aNameToElementMap.end() )
+ return uno::makeAny( pIter->second );
+ else
+ throw container::NoSuchElementException();
+}
+
+uno::Sequence< ::rtl::OUString > SAL_CALL GraphicNameAccess::getElementNames()
+throw(::com::sun::star::uno::RuntimeException)
+{
+ if ( m_aSeq.getLength() == 0 )
+ {
+ uno::Sequence< rtl::OUString > aSeq( m_aNameToElementMap.size() );
+ NameGraphicHashMap::const_iterator pIter = m_aNameToElementMap.begin();
+ sal_Int32 i( 0);
+ while ( pIter != m_aNameToElementMap.end())
+ {
+ aSeq[i++] = pIter->first;
+ ++pIter;
+ }
+ m_aSeq = aSeq;
+ }
+
+ return m_aSeq;
+}
+
+sal_Bool SAL_CALL GraphicNameAccess::hasByName( const ::rtl::OUString& aName )
+throw(::com::sun::star::uno::RuntimeException)
+{
+ NameGraphicHashMap::const_iterator pIter = m_aNameToElementMap.find( aName );
+ return ( pIter != m_aNameToElementMap.end() );
+}
+
+// XElementAccess
+sal_Bool SAL_CALL GraphicNameAccess::hasElements()
+throw( uno::RuntimeException )
+{
+ return ( !m_aNameToElementMap.empty() );
+}
+
+uno::Type SAL_CALL GraphicNameAccess::getElementType()
+throw( uno::RuntimeException )
+{
+ return ::getCppuType( (const uno::Reference< graphic::XGraphic > *)NULL );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/imagemanager.cxx b/framework/source/uiconfiguration/imagemanager.cxx
new file mode 100644
index 000000000000..325b6bf45aae
--- /dev/null
+++ b/framework/source/uiconfiguration/imagemanager.cxx
@@ -0,0 +1,257 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uiconfiguration/imagemanager.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <framework/imagesconfiguration.hxx>
+#include <uiconfiguration/graphicnameaccess.hxx>
+#include <services.h>
+#include "imagemanagerimpl.hxx"
+
+#include "properties.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/ui/ConfigurationEvent.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/sequence.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <vcl/pngread.hxx>
+#include <vcl/pngwrite.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::makeAny;
+using ::com::sun::star::graphic::XGraphic;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::ui;
+
+// Image sizes for our toolbars/menus
+const sal_Int32 IMAGE_SIZE_NORMAL = 16;
+const sal_Int32 IMAGE_SIZE_LARGE = 26;
+const sal_Int16 MAX_IMAGETYPE_VALUE = ::com::sun::star::ui::ImageType::COLOR_HIGHCONTRAST|
+ ::com::sun::star::ui::ImageType::SIZE_LARGE;
+
+namespace framework
+{
+
+typedef GraphicNameAccess CmdToXGraphicNameAccess;
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_MULTISERVICE ( ImageManager ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_IMAGEMANAGER ,
+ IMPLEMENTATIONNAME_IMAGEMANAGER
+ )
+
+DEFINE_INIT_SERVICE ( ImageManager, {} )
+
+ImageManager::ImageManager( uno::Reference< XMultiServiceFactory > xServiceManager ) :
+ ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_pImpl( new ImageManagerImpl(xServiceManager,this,false) )
+{
+}
+
+ImageManager::~ImageManager()
+{
+ m_pImpl->clear();
+}
+
+// XComponent
+void SAL_CALL ImageManager::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->dispose();
+}
+
+void SAL_CALL ImageManager::addEventListener( const uno::Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->addEventListener(xListener);
+}
+
+void SAL_CALL ImageManager::removeEventListener( const uno::Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_pImpl->removeEventListener(xListener);
+}
+
+// Non-UNO methods
+void ImageManager::setStorage( const uno::Reference< XStorage >& Storage )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_pImpl->m_aLock );
+
+ m_pImpl->m_xUserConfigStorage = Storage;
+ m_pImpl->implts_initialize();
+}
+
+// XInitialization
+void SAL_CALL ImageManager::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ m_pImpl->initialize(aArguments);
+}
+
+// XImageManager
+void SAL_CALL ImageManager::reset()
+throw (::com::sun::star::uno::RuntimeException)
+{
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_pImpl->reset();
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ImageManager::getAllImageNames( ::sal_Int16 nImageType )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_pImpl->getAllImageNames( nImageType );
+}
+
+::sal_Bool SAL_CALL ImageManager::hasImage( ::sal_Int16 nImageType, const ::rtl::OUString& aCommandURL )
+throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ return m_pImpl->hasImage(nImageType,aCommandURL);
+}
+
+Sequence< uno::Reference< XGraphic > > SAL_CALL ImageManager::getImages(
+ ::sal_Int16 nImageType,
+ const Sequence< ::rtl::OUString >& aCommandURLSequence )
+throw ( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException )
+{
+ return m_pImpl->getImages(nImageType,aCommandURLSequence);
+}
+
+void SAL_CALL ImageManager::replaceImages(
+ ::sal_Int16 nImageType,
+ const Sequence< ::rtl::OUString >& aCommandURLSequence,
+ const Sequence< uno::Reference< XGraphic > >& aGraphicsSequence )
+throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::IllegalAccessException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->replaceImages(nImageType,aCommandURLSequence,aGraphicsSequence);
+}
+
+void SAL_CALL ImageManager::removeImages( ::sal_Int16 nImageType, const Sequence< ::rtl::OUString >& aCommandURLSequence )
+throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::IllegalAccessException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->removeImages(nImageType,aCommandURLSequence);
+}
+
+void SAL_CALL ImageManager::insertImages( ::sal_Int16 nImageType, const Sequence< ::rtl::OUString >& aCommandURLSequence, const Sequence< uno::Reference< XGraphic > >& aGraphicSequence )
+throw ( ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::IllegalAccessException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->insertImages(nImageType,aCommandURLSequence,aGraphicSequence);
+}
+
+// XUIConfiguration
+void SAL_CALL ImageManager::addConfigurationListener( const uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->addConfigurationListener(xListener);
+}
+
+void SAL_CALL ImageManager::removeConfigurationListener( const uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_pImpl->removeConfigurationListener(xListener);
+}
+
+// XUIConfigurationPersistence
+void SAL_CALL ImageManager::reload()
+throw ( ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException )
+{
+ m_pImpl->reload();
+}
+
+void SAL_CALL ImageManager::store()
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->store();
+}
+
+void SAL_CALL ImageManager::storeToStorage( const uno::Reference< XStorage >& Storage )
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->storeToStorage(Storage);
+}
+
+sal_Bool SAL_CALL ImageManager::isModified()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_pImpl->isModified();
+}
+
+sal_Bool SAL_CALL ImageManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_pImpl->isReadOnly();
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/imagemanagerimpl.cxx b/framework/source/uiconfiguration/imagemanagerimpl.cxx
new file mode 100644
index 000000000000..4b7722c43abe
--- /dev/null
+++ b/framework/source/uiconfiguration/imagemanagerimpl.cxx
@@ -0,0 +1,1460 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <imagemanagerimpl.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <framework/imagesconfiguration.hxx>
+#include <uiconfiguration/graphicnameaccess.hxx>
+#include <services.h>
+
+#include "properties.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/ui/ConfigurationEvent.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/sequence.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <vcl/pngread.hxx>
+#include <vcl/pngwrite.hxx>
+#include <rtl/logfile.hxx>
+#include "svtools/miscopt.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::makeAny;
+using ::com::sun::star::graphic::XGraphic;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::ui;
+using namespace ::cppu;
+
+// Image sizes for our toolbars/menus
+const sal_Int32 IMAGE_SIZE_NORMAL = 16;
+const sal_Int32 IMAGE_SIZE_LARGE = 26;
+const sal_Int16 MAX_IMAGETYPE_VALUE = ::com::sun::star::ui::ImageType::SIZE_LARGE;
+
+static const char IMAGE_FOLDER[] = "images";
+static const char BITMAPS_FOLDER[] = "Bitmaps";
+static const char IMAGE_EXTENSION[] = ".png";
+
+static const char* IMAGELIST_XML_FILE[] =
+{
+ "sc_imagelist.xml",
+ "lc_imagelist.xml"
+};
+
+static const char* BITMAP_FILE_NAMES[] =
+{
+ "sc_userimages.png",
+ "lc_userimages.png"
+};
+
+namespace framework
+{
+ static char ModuleImageList[] = "private:resource/images/moduleimages";
+ static osl::Mutex* pImageListWrapperMutex = 0;
+ static GlobalImageList* pGlobalImageList = 0;
+ static const char* ImageType_Prefixes[ImageType_COUNT] =
+ {
+ "res/commandimagelist/sc_",
+ "res/commandimagelist/lc_"
+ };
+
+typedef GraphicNameAccess CmdToXGraphicNameAccess;
+
+static osl::Mutex& getGlobalImageListMutex()
+{
+ if ( pImageListWrapperMutex == 0 )
+ {
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+ if ( pImageListWrapperMutex == 0 )
+ pImageListWrapperMutex = new osl::Mutex;
+ }
+
+ return *pImageListWrapperMutex;
+}
+
+static GlobalImageList* getGlobalImageList( const uno::Reference< XMultiServiceFactory >& rServiceManager )
+{
+ osl::MutexGuard guard( getGlobalImageListMutex() );
+
+ if ( pGlobalImageList == 0 )
+ pGlobalImageList = new GlobalImageList( rServiceManager );
+
+ return pGlobalImageList;
+}
+
+static rtl::OUString getCanonicalName( const rtl::OUString& rFileName )
+{
+ bool bRemoveSlash( true );
+ sal_Int32 nLength = rFileName.getLength();
+ const sal_Unicode* pString = rFileName.getStr();
+
+ rtl::OUStringBuffer aBuf( nLength );
+ for ( sal_Int32 i = 0; i < nLength; i++ )
+ {
+ const sal_Unicode c = pString[i];
+ switch ( c )
+ {
+ // map forbidden characters to escape
+ case '/' : if ( !bRemoveSlash )
+ aBuf.appendAscii( "%2f" );
+ break;
+ case '\\': aBuf.appendAscii( "%5c" ); bRemoveSlash = false; break;
+ case ':' : aBuf.appendAscii( "%3a" ); bRemoveSlash = false; break;
+ case '*' : aBuf.appendAscii( "%2a" ); bRemoveSlash = false; break;
+ case '?' : aBuf.appendAscii( "%3f" ); bRemoveSlash = false; break;
+ case '<' : aBuf.appendAscii( "%3c" ); bRemoveSlash = false; break;
+ case '>' : aBuf.appendAscii( "%3e" ); bRemoveSlash = false; break;
+ case '|' : aBuf.appendAscii( "%7c" ); bRemoveSlash = false; break;
+ default: aBuf.append( c ); bRemoveSlash = false;
+ }
+ }
+ return aBuf.makeStringAndClear();
+}
+
+//_________________________________________________________________________________________________________________
+
+CmdImageList::CmdImageList( const uno::Reference< XMultiServiceFactory >& rServiceManager, const rtl::OUString& aModuleIdentifier ) :
+ m_bVectorInit( sal_False ),
+ m_aModuleIdentifier( aModuleIdentifier ),
+ m_xServiceManager( rServiceManager ),
+ m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
+{
+ for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
+ m_pImageList[n] = 0;
+}
+
+CmdImageList::~CmdImageList()
+{
+ for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
+ delete m_pImageList[n];
+}
+
+void CmdImageList::impl_fillCommandToImageNameMap()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework: CmdImageList::impl_fillCommandToImageNameMap" );
+
+ if ( !m_bVectorInit )
+ {
+ const rtl::OUString aCommandImageList( RTL_CONSTASCII_USTRINGPARAM( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDIMAGELIST ));
+ Sequence< OUString > aCmdImageSeq;
+ uno::Reference< XNameAccess > xCmdDesc( m_xServiceManager->createInstance(
+ SERVICENAME_UICOMMANDDESCRIPTION ),
+ UNO_QUERY );
+
+ if ( m_aModuleIdentifier.getLength() > 0 )
+ {
+ // If we have a module identifier - use to retrieve the command image name list from it.
+ // Otherwise we will use the global command image list
+ try
+ {
+ xCmdDesc->getByName( m_aModuleIdentifier ) >>= xCmdDesc;
+ if ( xCmdDesc.is() )
+ xCmdDesc->getByName( aCommandImageList ) >>= aCmdImageSeq;
+ }
+ catch ( NoSuchElementException& )
+ {
+ // Module unknown we will work with an empty command image list!
+ return;
+ }
+ }
+
+ if ( xCmdDesc.is() )
+ {
+ try
+ {
+ xCmdDesc->getByName( aCommandImageList ) >>= aCmdImageSeq;
+ }
+ catch ( NoSuchElementException& )
+ {
+ }
+ catch ( WrappedTargetException& )
+ {
+ }
+ }
+
+ // We have to map commands which uses special characters like '/',':','?','\','<'.'>','|'
+ String aExt = String::CreateFromAscii( IMAGE_EXTENSION );
+ m_aImageCommandNameVector.resize(aCmdImageSeq.getLength() );
+ m_aImageNameVector.resize( aCmdImageSeq.getLength() );
+
+ ::std::copy( aCmdImageSeq.getConstArray(),
+ aCmdImageSeq.getConstArray()+aCmdImageSeq.getLength(),
+ m_aImageCommandNameVector.begin() );
+
+ // Create a image name vector that must be provided to the vcl imagelist. We also need
+ // a command to image name map to speed up access time for image retrieval.
+ OUString aUNOString( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
+ String aEmptyString;
+ const sal_uInt32 nCount = m_aImageCommandNameVector.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ OUString aCommandName( m_aImageCommandNameVector[i] );
+ String aImageName;
+
+ if ( aCommandName.indexOf( aUNOString ) != 0 )
+ {
+ INetURLObject aUrlObject( aCommandName, INetURLObject::ENCODE_ALL );
+ aImageName = aUrlObject.GetURLPath();
+ aImageName = getCanonicalName( aImageName ); // convert to valid filename
+ }
+ else
+ {
+ // just remove the schema
+ if ( aCommandName.getLength() > 5 )
+ aImageName = aCommandName.copy( 5 );
+ else
+ aImageName = aEmptyString;
+
+ // Search for query part.
+ sal_Int32 nIndex = aImageName.Search( '?' );
+ if ( nIndex != STRING_NOTFOUND )
+ aImageName = getCanonicalName( aImageName ); // convert to valid filename
+ }
+ // Image names are not case-dependent. Always use lower case characters to
+ // reflect this.
+ aImageName += aExt;
+ aImageName.ToLowerAscii();
+
+ m_aImageNameVector[i] = aImageName;
+ m_aCommandToImageNameMap.insert( CommandToImageNameMap::value_type( aCommandName, aImageName ));
+ }
+
+ m_bVectorInit = sal_True;
+ }
+}
+
+ImageList* CmdImageList::impl_getImageList( sal_Int16 nImageType )
+{
+ SvtMiscOptions aMiscOptions;
+
+ sal_Int16 nSymbolsStyle = aMiscOptions.GetCurrentSymbolsStyle();
+ if ( nSymbolsStyle != m_nSymbolsStyle )
+ {
+ m_nSymbolsStyle = nSymbolsStyle;
+ for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
+ delete m_pImageList[n], m_pImageList[n] = NULL;
+ }
+
+ if ( !m_pImageList[nImageType] )
+ {
+ m_pImageList[nImageType] = new ImageList( m_aImageNameVector,
+ OUString::createFromAscii( ImageType_Prefixes[nImageType] ) );
+ }
+
+ return m_pImageList[nImageType];
+}
+
+std::vector< ::rtl::OUString >& CmdImageList::impl_getImageNameVector()
+{
+ return m_aImageNameVector;
+}
+
+std::vector< rtl::OUString >& CmdImageList::impl_getImageCommandNameVector()
+{
+ return m_aImageCommandNameVector;
+}
+
+Image CmdImageList::getImageFromCommandURL( sal_Int16 nImageType, const rtl::OUString& rCommandURL )
+{
+ impl_fillCommandToImageNameMap();
+ CommandToImageNameMap::const_iterator pIter = m_aCommandToImageNameMap.find( rCommandURL );
+ if ( pIter != m_aCommandToImageNameMap.end() )
+ {
+ ImageList* pImageList = impl_getImageList( nImageType );
+ return pImageList->GetImage( pIter->second );
+ }
+
+ return Image();
+}
+
+bool CmdImageList::hasImage( sal_Int16 /*nImageType*/, const rtl::OUString& rCommandURL )
+{
+ impl_fillCommandToImageNameMap();
+ CommandToImageNameMap::const_iterator pIter = m_aCommandToImageNameMap.find( rCommandURL );
+ if ( pIter != m_aCommandToImageNameMap.end() )
+ return true;
+ else
+ return false;
+}
+
+::std::vector< rtl::OUString >& CmdImageList::getImageNames()
+{
+ return impl_getImageNameVector();
+}
+
+::std::vector< rtl::OUString >& CmdImageList::getImageCommandNames()
+{
+ return impl_getImageCommandNameVector();
+}
+
+//_________________________________________________________________________________________________________________
+
+GlobalImageList::GlobalImageList( const uno::Reference< XMultiServiceFactory >& rServiceManager ) :
+ CmdImageList( rServiceManager, rtl::OUString() ),
+ m_nRefCount( 0 )
+{
+}
+
+GlobalImageList::~GlobalImageList()
+{
+}
+
+Image GlobalImageList::getImageFromCommandURL( sal_Int16 nImageType, const rtl::OUString& rCommandURL )
+{
+ osl::MutexGuard guard( getGlobalImageListMutex() );
+ return CmdImageList::getImageFromCommandURL( nImageType, rCommandURL );
+}
+
+bool GlobalImageList::hasImage( sal_Int16 nImageType, const rtl::OUString& rCommandURL )
+{
+ osl::MutexGuard guard( getGlobalImageListMutex() );
+ return CmdImageList::hasImage( nImageType, rCommandURL );
+}
+
+::std::vector< rtl::OUString >& GlobalImageList::getImageNames()
+{
+ osl::MutexGuard guard( getGlobalImageListMutex() );
+ return impl_getImageNameVector();
+}
+
+::std::vector< rtl::OUString >& GlobalImageList::getImageCommandNames()
+{
+ osl::MutexGuard guard( getGlobalImageListMutex() );
+ return impl_getImageCommandNameVector();
+}
+
+oslInterlockedCount GlobalImageList::acquire()
+{
+ osl_incrementInterlockedCount( &m_nRefCount );
+ return m_nRefCount;
+}
+
+oslInterlockedCount GlobalImageList::release()
+{
+ osl::MutexGuard guard( getGlobalImageListMutex() );
+
+ if ( !osl_decrementInterlockedCount( &m_nRefCount ))
+ {
+ oslInterlockedCount nCount( m_nRefCount );
+ // remove global pointer as we destroy the object now
+ pGlobalImageList = 0;
+ delete this;
+ return nCount;
+ }
+
+ return m_nRefCount;
+}
+
+static sal_Bool implts_checkAndScaleGraphic( uno::Reference< XGraphic >& rOutGraphic, const uno::Reference< XGraphic >& rInGraphic, sal_Int16 nImageType )
+{
+ static Size aNormSize( IMAGE_SIZE_NORMAL, IMAGE_SIZE_NORMAL );
+ static Size aLargeSize( IMAGE_SIZE_LARGE, IMAGE_SIZE_LARGE );
+
+ if ( !rInGraphic.is() )
+ {
+ rOutGraphic = Image().GetXGraphic();
+ return sal_False;
+ }
+
+ // Check size and scale it
+ Image aImage( rInGraphic );
+ Size aSize = aImage.GetSizePixel();
+ bool bMustScale( false );
+
+ if ( nImageType == ImageType_Color_Large )
+ bMustScale = ( aSize != aLargeSize );
+ else
+ bMustScale = ( aSize != aNormSize );
+
+ if ( bMustScale )
+ {
+ BitmapEx aBitmap = aImage.GetBitmapEx();
+ aBitmap.Scale( aNormSize );
+ aImage = Image( aBitmap );
+ rOutGraphic = aImage.GetXGraphic();
+ }
+ else
+ rOutGraphic = rInGraphic;
+ return sal_True;
+}
+
+static sal_Int16 implts_convertImageTypeToIndex( sal_Int16 nImageType )
+{
+ sal_Int16 nIndex( 0 );
+ if ( nImageType & ::com::sun::star::ui::ImageType::SIZE_LARGE )
+ nIndex += 1;
+ return nIndex;
+}
+
+ImageList* ImageManagerImpl::implts_getUserImageList( ImageType nImageType )
+{
+ ResetableGuard aGuard( m_aLock );
+ if ( !m_pUserImageList[nImageType] )
+ implts_loadUserImages( nImageType, m_xUserImageStorage, m_xUserBitmapsStorage );
+
+ return m_pUserImageList[nImageType];
+}
+
+void ImageManagerImpl::implts_initialize()
+{
+ // Initialize the top-level structures with the storage data
+ if ( m_xUserConfigStorage.is() )
+ {
+ long nModes = m_bReadOnly ? ElementModes::READ : ElementModes::READWRITE;
+
+ try
+ {
+ m_xUserImageStorage = m_xUserConfigStorage->openStorageElement( OUString(RTL_CONSTASCII_USTRINGPARAM( IMAGE_FOLDER )),
+ nModes );
+ if ( m_xUserImageStorage.is() )
+ {
+ m_xUserBitmapsStorage = m_xUserImageStorage->openStorageElement( OUString(RTL_CONSTASCII_USTRINGPARAM( BITMAPS_FOLDER )),
+ nModes );
+ }
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+ }
+}
+
+sal_Bool ImageManagerImpl::implts_loadUserImages(
+ ImageType nImageType,
+ const uno::Reference< XStorage >& xUserImageStorage,
+ const uno::Reference< XStorage >& xUserBitmapsStorage )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( xUserImageStorage.is() && xUserBitmapsStorage.is() )
+ {
+ try
+ {
+ uno::Reference< XStream > xStream = xUserImageStorage->openStreamElement( rtl::OUString::createFromAscii( IMAGELIST_XML_FILE[nImageType] ),
+ ElementModes::READ );
+ uno::Reference< XInputStream > xInputStream = xStream->getInputStream();
+
+ ImageListsDescriptor aUserImageListInfo;
+ ImagesConfiguration::LoadImages( m_xServiceManager,
+ xInputStream,
+ aUserImageListInfo );
+ if (( aUserImageListInfo.pImageList != 0 ) &&
+ ( aUserImageListInfo.pImageList->Count() > 0 ))
+ {
+ ImageListItemDescriptor* pList = aUserImageListInfo.pImageList->GetObject(0);
+ sal_Int32 nCount = pList->pImageItemList->Count();
+ std::vector< OUString > aUserImagesVector;
+ aUserImagesVector.reserve(nCount);
+ for ( sal_uInt16 i=0; i < nCount; i++ )
+ {
+ const ImageItemDescriptor* pItem = pList->pImageItemList->GetObject(i);
+ aUserImagesVector.push_back( pItem->aCommandURL );
+ }
+
+ uno::Reference< XStream > xBitmapStream = xUserBitmapsStorage->openStreamElement(
+ rtl::OUString::createFromAscii( BITMAP_FILE_NAMES[nImageType] ),
+ ElementModes::READ );
+
+ if ( xBitmapStream.is() )
+ {
+ SvStream* pSvStream( 0 );
+ BitmapEx aUserBitmap;
+ {
+ pSvStream = utl::UcbStreamHelper::CreateStream( xBitmapStream );
+ vcl::PNGReader aPngReader( *pSvStream );
+ aUserBitmap = aPngReader.Read();
+ }
+ delete pSvStream;
+
+ // Delete old image list and create a new one from the read bitmap
+ delete m_pUserImageList[nImageType];
+ m_pUserImageList[nImageType] = new ImageList();
+ m_pUserImageList[nImageType]->InsertFromHorizontalStrip
+ ( aUserBitmap, aUserImagesVector );
+ return sal_True;
+ }
+ }
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+ }
+
+ // Destroy old image list - create a new empty one
+ delete m_pUserImageList[nImageType];
+ m_pUserImageList[nImageType] = new ImageList;
+
+ return sal_True;
+}
+
+sal_Bool ImageManagerImpl::implts_storeUserImages(
+ ImageType nImageType,
+ const uno::Reference< XStorage >& xUserImageStorage,
+ const uno::Reference< XStorage >& xUserBitmapsStorage )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bModified )
+ {
+ ImageList* pImageList = implts_getUserImageList( nImageType );
+ if ( pImageList->GetImageCount() > 0 )
+ {
+ ImageListsDescriptor aUserImageListInfo;
+ aUserImageListInfo.pImageList = new ImageListDescriptor;
+
+ ImageListItemDescriptor* pList = new ImageListItemDescriptor;
+ aUserImageListInfo.pImageList->Insert( pList, 0 );
+
+ pList->pImageItemList = new ImageItemListDescriptor;
+ for ( sal_uInt16 i=0; i < pImageList->GetImageCount(); i++ )
+ {
+ ImageItemDescriptor* pItem = new ::framework::ImageItemDescriptor;
+
+ pItem->nIndex = i;
+ pItem->aCommandURL = pImageList->GetImageName( i );
+ pList->pImageItemList->Insert( pItem, pList->pImageItemList->Count() );
+ }
+
+ pList->aURL = String::CreateFromAscii("Bitmaps/");
+ pList->aURL += String::CreateFromAscii( BITMAP_FILE_NAMES[nImageType] );
+
+ uno::Reference< XTransactedObject > xTransaction;
+ uno::Reference< XOutputStream > xOutputStream;
+ uno::Reference< XStream > xStream = xUserImageStorage->openStreamElement( rtl::OUString::createFromAscii( IMAGELIST_XML_FILE[nImageType] ),
+ ElementModes::WRITE|ElementModes::TRUNCATE );
+ if ( xStream.is() )
+ {
+ uno::Reference< XStream > xBitmapStream =
+ xUserBitmapsStorage->openStreamElement( rtl::OUString::createFromAscii( BITMAP_FILE_NAMES[nImageType] ),
+ ElementModes::WRITE|ElementModes::TRUNCATE );
+ if ( xBitmapStream.is() )
+ {
+ SvStream* pSvStream = utl::UcbStreamHelper::CreateStream( xBitmapStream );
+ {
+ vcl::PNGWriter aPngWriter( pImageList->GetAsHorizontalStrip() );
+ aPngWriter.Write( *pSvStream );
+ }
+ delete pSvStream;
+
+ // Commit user bitmaps storage
+ xTransaction = uno::Reference< XTransactedObject >( xUserBitmapsStorage, UNO_QUERY );
+ if ( xTransaction.is() )
+ xTransaction->commit();
+ }
+
+ xOutputStream = xStream->getOutputStream();
+ if ( xOutputStream.is() )
+ ImagesConfiguration::StoreImages( m_xServiceManager, xOutputStream, aUserImageListInfo );
+
+ // Commit user image storage
+ xTransaction = uno::Reference< XTransactedObject >( xUserImageStorage, UNO_QUERY );
+ if ( xTransaction.is() )
+ xTransaction->commit();
+ }
+
+ return sal_True;
+ }
+ else
+ {
+ // Remove the streams from the storage, if we have no data. We have to catch
+ // the NoSuchElementException as it can be possible that there is no stream at all!
+ try
+ {
+ xUserImageStorage->removeElement( rtl::OUString::createFromAscii( IMAGELIST_XML_FILE[nImageType] ));
+ }
+ catch ( ::com::sun::star::container::NoSuchElementException& )
+ {
+ }
+
+ try
+ {
+ xUserBitmapsStorage->removeElement( rtl::OUString::createFromAscii( BITMAP_FILE_NAMES[nImageType] ));
+ }
+ catch ( ::com::sun::star::container::NoSuchElementException& )
+ {
+ }
+
+ uno::Reference< XTransactedObject > xTransaction;
+
+ // Commit user image storage
+ xTransaction = uno::Reference< XTransactedObject >( xUserImageStorage, UNO_QUERY );
+ if ( xTransaction.is() )
+ xTransaction->commit();
+
+ // Commit user bitmaps storage
+ xTransaction = uno::Reference< XTransactedObject >( xUserBitmapsStorage, UNO_QUERY );
+ if ( xTransaction.is() )
+ xTransaction->commit();
+
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+const rtl::Reference< GlobalImageList >& ImageManagerImpl::implts_getGlobalImageList()
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_pGlobalImageList.is() )
+ m_pGlobalImageList = getGlobalImageList( m_xServiceManager );
+ return m_pGlobalImageList;
+}
+
+CmdImageList* ImageManagerImpl::implts_getDefaultImageList()
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_pDefaultImageList )
+ m_pDefaultImageList = new CmdImageList( m_xServiceManager, m_aModuleIdentifier );
+
+ return m_pDefaultImageList;
+}
+
+ImageManagerImpl::ImageManagerImpl( const uno::Reference< XMultiServiceFactory >& xServiceManager,::cppu::OWeakObject* pOwner,bool _bUseGlobal ) :
+ ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_xServiceManager( xServiceManager )
+ , m_pOwner(pOwner)
+ , m_pDefaultImageList( 0 )
+ , m_aXMLPostfix( RTL_CONSTASCII_USTRINGPARAM( ".xml" ))
+ , m_aResourceString( RTL_CONSTASCII_USTRINGPARAM( ModuleImageList ))
+ , m_aListenerContainer( m_aLock.getShareableOslMutex() )
+ , m_bUseGlobal(_bUseGlobal)
+ , m_bReadOnly( true )
+ , m_bInitialized( false )
+ , m_bModified( false )
+ , m_bConfigRead( false )
+ , m_bDisposed( false )
+{
+ for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
+ {
+ m_pUserImageList[n] = 0;
+ m_bUserImageListModified[n] = false;
+ }
+}
+
+ImageManagerImpl::~ImageManagerImpl()
+{
+ clear();
+}
+
+void ImageManagerImpl::dispose()
+{
+ uno::Reference< uno::XInterface > xOwner(static_cast< OWeakObject* >(m_pOwner));
+ css::lang::EventObject aEvent( xOwner );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ {
+ ResetableGuard aGuard( m_aLock );
+ m_xUserConfigStorage.clear();
+ m_xUserImageStorage.clear();
+ m_xUserRootCommit.clear();
+ m_bConfigRead = false;
+ m_bModified = false;
+ m_bDisposed = true;
+
+ // delete user and default image list on dispose
+ for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
+ {
+ delete m_pUserImageList[n];
+ m_pUserImageList[n] = 0;
+ }
+ delete m_pDefaultImageList;
+ m_pDefaultImageList = 0;
+ }
+
+}
+void ImageManagerImpl::addEventListener( const uno::Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const uno::Reference< XEventListener >* ) NULL ), xListener );
+}
+
+void ImageManagerImpl::removeEventListener( const uno::Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const uno::Reference< XEventListener >* ) NULL ), xListener );
+}
+
+// XInitialization
+void ImageManagerImpl::initialize( const Sequence< Any >& aArguments )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bInitialized )
+ {
+ for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
+ {
+ PropertyValue aPropValue;
+ if ( aArguments[n] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("UserConfigStorage")) )
+ {
+ aPropValue.Value >>= m_xUserConfigStorage;
+ }
+ else if ( aPropValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ModuleIdentifier")) )
+ {
+ aPropValue.Value >>= m_aModuleIdentifier;
+ }
+ else if ( aPropValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("UserRootCommit")) )
+ {
+ aPropValue.Value >>= m_xUserRootCommit;
+ }
+ }
+ }
+
+ if ( m_xUserConfigStorage.is() )
+ {
+ uno::Reference< XPropertySet > xPropSet( m_xUserConfigStorage, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ long nOpenMode = 0;
+ if ( xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))) >>= nOpenMode )
+ m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
+ }
+ }
+
+ implts_initialize();
+
+ m_bInitialized = true;
+ }
+}
+
+// XImageManagerImpl
+void ImageManagerImpl::reset()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ std::vector< OUString > aUserImageNames;
+
+ for ( sal_Int32 i = 0; i < ImageType_COUNT; i++ )
+ {
+ aUserImageNames.clear();
+ ImageList* pImageList = implts_getUserImageList( ImageType(i));
+ pImageList->GetImageNames( aUserImageNames );
+
+ Sequence< rtl::OUString > aRemoveList( aUserImageNames.size() );
+ const sal_uInt32 nCount = aUserImageNames.size();
+ for ( sal_uInt32 j = 0; j < nCount; j++ )
+ aRemoveList[j] = aUserImageNames[j];
+
+ // Remove images
+ removeImages( sal_Int16( i ), aRemoveList );
+ m_bUserImageListModified[i] = true;
+ }
+
+ m_bModified = sal_True;
+}
+
+Sequence< ::rtl::OUString > ImageManagerImpl::getAllImageNames( ::sal_Int16 nImageType )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ ImageNameMap aImageCmdNameMap;
+
+ sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType );
+
+ sal_uInt32 i( 0 );
+ if ( m_bUseGlobal )
+ {
+ rtl::Reference< GlobalImageList > rGlobalImageList = implts_getGlobalImageList();
+
+ const std::vector< OUString >& rGlobalImageNameVector = rGlobalImageList->getImageCommandNames();
+ const sal_uInt32 nGlobalCount = rGlobalImageNameVector.size();
+ for ( i = 0; i < nGlobalCount; i++ )
+ aImageCmdNameMap.insert( ImageNameMap::value_type( rGlobalImageNameVector[i], sal_True ));
+
+ const std::vector< OUString >& rModuleImageNameVector = implts_getDefaultImageList()->getImageCommandNames();
+ const sal_uInt32 nModuleCount = rModuleImageNameVector.size();
+ for ( i = 0; i < nModuleCount; i++ )
+ aImageCmdNameMap.insert( ImageNameMap::value_type( rModuleImageNameVector[i], sal_True ));
+ }
+
+ ImageList* pImageList = implts_getUserImageList( ImageType( nIndex ));
+ std::vector< OUString > rUserImageNames;
+ pImageList->GetImageNames( rUserImageNames );
+ const sal_uInt32 nUserCount = rUserImageNames.size();
+ for ( i = 0; i < nUserCount; i++ )
+ aImageCmdNameMap.insert( ImageNameMap::value_type( rUserImageNames[i], sal_True ));
+
+ Sequence< OUString > aImageNameSeq( aImageCmdNameMap.size() );
+ ImageNameMap::const_iterator pIter;
+ i = 0;
+ for ( pIter = aImageCmdNameMap.begin(); pIter != aImageCmdNameMap.end(); ++pIter )
+ aImageNameSeq[i++] = pIter->first;
+
+ return aImageNameSeq;
+}
+
+::sal_Bool ImageManagerImpl::hasImage( ::sal_Int16 nImageType, const ::rtl::OUString& aCommandURL )
+throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE ))
+ throw IllegalArgumentException();
+
+ sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType );
+ if ( m_bUseGlobal && implts_getGlobalImageList()->hasImage( nIndex, aCommandURL ))
+ return sal_True;
+ else
+ {
+ if ( m_bUseGlobal && implts_getDefaultImageList()->hasImage( nIndex, aCommandURL ))
+ return sal_True;
+ else
+ {
+ // User layer
+ ImageList* pImageList = implts_getUserImageList( ImageType( nIndex ));
+ if ( pImageList )
+ return ( pImageList->GetImagePos( aCommandURL ) != IMAGELIST_IMAGE_NOTFOUND );
+ }
+ }
+
+ return sal_False;
+}
+
+Sequence< uno::Reference< XGraphic > > ImageManagerImpl::getImages(
+ ::sal_Int16 nImageType,
+ const Sequence< ::rtl::OUString >& aCommandURLSequence )
+throw ( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE ))
+ throw IllegalArgumentException();
+
+ Sequence< uno::Reference< XGraphic > > aGraphSeq( aCommandURLSequence.getLength() );
+
+ const rtl::OUString* aStrArray = aCommandURLSequence.getConstArray();
+
+ sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType );
+ rtl::Reference< GlobalImageList > rGlobalImageList;
+ CmdImageList* pDefaultImageList = NULL;
+ if ( m_bUseGlobal )
+ {
+ rGlobalImageList = implts_getGlobalImageList();
+ pDefaultImageList = implts_getDefaultImageList();
+ }
+ ImageList* pUserImageList = implts_getUserImageList( ImageType( nIndex ));
+
+ // We have to search our image list in the following order:
+ // 1. user image list (read/write)
+ // 2. module image list (read)
+ // 3. global image list (read)
+ for ( sal_Int32 n = 0; n < aCommandURLSequence.getLength(); n++ )
+ {
+ Image aImage = pUserImageList->GetImage( aStrArray[n] );
+ if ( !aImage && m_bUseGlobal )
+ {
+ aImage = pDefaultImageList->getImageFromCommandURL( nIndex, aStrArray[n] );
+ if ( !aImage )
+ aImage = rGlobalImageList->getImageFromCommandURL( nIndex, aStrArray[n] );
+ }
+
+ aGraphSeq[n] = aImage.GetXGraphic();
+ }
+
+ return aGraphSeq;
+}
+
+void ImageManagerImpl::replaceImages(
+ ::sal_Int16 nImageType,
+ const Sequence< ::rtl::OUString >& aCommandURLSequence,
+ const Sequence< uno::Reference< XGraphic > >& aGraphicsSequence )
+throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::IllegalAccessException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ CmdToXGraphicNameAccess* pInsertedImages( 0 );
+ CmdToXGraphicNameAccess* pReplacedImages( 0 );
+
+ {
+ ResetableGuard aLock( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if (( aCommandURLSequence.getLength() != aGraphicsSequence.getLength() ) ||
+ (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE )))
+ throw IllegalArgumentException();
+
+ if ( m_bReadOnly )
+ throw IllegalAccessException();
+
+ sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType );
+ ImageList* pImageList = implts_getUserImageList( ImageType( nIndex ));
+
+ uno::Reference< XGraphic > xGraphic;
+ for ( sal_Int32 i = 0; i < aCommandURLSequence.getLength(); i++ )
+ {
+ // Check size and scale. If we don't have any graphics ignore it
+ if ( !implts_checkAndScaleGraphic( xGraphic, aGraphicsSequence[i], nIndex ))
+ continue;
+
+ sal_uInt16 nPos = pImageList->GetImagePos( aCommandURLSequence[i] );
+ if ( nPos == IMAGELIST_IMAGE_NOTFOUND )
+ {
+ pImageList->AddImage( aCommandURLSequence[i], xGraphic );
+ if ( !pInsertedImages )
+ pInsertedImages = new CmdToXGraphicNameAccess();
+ pInsertedImages->addElement( aCommandURLSequence[i], xGraphic );
+ }
+ else
+ {
+ pImageList->ReplaceImage( aCommandURLSequence[i], xGraphic );
+ if ( !pReplacedImages )
+ pReplacedImages = new CmdToXGraphicNameAccess();
+ pReplacedImages->addElement( aCommandURLSequence[i], xGraphic );
+ }
+ }
+
+ if (( pInsertedImages != 0 ) || ( pReplacedImages != 0 ))
+ {
+ m_bModified = sal_True;
+ m_bUserImageListModified[nIndex] = true;
+ }
+ }
+
+ uno::Reference< uno::XInterface > xOwner(static_cast< OWeakObject* >(m_pOwner));
+ // Notify listeners
+ if ( pInsertedImages != 0 )
+ {
+ ConfigurationEvent aInsertEvent;
+ aInsertEvent.aInfo <<= nImageType;
+ aInsertEvent.Accessor <<= xOwner;
+ aInsertEvent.Source = xOwner;
+ aInsertEvent.ResourceURL = m_aResourceString;
+ aInsertEvent.Element = uno::makeAny( uno::Reference< XNameAccess >(
+ static_cast< OWeakObject *>( pInsertedImages ), UNO_QUERY ));
+ implts_notifyContainerListener( aInsertEvent, NotifyOp_Insert );
+ }
+ if ( pReplacedImages != 0 )
+ {
+ ConfigurationEvent aReplaceEvent;
+ aReplaceEvent.aInfo <<= nImageType;
+ aReplaceEvent.Accessor <<= xOwner;
+ aReplaceEvent.Source = xOwner;
+ aReplaceEvent.ResourceURL = m_aResourceString;
+ aReplaceEvent.ReplacedElement = Any();
+ aReplaceEvent.Element = uno::makeAny( uno::Reference< XNameAccess >(
+ static_cast< OWeakObject *>( pReplacedImages ), UNO_QUERY ));
+ implts_notifyContainerListener( aReplaceEvent, NotifyOp_Replace );
+ }
+}
+
+void ImageManagerImpl::removeImages( ::sal_Int16 nImageType, const Sequence< ::rtl::OUString >& aCommandURLSequence )
+throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::IllegalAccessException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ CmdToXGraphicNameAccess* pRemovedImages( 0 );
+ CmdToXGraphicNameAccess* pReplacedImages( 0 );
+
+ {
+ ResetableGuard aLock( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if (( nImageType < 0 ) || ( nImageType > MAX_IMAGETYPE_VALUE ))
+ throw IllegalArgumentException();
+
+ if ( m_bReadOnly )
+ throw IllegalAccessException();
+
+ sal_Int16 nIndex = implts_convertImageTypeToIndex( nImageType );
+ rtl::Reference< GlobalImageList > rGlobalImageList;
+ CmdImageList* pDefaultImageList = NULL;
+ if ( m_bUseGlobal )
+ {
+ rGlobalImageList = implts_getGlobalImageList();
+ pDefaultImageList = implts_getDefaultImageList();
+ }
+ ImageList* pImageList = implts_getUserImageList( ImageType( nIndex ));
+ uno::Reference< XGraphic > xEmptyGraphic( Image().GetXGraphic() );
+
+ for ( sal_Int32 i = 0; i < aCommandURLSequence.getLength(); i++ )
+ {
+ sal_uInt16 nPos = pImageList->GetImagePos( aCommandURLSequence[i] );
+ if ( nPos != IMAGELIST_IMAGE_NOTFOUND )
+ {
+ Image aImage = pImageList->GetImage( nPos );
+ sal_uInt16 nId = pImageList->GetImageId( nPos );
+ pImageList->RemoveImage( nId );
+
+ if ( m_bUseGlobal )
+ {
+ // Check, if we have a image in our module/global image list. If we find one =>
+ // this is a replace instead of a remove operation!
+ Image aNewImage = pDefaultImageList->getImageFromCommandURL( nIndex, aCommandURLSequence[i] );
+ if ( !aNewImage )
+ aNewImage = rGlobalImageList->getImageFromCommandURL( nIndex, aCommandURLSequence[i] );
+ if ( !aNewImage )
+ {
+ if ( !pRemovedImages )
+ pRemovedImages = new CmdToXGraphicNameAccess();
+ pRemovedImages->addElement( aCommandURLSequence[i], xEmptyGraphic );
+ }
+ else
+ {
+ if ( !pReplacedImages )
+ pReplacedImages = new CmdToXGraphicNameAccess();
+ pReplacedImages->addElement( aCommandURLSequence[i], aNewImage.GetXGraphic() );
+ }
+ } // if ( m_bUseGlobal )
+ else
+ {
+ if ( !pRemovedImages )
+ pRemovedImages = new CmdToXGraphicNameAccess();
+ pRemovedImages->addElement( aCommandURLSequence[i], xEmptyGraphic );
+ }
+ }
+ }
+
+ if (( pReplacedImages != 0 ) || ( pRemovedImages != 0 ))
+ {
+ m_bModified = sal_True;
+ m_bUserImageListModified[nIndex] = true;
+ }
+ }
+
+ // Notify listeners
+ uno::Reference< uno::XInterface > xOwner(static_cast< OWeakObject* >(m_pOwner));
+ if ( pRemovedImages != 0 )
+ {
+ ConfigurationEvent aRemoveEvent;
+ aRemoveEvent.aInfo = uno::makeAny( nImageType );
+ aRemoveEvent.Accessor = uno::makeAny( xOwner );
+ aRemoveEvent.Source = xOwner;
+ aRemoveEvent.ResourceURL = m_aResourceString;
+ aRemoveEvent.Element = uno::makeAny( uno::Reference< XNameAccess >(
+ static_cast< OWeakObject *>( pRemovedImages ), UNO_QUERY ));
+ implts_notifyContainerListener( aRemoveEvent, NotifyOp_Remove );
+ }
+ if ( pReplacedImages != 0 )
+ {
+ ConfigurationEvent aReplaceEvent;
+ aReplaceEvent.aInfo = uno::makeAny( nImageType );
+ aReplaceEvent.Accessor = uno::makeAny( xOwner );
+ aReplaceEvent.Source = xOwner;
+ aReplaceEvent.ResourceURL = m_aResourceString;
+ aReplaceEvent.ReplacedElement = Any();
+ aReplaceEvent.Element = uno::makeAny( uno::Reference< XNameAccess >(
+ static_cast< OWeakObject *>( pReplacedImages ), UNO_QUERY ));
+ implts_notifyContainerListener( aReplaceEvent, NotifyOp_Replace );
+ }
+}
+
+void ImageManagerImpl::insertImages( ::sal_Int16 nImageType, const Sequence< ::rtl::OUString >& aCommandURLSequence, const Sequence< uno::Reference< XGraphic > >& aGraphicSequence )
+throw ( ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::IllegalAccessException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ replaceImages(nImageType,aCommandURLSequence,aGraphicSequence);
+}
+
+
+// XUIConfigurationPersistence
+void ImageManagerImpl::reload()
+throw ( ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ CommandMap aOldUserCmdImageSet;
+ std::vector< rtl::OUString > aNewUserCmdImageSet;
+
+ if ( m_bModified )
+ {
+ for ( sal_Int16 i = 0; i < sal_Int16( ImageType_COUNT ); i++ )
+ {
+ if ( !m_bDisposed && m_bUserImageListModified[i] )
+ {
+ std::vector< rtl::OUString > aOldUserCmdImageVector;
+ ImageList* pImageList = implts_getUserImageList( (ImageType)i );
+ pImageList->GetImageNames( aOldUserCmdImageVector );
+
+ // Fill hash map to speed up search afterwards
+ sal_uInt32 j( 0 );
+ const sal_uInt32 nOldCount = aOldUserCmdImageVector.size();
+ for ( j = 0; j < nOldCount; j++ )
+ aOldUserCmdImageSet.insert( CommandMap::value_type( aOldUserCmdImageVector[j], false ));
+
+ // Attention: This can make the old image list pointer invalid!
+ implts_loadUserImages( (ImageType)i, m_xUserImageStorage, m_xUserBitmapsStorage );
+ pImageList = implts_getUserImageList( (ImageType)i );
+ pImageList->GetImageNames( aNewUserCmdImageSet );
+
+ CmdToXGraphicNameAccess* pInsertedImages( 0 );
+ CmdToXGraphicNameAccess* pReplacedImages( 0 );
+ CmdToXGraphicNameAccess* pRemovedImages( 0 );
+
+ const sal_uInt32 nNewCount = aNewUserCmdImageSet.size();
+ for ( j = 0; j < nNewCount; j++ )
+ {
+ CommandMap::iterator pIter = aOldUserCmdImageSet.find( aNewUserCmdImageSet[j] );
+ if ( pIter != aOldUserCmdImageSet.end() )
+ {
+ pIter->second = true; // mark entry as replaced
+ if ( !pReplacedImages )
+ pReplacedImages = new CmdToXGraphicNameAccess();
+ pReplacedImages->addElement( aNewUserCmdImageSet[j],
+ pImageList->GetImage( aNewUserCmdImageSet[j] ).GetXGraphic() );
+ }
+ else
+ {
+ if ( !pInsertedImages )
+ pInsertedImages = new CmdToXGraphicNameAccess();
+ pInsertedImages->addElement( aNewUserCmdImageSet[j],
+ pImageList->GetImage( aNewUserCmdImageSet[j] ).GetXGraphic() );
+ }
+ }
+
+ // Search map for unmarked entries => they have been removed from the user list
+ // through this reload operation.
+ // We have to search the module and global image list!
+ rtl::Reference< GlobalImageList > rGlobalImageList;
+ CmdImageList* pDefaultImageList = NULL;
+ if ( m_bUseGlobal )
+ {
+ rGlobalImageList = implts_getGlobalImageList();
+ pDefaultImageList = implts_getDefaultImageList();
+ }
+ uno::Reference< XGraphic > xEmptyGraphic( Image().GetXGraphic() );
+ CommandMap::const_iterator pIter = aOldUserCmdImageSet.begin();
+ while ( pIter != aOldUserCmdImageSet.end() )
+ {
+ if ( !pIter->second )
+ {
+ if ( m_bUseGlobal )
+ {
+ Image aImage = pDefaultImageList->getImageFromCommandURL( i, pIter->first );
+ if ( !aImage )
+ aImage = rGlobalImageList->getImageFromCommandURL( i, pIter->first );
+
+ if ( !aImage )
+ {
+ // No image in the module/global image list => remove user image
+ if ( !pRemovedImages )
+ pRemovedImages = new CmdToXGraphicNameAccess();
+ pRemovedImages->addElement( pIter->first, xEmptyGraphic );
+ }
+ else
+ {
+ // Image has been found in the module/global image list => replace user image
+ if ( !pReplacedImages )
+ pReplacedImages = new CmdToXGraphicNameAccess();
+ pReplacedImages->addElement( pIter->first, aImage.GetXGraphic() );
+ }
+ } // if ( m_bUseGlobal )
+ else
+ {
+ // No image in the user image list => remove user image
+ if ( !pRemovedImages )
+ pRemovedImages = new CmdToXGraphicNameAccess();
+ pRemovedImages->addElement( pIter->first, xEmptyGraphic );
+ }
+ }
+ ++pIter;
+ }
+
+ aGuard.unlock();
+
+ // Now notify our listeners. Unlock mutex to prevent deadlocks
+ uno::Reference< uno::XInterface > xOwner(static_cast< OWeakObject* >(m_pOwner));
+ if ( pInsertedImages != 0 )
+ {
+ ConfigurationEvent aInsertEvent;
+ aInsertEvent.aInfo = uno::makeAny( i );
+ aInsertEvent.Accessor = uno::makeAny( xOwner );
+ aInsertEvent.Source = xOwner;
+ aInsertEvent.ResourceURL = m_aResourceString;
+ aInsertEvent.Element = uno::makeAny( uno::Reference< XNameAccess >(
+ static_cast< OWeakObject *>( pInsertedImages ), UNO_QUERY ));
+ implts_notifyContainerListener( aInsertEvent, NotifyOp_Insert );
+ }
+ if ( pReplacedImages != 0 )
+ {
+ ConfigurationEvent aReplaceEvent;
+ aReplaceEvent.aInfo = uno::makeAny( i );
+ aReplaceEvent.Accessor = uno::makeAny( xOwner );
+ aReplaceEvent.Source = xOwner;
+ aReplaceEvent.ResourceURL = m_aResourceString;
+ aReplaceEvent.ReplacedElement = Any();
+ aReplaceEvent.Element = uno::makeAny( uno::Reference< XNameAccess >(
+ static_cast< OWeakObject *>( pReplacedImages ), UNO_QUERY ));
+ implts_notifyContainerListener( aReplaceEvent, NotifyOp_Replace );
+ }
+ if ( pRemovedImages != 0 )
+ {
+ ConfigurationEvent aRemoveEvent;
+ aRemoveEvent.aInfo = uno::makeAny( i );
+ aRemoveEvent.Accessor = uno::makeAny( xOwner );
+ aRemoveEvent.Source = xOwner;
+ aRemoveEvent.ResourceURL = m_aResourceString;
+ aRemoveEvent.Element = uno::makeAny( uno::Reference< XNameAccess >(
+ static_cast< OWeakObject *>( pRemovedImages ), UNO_QUERY ));
+ implts_notifyContainerListener( aRemoveEvent, NotifyOp_Remove );
+ }
+
+ aGuard.lock();
+ }
+ }
+ }
+}
+
+void ImageManagerImpl::store()
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_bModified )
+ {
+ sal_Bool bWritten( sal_False );
+ for ( sal_Int32 i = 0; i < ImageType_COUNT; i++ )
+ {
+ sal_Bool bSuccess = implts_storeUserImages( ImageType(i), m_xUserImageStorage, m_xUserBitmapsStorage );
+ if ( bSuccess )
+ bWritten = sal_True;
+ m_bUserImageListModified[i] = false;
+ }
+
+ if ( bWritten &&
+ m_xUserConfigStorage.is() )
+ {
+ uno::Reference< XTransactedObject > xUserConfigStorageCommit( m_xUserConfigStorage, UNO_QUERY );
+ if ( xUserConfigStorageCommit.is() )
+ xUserConfigStorageCommit->commit();
+ if ( m_xUserRootCommit.is() )
+ m_xUserRootCommit->commit();
+ }
+
+ m_bModified = sal_False;
+ }
+}
+
+void ImageManagerImpl::storeToStorage( const uno::Reference< XStorage >& Storage )
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_bModified && Storage.is() )
+ {
+ long nModes = ElementModes::READWRITE;
+
+ uno::Reference< XStorage > xUserImageStorage = Storage->openStorageElement( OUString(RTL_CONSTASCII_USTRINGPARAM( IMAGE_FOLDER )),
+ nModes );
+ if ( xUserImageStorage.is() )
+ {
+ uno::Reference< XStorage > xUserBitmapsStorage = xUserImageStorage->openStorageElement( OUString(RTL_CONSTASCII_USTRINGPARAM( BITMAPS_FOLDER )),
+ nModes );
+ for ( sal_Int32 i = 0; i < ImageType_COUNT; i++ )
+ {
+ implts_getUserImageList( (ImageType)i );
+ implts_storeUserImages( (ImageType)i, xUserImageStorage, xUserBitmapsStorage );
+ }
+
+ uno::Reference< XTransactedObject > xTransaction( Storage, UNO_QUERY );
+ if ( xTransaction.is() )
+ xTransaction->commit();
+ }
+ }
+}
+
+sal_Bool ImageManagerImpl::isModified()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+ return m_bModified;
+}
+
+sal_Bool ImageManagerImpl::isReadOnly() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+ return m_bReadOnly;
+}
+// XUIConfiguration
+void ImageManagerImpl::addConfigurationListener( const uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const uno::Reference< XUIConfigurationListener >* ) NULL ), xListener );
+}
+
+void ImageManagerImpl::removeConfigurationListener( const uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const uno::Reference< XUIConfigurationListener >* ) NULL ), xListener );
+}
+
+
+void ImageManagerImpl::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp )
+{
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer(
+ ::getCppuType( ( const css::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >*) NULL ) );
+ if ( pContainer != NULL )
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
+ while ( pIterator.hasMoreElements() )
+ {
+ try
+ {
+ switch ( eOp )
+ {
+ case NotifyOp_Replace:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementReplaced( aEvent );
+ break;
+ case NotifyOp_Insert:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementInserted( aEvent );
+ break;
+ case NotifyOp_Remove:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementRemoved( aEvent );
+ break;
+ }
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+}
+void ImageManagerImpl::clear()
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if (!m_pUserImageList)
+ return;
+
+ for ( sal_Int32 n = 0; n < ImageType_COUNT; n++ )
+ {
+ delete m_pUserImageList[n];
+ m_pUserImageList[n] = 0;
+ }
+}
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/imagemanagerimpl.hxx b/framework/source/uiconfiguration/imagemanagerimpl.hxx
new file mode 100644
index 000000000000..4e6d123c3211
--- /dev/null
+++ b/framework/source/uiconfiguration/imagemanagerimpl.hxx
@@ -0,0 +1,225 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_UICONFIGURATION_IMAGEMANAGERIMPL_HXX_
+#define __FRAMEWORK_UICONFIGURATION_IMAGEMANAGERIMPL_HXX_
+
+
+/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
+ with solaris headers ...
+*/
+#include <vector>
+#include <list>
+#include <boost/unordered_map.hpp>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/threadhelpbase.hxx>
+#include <macros/generic.hxx>
+#include <macros/xinterface.hxx>
+#include <macros/xtypeprovider.hxx>
+#include <macros/xserviceinfo.hxx>
+#include <stdtypes.h>
+#include <uiconfiguration/imagetype.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+#include <com/sun/star/ui/XUIConfigurationStorage.hpp>
+#include <com/sun/star/ui/XUIConfiguration.hpp>
+#include <com/sun/star/ui/XImageManager.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/ConfigurationEvent.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/ui/XImageManager.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <rtl/ustring.hxx>
+
+#include <vcl/image.hxx>
+#include <tools/color.hxx>
+#include <rtl/ref.hxx>
+
+#include <vector>
+
+namespace framework
+{
+ class CmdImageList
+ {
+ public:
+ CmdImageList( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager,
+ const ::rtl::OUString& aModuleIdentifier );
+ virtual ~CmdImageList();
+
+ virtual Image getImageFromCommandURL( sal_Int16 nImageType, const rtl::OUString& rCommandURL );
+ virtual bool hasImage( sal_Int16 nImageType, const rtl::OUString& rCommandURL );
+ virtual ::std::vector< rtl::OUString >& getImageNames();
+ virtual ::std::vector< rtl::OUString >& getImageCommandNames();
+
+ protected:
+ void impl_fillCommandToImageNameMap();
+ ImageList* impl_getImageList( sal_Int16 nImageType );
+ std::vector< ::rtl::OUString >& impl_getImageNameVector();
+ std::vector< ::rtl::OUString >& impl_getImageCommandNameVector();
+
+ private:
+ sal_Bool m_bVectorInit;
+ rtl::OUString m_aModuleIdentifier;
+ ImageList* m_pImageList[ImageType_COUNT];
+ CommandToImageNameMap m_aCommandToImageNameMap;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager;
+ ::std::vector< rtl::OUString > m_aImageNameVector;
+ ::std::vector< rtl::OUString > m_aImageCommandNameVector;
+ sal_Int16 m_nSymbolsStyle;
+ };
+
+ class GlobalImageList : public CmdImageList, public rtl::IReference
+ {
+ public:
+ GlobalImageList( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager );
+ virtual ~GlobalImageList();
+
+ virtual Image getImageFromCommandURL( sal_Int16 nImageType, const rtl::OUString& rCommandURL );
+ virtual bool hasImage( sal_Int16 nImageType, const rtl::OUString& rCommandURL );
+ virtual ::std::vector< rtl::OUString >& getImageNames();
+ virtual ::std::vector< rtl::OUString >& getImageCommandNames();
+
+ // ÍReference
+ virtual oslInterlockedCount SAL_CALL acquire();
+ virtual oslInterlockedCount SAL_CALL release();
+
+ private:
+ oslInterlockedCount m_nRefCount;
+ };
+
+ class ImageManagerImpl : public ThreadHelpBase // Struct for right initalization of mutex member! Must be first of baseclasses.
+ {
+ public:
+
+ ImageManagerImpl(const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager
+ ,::cppu::OWeakObject *pOwner
+ ,bool _bUseGlobal);
+ ~ImageManagerImpl();
+
+ void dispose();
+ void initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments );
+ void addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ void removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XImageManager
+ void reset() throw (::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > getAllImageNames( ::sal_Int16 nImageType ) throw (::com::sun::star::uno::RuntimeException);
+ ::sal_Bool hasImage( ::sal_Int16 nImageType, const ::rtl::OUString& aCommandURL ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > > getImages( ::sal_Int16 nImageType, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aCommandURLSequence ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ void replaceImages( ::sal_Int16 nImageType, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aCommandURLSequence, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > >& aGraphicsSequence ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+ void removeImages( ::sal_Int16 nImageType, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aResourceURLSequence ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+ void insertImages( ::sal_Int16 nImageType, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aCommandURLSequence, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > >& aGraphicSequence ) throw (::com::sun::star::container::ElementExistException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+
+ // XUIConfiguration
+ void addConfigurationListener( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+ void removeConfigurationListener( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XUIConfigurationPersistence
+ void reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ void store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ void storeToStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ sal_Bool isModified() throw (::com::sun::star::uno::RuntimeException);
+ sal_Bool isReadOnly() throw (::com::sun::star::uno::RuntimeException);
+
+ void clear();
+
+ typedef boost::unordered_map< rtl::OUString,
+ sal_Bool,
+ OUStringHashCode,
+ ::std::equal_to< ::rtl::OUString > > ImageNameMap;
+
+ enum Layer
+ {
+ LAYER_DEFAULT,
+ LAYER_USERDEFINED,
+ LAYER_COUNT
+ };
+
+ enum NotifyOp
+ {
+ NotifyOp_Remove,
+ NotifyOp_Insert,
+ NotifyOp_Replace
+ };
+
+ typedef ::std::vector< ::com::sun::star::ui::ConfigurationEvent > ConfigEventNotifyContainer;
+
+ // private methods
+ void implts_initialize();
+ void implts_notifyContainerListener( const ::com::sun::star::ui::ConfigurationEvent& aEvent, NotifyOp eOp );
+ ImageList* implts_getUserImageList( ImageType nImageType );
+ sal_Bool implts_loadUserImages( ImageType nImageType,
+ const com::sun::star::uno::Reference< com::sun::star::embed::XStorage >& xUserImageStorage,
+ const com::sun::star::uno::Reference< com::sun::star::embed::XStorage >& xUserBitmapsStorage );
+ sal_Bool implts_storeUserImages( ImageType nImageType,
+ const com::sun::star::uno::Reference< com::sun::star::embed::XStorage >& xUserImageStorage,
+ const com::sun::star::uno::Reference< com::sun::star::embed::XStorage >& xUserBitmapsStorage );
+ const rtl::Reference< GlobalImageList >& implts_getGlobalImageList();
+ CmdImageList* implts_getDefaultImageList();
+
+
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage > m_xUserConfigStorage;
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage > m_xUserImageStorage;
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage > m_xUserBitmapsStorage;
+ com::sun::star::uno::Reference< com::sun::star::embed::XTransactedObject > m_xUserRootCommit;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xServiceManager;
+ ::cppu::OWeakObject* m_pOwner;
+ rtl::Reference< GlobalImageList > m_pGlobalImageList;
+ CmdImageList* m_pDefaultImageList;
+ rtl::OUString m_aXMLPostfix;
+ rtl::OUString m_aModuleIdentifier;
+ rtl::OUString m_aResourceString;
+ ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer; /// container for ALL Listener
+ ImageList* m_pUserImageList[ImageType_COUNT];
+ bool m_bUserImageListModified[ImageType_COUNT];
+ bool m_bUseGlobal;
+ bool m_bReadOnly;
+ bool m_bInitialized;
+ bool m_bModified;
+ bool m_bConfigRead;
+ bool m_bDisposed;
+ };
+}
+
+#endif // __FRAMEWORK_UICONFIGURATION_IMAGEMANAGERIMPL_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/moduleimagemanager.cxx b/framework/source/uiconfiguration/moduleimagemanager.cxx
new file mode 100644
index 000000000000..86540e1949fd
--- /dev/null
+++ b/framework/source/uiconfiguration/moduleimagemanager.cxx
@@ -0,0 +1,229 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <rtl/logfile.hxx>
+#include <uiconfiguration/moduleimagemanager.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <framework/imagesconfiguration.hxx>
+#include <uiconfiguration/graphicnameaccess.hxx>
+#include <services.h>
+#include "imagemanagerimpl.hxx"
+
+#include "properties.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/ui/ConfigurationEvent.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <com/sun/star/uri/XUriReference.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/mutex.hxx>
+#include <osl/file.hxx>
+#include <comphelper/sequence.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <vcl/pngread.hxx>
+#include <vcl/pngwrite.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::XInterface;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::makeAny;
+using ::com::sun::star::graphic::XGraphic;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::embed;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+ModuleImageManager::ModuleImageManager( uno::Reference< XMultiServiceFactory > xServiceManager ) :
+ ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_pImpl( new ImageManagerImpl(xServiceManager,static_cast< OWeakObject* >(this),true) )
+{
+}
+
+ModuleImageManager::~ModuleImageManager()
+{
+}
+
+// XComponent
+void SAL_CALL ModuleImageManager::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->dispose();
+}
+
+void SAL_CALL ModuleImageManager::addEventListener( const uno::Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->addEventListener(xListener);
+}
+
+void SAL_CALL ModuleImageManager::removeEventListener( const uno::Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_pImpl->removeEventListener(xListener);
+}
+
+// XInitialization
+void SAL_CALL ModuleImageManager::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ m_pImpl->initialize(aArguments);
+}
+
+// XImageManager
+void SAL_CALL ModuleImageManager::reset()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->reset();
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ModuleImageManager::getAllImageNames( ::sal_Int16 nImageType )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_pImpl->getAllImageNames( nImageType );
+}
+
+::sal_Bool SAL_CALL ModuleImageManager::hasImage( ::sal_Int16 nImageType, const ::rtl::OUString& aCommandURL )
+throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ return m_pImpl->hasImage(nImageType,aCommandURL);
+}
+
+Sequence< uno::Reference< XGraphic > > SAL_CALL ModuleImageManager::getImages(
+ ::sal_Int16 nImageType,
+ const Sequence< ::rtl::OUString >& aCommandURLSequence )
+throw ( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework: ModuleImageManager::getImages" );
+ return m_pImpl->getImages(nImageType,aCommandURLSequence);
+}
+
+void SAL_CALL ModuleImageManager::replaceImages(
+ ::sal_Int16 nImageType,
+ const Sequence< ::rtl::OUString >& aCommandURLSequence,
+ const Sequence< uno::Reference< XGraphic > >& aGraphicsSequence )
+throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::IllegalAccessException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->replaceImages(nImageType,aCommandURLSequence,aGraphicsSequence);
+}
+
+void SAL_CALL ModuleImageManager::removeImages( ::sal_Int16 nImageType, const Sequence< ::rtl::OUString >& aCommandURLSequence )
+throw ( ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::IllegalAccessException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->removeImages(nImageType,aCommandURLSequence);
+}
+
+void SAL_CALL ModuleImageManager::insertImages( ::sal_Int16 nImageType, const Sequence< ::rtl::OUString >& aCommandURLSequence, const Sequence< uno::Reference< XGraphic > >& aGraphicSequence )
+throw ( ::com::sun::star::container::ElementExistException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::IllegalAccessException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->insertImages(nImageType,aCommandURLSequence,aGraphicSequence);
+}
+
+// XUIConfiguration
+void SAL_CALL ModuleImageManager::addConfigurationListener( const uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->addConfigurationListener(xListener);
+}
+
+void SAL_CALL ModuleImageManager::removeConfigurationListener( const uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->removeConfigurationListener(xListener);
+}
+
+// XUIConfigurationPersistence
+void SAL_CALL ModuleImageManager::reload()
+throw ( ::com::sun::star::uno::Exception,
+ ::com::sun::star::uno::RuntimeException )
+{
+ m_pImpl->reload();
+}
+
+void SAL_CALL ModuleImageManager::store()
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->store();
+}
+
+void SAL_CALL ModuleImageManager::storeToStorage( const uno::Reference< XStorage >& Storage )
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ m_pImpl->storeToStorage(Storage);
+}
+
+sal_Bool SAL_CALL ModuleImageManager::isModified()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_pImpl->isModified();
+}
+
+sal_Bool SAL_CALL ModuleImageManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_pImpl->isReadOnly();
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/moduleuicfgsupplier.cxx b/framework/source/uiconfiguration/moduleuicfgsupplier.cxx
new file mode 100644
index 000000000000..59cb3b531e2b
--- /dev/null
+++ b/framework/source/uiconfiguration/moduleuicfgsupplier.cxx
@@ -0,0 +1,245 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uiconfiguration/moduleuicfgsupplier.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/embed/XPackageStructureCreator.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <rtl/logfile.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::embed;
+using namespace ::com::sun::star::ui;
+using namespace ::com::sun::star::frame;
+
+namespace framework
+{
+
+class RootStorageWrapper : public ::cppu::WeakImplHelper1< com::sun::star::embed::XTransactedObject >
+{
+ public:
+ // XInterface, XTypeProvider
+ RootStorageWrapper( const Reference< XTransactedObject >& xRootCommit ) : m_xRootCommit( xRootCommit ) {}
+ virtual ~RootStorageWrapper() {}
+
+ // XTransactedObject
+ virtual void SAL_CALL commit() throw ( com::sun::star::io::IOException, com::sun::star::lang::WrappedTargetException )
+ {
+ m_xRootCommit->commit();
+ }
+
+ virtual void SAL_CALL revert() throw ( com::sun::star::io::IOException, com::sun::star::lang::WrappedTargetException )
+ {
+ m_xRootCommit->revert();
+ }
+
+ private:
+ Reference< XTransactedObject > m_xRootCommit;
+};
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_4 ( ModuleUIConfigurationManagerSupplier ,
+ OWeakObject ,
+ DIRECT_INTERFACE( css::lang::XTypeProvider ),
+ DIRECT_INTERFACE( css::lang::XServiceInfo ),
+ DIRECT_INTERFACE( css::lang::XComponent ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier )
+ )
+
+DEFINE_XTYPEPROVIDER_4 ( ModuleUIConfigurationManagerSupplier ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::lang::XComponent ,
+ ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier
+ )
+
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( ModuleUIConfigurationManagerSupplier ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ,
+ IMPLEMENTATIONNAME_MODULEUICONFIGURATIONMANAGERSUPPLIER
+ )
+
+DEFINE_INIT_SERVICE ( ModuleUIConfigurationManagerSupplier, {} )
+
+
+
+ModuleUIConfigurationManagerSupplier::ModuleUIConfigurationManagerSupplier( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_bDisposed( false )
+//TODO_AS , m_bInit( false )
+ , m_xModuleMgr( Reference< XModuleManager >( xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY ))
+ , m_xServiceManager( xServiceManager )
+ , m_aListenerContainer( m_aLock.getShareableOslMutex() )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::ModuleUIConfigurationManagerSupplier" );
+ // Retrieve known modules and insert them into our boost::unordered_map to speed-up access time.
+ Reference< XNameAccess > xNameAccess( m_xModuleMgr, UNO_QUERY );
+ const Sequence< ::rtl::OUString > aNameSeq = xNameAccess->getElementNames();
+ const ::rtl::OUString* pNameSeq = aNameSeq.getConstArray();
+ for ( sal_Int32 n = 0; n < aNameSeq.getLength(); n++ )
+ m_aModuleToModuleUICfgMgrMap.insert( ModuleToModuleCfgMgr::value_type( pNameSeq[n], Reference< XUIConfigurationManager >() ));
+}
+
+ModuleUIConfigurationManagerSupplier::~ModuleUIConfigurationManagerSupplier()
+{
+ m_xUserRootCommit.clear();
+
+ // dispose all our module user interface configuration managers
+ ModuleToModuleCfgMgr::iterator pIter = m_aModuleToModuleUICfgMgrMap.begin();
+ while ( pIter != m_aModuleToModuleUICfgMgrMap.end() )
+ {
+ Reference< XComponent > xComponent( pIter->second, UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+ ++pIter;
+ }
+}
+
+// XComponent
+void SAL_CALL ModuleUIConfigurationManagerSupplier::dispose()
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::dispose" );
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ css::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ {
+ ResetableGuard aGuard( m_aLock );
+ m_bDisposed = true;
+ }
+}
+
+void SAL_CALL ModuleUIConfigurationManagerSupplier::addEventListener( const Reference< XEventListener >& xListener )
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::addEventListener" );
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL ModuleUIConfigurationManagerSupplier::removeEventListener( const Reference< XEventListener >& xListener )
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::removeEventListener" );
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+// XModuleUIConfigurationManagerSupplier
+Reference< XUIConfigurationManager > SAL_CALL ModuleUIConfigurationManagerSupplier::getUIConfigurationManager( const ::rtl::OUString& ModuleIdentifier )
+throw ( NoSuchElementException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::getUIConfigurationManager" );
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ ModuleToModuleCfgMgr::iterator pIter = m_aModuleToModuleUICfgMgrMap.find( ModuleIdentifier );
+ if ( pIter == m_aModuleToModuleUICfgMgrMap.end() )
+ throw NoSuchElementException();
+//TODO_AS impl_initStorages();
+
+ // Create instance on demand
+ if ( !pIter->second.is() )
+ {
+ ::rtl::OUString sShort;
+ try
+ {
+ Sequence< PropertyValue > lProps;
+ Reference< XNameAccess > xCont(m_xModuleMgr, UNO_QUERY);
+ xCont->getByName(ModuleIdentifier) >>= lProps;
+ for (sal_Int32 i=0; i<lProps.getLength(); ++i)
+ {
+ if (lProps[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ooSetupFactoryShortName")))
+ {
+ lProps[i].Value >>= sShort;
+ break;
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ sShort = ::rtl::OUString();
+ }
+
+ if (!sShort.getLength())
+ throw NoSuchElementException();
+ PropertyValue aArg;
+ Sequence< Any > aArgs( 2 );
+ aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleShortName" ));
+ aArg.Value <<= sShort;
+ aArgs[0] <<= aArg;
+ aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
+ aArg.Value <<= ModuleIdentifier;
+ aArgs[1] <<= aArg;
+
+ pIter->second.set( m_xServiceManager->createInstanceWithArguments(SERVICENAME_MODULEUICONFIGURATIONMANAGER, aArgs ),UNO_QUERY );
+ }
+
+ return pIter->second;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx b/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx
new file mode 100644
index 000000000000..61086f56db68
--- /dev/null
+++ b/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx
@@ -0,0 +1,1619 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uiconfiguration/moduleuiconfigurationmanager.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <services.h>
+#include <uielement/constitemcontainer.hxx>
+#include <uielement/rootitemcontainer.hxx>
+#include <uielement/uielementtypenames.hxx>
+#include <framework/menuconfiguration.hxx>
+#include <framework/toolboxconfiguration.hxx>
+
+#include <framework/statusbarconfiguration.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/ui/ConfigurationEvent.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/io/XStream.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using rtl::OUString;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+using namespace com::sun::star::embed;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_8 ( ModuleUIConfigurationManager ,
+ OWeakObject ,
+ DIRECT_INTERFACE( css::lang::XTypeProvider ),
+ DIRECT_INTERFACE( css::lang::XServiceInfo ),
+ DIRECT_INTERFACE( css::lang::XComponent ),
+ DIRECT_INTERFACE( css::lang::XInitialization ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfiguration ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationManager ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XModuleUIConfigurationManager ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationPersistence )
+ )
+
+DEFINE_XTYPEPROVIDER_8 ( ModuleUIConfigurationManager ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::lang::XComponent ,
+ css::lang::XInitialization ,
+ ::com::sun::star::ui::XUIConfiguration ,
+ ::com::sun::star::ui::XUIConfigurationManager ,
+ ::com::sun::star::ui::XModuleUIConfigurationManager ,
+ ::com::sun::star::ui::XUIConfigurationPersistence
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( ModuleUIConfigurationManager ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_MODULEUICONFIGURATIONMANAGER ,
+ IMPLEMENTATIONNAME_MODULEUICONFIGURATIONMANAGER
+ )
+
+DEFINE_INIT_SERVICE ( ModuleUIConfigurationManager, {} )
+
+
+// important: The order and position of the elements must match the constant
+// definition of "::com::sun::star::ui::UIElementType"
+static const char* UIELEMENTTYPENAMES[] =
+{
+ "", // Dummy value for unknown!
+ UIELEMENTTYPE_MENUBAR_NAME,
+ UIELEMENTTYPE_POPUPMENU_NAME,
+ UIELEMENTTYPE_TOOLBAR_NAME,
+ UIELEMENTTYPE_STATUSBAR_NAME,
+ UIELEMENTTYPE_FLOATINGWINDOW_NAME,
+ UIELEMENTTYPE_PROGRESSBAR_NAME,
+ UIELEMENTTYPE_TOOLPANEL_NAME
+};
+
+static const char RESOURCEURL_PREFIX[] = "private:resource/";
+static const sal_Int32 RESOURCEURL_PREFIX_SIZE = 17;
+static const char RESOURCEURL_CUSTOM_ELEMENT[] = "custom_";
+
+static sal_Int16 RetrieveTypeFromResourceURL( const rtl::OUString& aResourceURL )
+{
+
+ if (( aResourceURL.indexOf( OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) &&
+ ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
+ {
+ OUString aTmpStr = aResourceURL.copy( RESOURCEURL_PREFIX_SIZE );
+ sal_Int32 nIndex = aTmpStr.indexOf( '/' );
+ if (( nIndex > 0 ) && ( aTmpStr.getLength() > nIndex ))
+ {
+ OUString aTypeStr( aTmpStr.copy( 0, nIndex ));
+ for ( int i = 0; i < UIElementType::COUNT; i++ )
+ {
+ if ( aTypeStr.equalsAscii( UIELEMENTTYPENAMES[i] ))
+ return sal_Int16( i );
+ }
+ }
+ }
+
+ return UIElementType::UNKNOWN;
+}
+
+static OUString RetrieveNameFromResourceURL( const rtl::OUString& aResourceURL )
+{
+ if (( aResourceURL.indexOf( OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) &&
+ ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
+ {
+ sal_Int32 nIndex = aResourceURL.lastIndexOf( '/' );
+ if (( nIndex > 0 ) && (( nIndex+1 ) < aResourceURL.getLength()))
+ return aResourceURL.copy( nIndex+1 );
+ }
+
+ return OUString();
+}
+
+void ModuleUIConfigurationManager::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType )
+{
+ // preload list of element types on demand
+ impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType );
+ impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
+
+ UIElementDataHashMap& rUserElements = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap;
+ UIElementDataHashMap::const_iterator pUserIter = rUserElements.begin();
+
+ OUString aCustomUrlPrefix( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_CUSTOM_ELEMENT ));
+ while ( pUserIter != rUserElements.end() )
+ {
+ sal_Int32 nIndex = pUserIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE );
+ if ( nIndex > RESOURCEURL_PREFIX_SIZE )
+ {
+ // Performance: Retrieve user interface name only for custom user interface elements.
+ // It's only used by them!
+ UIElementData* pDataSettings = impl_findUIElementData( pUserIter->second.aResourceURL, nElementType );
+ if ( pDataSettings )
+ {
+ // Retrieve user interface name from XPropertySet interface
+ rtl::OUString aUIName;
+ Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ Any a = xPropSet->getPropertyValue( m_aPropUIName );
+ a >>= aUIName;
+ }
+
+ UIElementInfo aInfo( pUserIter->second.aResourceURL, aUIName );
+ aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo ));
+ }
+ }
+ else
+ {
+ // The user interface name for standard user interface elements is stored in the WindowState.xcu file
+ UIElementInfo aInfo( pUserIter->second.aResourceURL, OUString() );
+ aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo ));
+ }
+ ++pUserIter;
+ }
+
+ UIElementDataHashMap& rDefaultElements = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
+ UIElementDataHashMap::const_iterator pDefIter = rDefaultElements.begin();
+
+ while ( pDefIter != rDefaultElements.end() )
+ {
+ UIElementInfoHashMap::const_iterator pIterInfo = aUIElementInfoCollection.find( pDefIter->second.aResourceURL );
+ if ( pIterInfo == aUIElementInfoCollection.end() )
+ {
+ sal_Int32 nIndex = pDefIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE );
+ if ( nIndex > RESOURCEURL_PREFIX_SIZE )
+ {
+ // Performance: Retrieve user interface name only for custom user interface elements.
+ // It's only used by them!
+ UIElementData* pDataSettings = impl_findUIElementData( pDefIter->second.aResourceURL, nElementType );
+ if ( pDataSettings )
+ {
+ // Retrieve user interface name from XPropertySet interface
+ rtl::OUString aUIName;
+ Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ Any a = xPropSet->getPropertyValue( m_aPropUIName );
+ a >>= aUIName;
+ }
+
+ UIElementInfo aInfo( pDefIter->second.aResourceURL, aUIName );
+ aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pDefIter->second.aResourceURL, aInfo ));
+ }
+ }
+ else
+ {
+ // The user interface name for standard user interface elements is stored in the WindowState.xcu file
+ UIElementInfo aInfo( pDefIter->second.aResourceURL, OUString() );
+ aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pDefIter->second.aResourceURL, aInfo ));
+ }
+ }
+
+ ++pDefIter;
+ }
+}
+
+void ModuleUIConfigurationManager::impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType )
+{
+ UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType];
+
+ if ( !rElementTypeData.bLoaded )
+ {
+ Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
+ if ( xElementTypeStorage.is() )
+ {
+ rtl::OUStringBuffer aBuf( RESOURCEURL_PREFIX_SIZE );
+ aBuf.appendAscii( RESOURCEURL_PREFIX );
+ aBuf.appendAscii( UIELEMENTTYPENAMES[ nElementType ] );
+ aBuf.appendAscii( "/" );
+ OUString aResURLPrefix( aBuf.makeStringAndClear() );
+
+ UIElementDataHashMap& rHashMap = rElementTypeData.aElementsHashMap;
+ Reference< XNameAccess > xNameAccess( xElementTypeStorage, UNO_QUERY );
+ Sequence< OUString > aUIElementNames = xNameAccess->getElementNames();
+ for ( sal_Int32 n = 0; n < aUIElementNames.getLength(); n++ )
+ {
+ UIElementData aUIElementData;
+
+ // Resource name must be without ".xml"
+ sal_Int32 nIndex = aUIElementNames[n].lastIndexOf( '.' );
+ if (( nIndex > 0 ) && ( nIndex < aUIElementNames[n].getLength() ))
+ {
+ OUString aExtension( aUIElementNames[n].copy( nIndex+1 ));
+ OUString aUIElementName( aUIElementNames[n].copy( 0, nIndex ));
+
+ if (( aUIElementName.getLength() > 0 ) &&
+ ( aExtension.equalsIgnoreAsciiCaseAsciiL( "xml", 3 )))
+ {
+ aUIElementData.aResourceURL = aResURLPrefix + aUIElementName;
+ aUIElementData.aName = aUIElementNames[n];
+
+ if ( eLayer == LAYER_USERDEFINED )
+ {
+ aUIElementData.bModified = false;
+ aUIElementData.bDefault = false;
+ aUIElementData.bDefaultNode = false;
+ }
+
+ // Create boost::unordered_map entries for all user interface elements inside the storage. We don't load the
+ // settings to speed up the process.
+ rHashMap.insert( UIElementDataHashMap::value_type( aUIElementData.aResourceURL, aUIElementData ));
+ }
+ }
+ rElementTypeData.bLoaded = true;
+ }
+ }
+ }
+
+}
+
+void ModuleUIConfigurationManager::impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData )
+{
+ UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType];
+
+ Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
+ if ( xElementTypeStorage.is() && aUIElementData.aName.getLength() )
+ {
+ try
+ {
+ Reference< XStream > xStream = xElementTypeStorage->openStreamElement( aUIElementData.aName, ElementModes::READ );
+ Reference< XInputStream > xInputStream = xStream->getInputStream();
+
+ if ( xInputStream.is() )
+ {
+ switch ( nElementType )
+ {
+ case ::com::sun::star::ui::UIElementType::UNKNOWN:
+ break;
+
+ case ::com::sun::star::ui::UIElementType::MENUBAR:
+ {
+ try
+ {
+ MenuConfiguration aMenuCfg( m_xServiceManager );
+ Reference< XIndexAccess > xContainer( aMenuCfg.CreateMenuBarConfigurationFromXML( xInputStream ));
+ RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xContainer );
+ if ( pRootItemContainer )
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY );
+ else
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xContainer, sal_True ) ), UNO_QUERY );
+ return;
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ case ::com::sun::star::ui::UIElementType::POPUPMENU:
+ {
+ break;
+ }
+
+ case ::com::sun::star::ui::UIElementType::TOOLBAR:
+ {
+ try
+ {
+ Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
+ ToolBoxConfiguration::LoadToolBox( m_xServiceManager, xInputStream, xIndexContainer );
+ RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY );
+ return;
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+
+ break;
+ }
+
+ case ::com::sun::star::ui::UIElementType::STATUSBAR:
+ {
+ try
+ {
+ Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
+ StatusBarConfiguration::LoadStatusBar( m_xServiceManager, xInputStream, xIndexContainer );
+ RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY );
+ return;
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+
+ break;
+ }
+
+ case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW:
+ {
+ break;
+ }
+ }
+ }
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+ }
+
+ // At least we provide an empty settings container!
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer() ), UNO_QUERY );
+}
+
+ModuleUIConfigurationManager::UIElementData* ModuleUIConfigurationManager::impl_findUIElementData( const rtl::OUString& aResourceURL, sal_Int16 nElementType, bool bLoad )
+{
+ // preload list of element types on demand
+ impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType );
+ impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
+
+ // first try to look into our user-defined vector/boost::unordered_map combination
+ UIElementDataHashMap& rUserHashMap = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rUserHashMap.find( aResourceURL );
+ if ( pIter != rUserHashMap.end() )
+ {
+ // Default data settings data must be retrieved from the default layer!
+ if ( !pIter->second.bDefault )
+ {
+ if ( !pIter->second.xSettings.is() && bLoad )
+ impl_requestUIElementData( nElementType, LAYER_USERDEFINED, pIter->second );
+ return &(pIter->second);
+ }
+ }
+
+ // Not successfull, we have to look into our default vector/boost::unordered_map combination
+ UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
+ pIter = rDefaultHashMap.find( aResourceURL );
+ if ( pIter != rDefaultHashMap.end() )
+ {
+ if ( !pIter->second.xSettings.is() && bLoad )
+ impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
+ return &(pIter->second);
+ }
+
+ // Nothing has been found!
+ return NULL;
+}
+
+void ModuleUIConfigurationManager::impl_storeElementTypeData( Reference< XStorage > xStorage, UIElementType& rElementType, bool bResetModifyState )
+{
+ UIElementDataHashMap& rHashMap = rElementType.aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rHashMap.begin();
+
+ while ( pIter != rHashMap.end() )
+ {
+ UIElementData& rElement = pIter->second;
+ if ( rElement.bModified )
+ {
+ if ( rElement.bDefault )
+ {
+ xStorage->removeElement( rElement.aName );
+ rElement.bModified = sal_False; // mark as not modified
+ }
+ else
+ {
+ Reference< XStream > xStream( xStorage->openStreamElement( rElement.aName, ElementModes::WRITE|ElementModes::TRUNCATE ), UNO_QUERY );
+ Reference< XOutputStream > xOutputStream( xStream->getOutputStream() );
+
+ if ( xOutputStream.is() )
+ {
+ switch( rElementType.nElementType )
+ {
+ case ::com::sun::star::ui::UIElementType::MENUBAR:
+ {
+ try
+ {
+ MenuConfiguration aMenuCfg( m_xServiceManager );
+ aMenuCfg.StoreMenuBarConfigurationToXML( rElement.xSettings, xOutputStream );
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ case ::com::sun::star::ui::UIElementType::TOOLBAR:
+ {
+ try
+ {
+ ToolBoxConfiguration::StoreToolBox( m_xServiceManager, xOutputStream, rElement.xSettings );
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ case ::com::sun::star::ui::UIElementType::STATUSBAR:
+ {
+ try
+ {
+ StatusBarConfiguration::StoreStatusBar( m_xServiceManager, xOutputStream, rElement.xSettings );
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // mark as not modified if we store to our own storage
+ if ( bResetModifyState )
+ rElement.bModified = sal_False;
+ }
+ }
+
+ ++pIter;
+ }
+
+ // commit element type storage
+ Reference< XTransactedObject > xTransactedObject( xStorage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+
+ // mark UIElementType as not modified if we store to our own storage
+ if ( bResetModifyState )
+ rElementType.bModified = sal_False;
+}
+
+// This is only allowed to be called on the LAYER_USER_DEFINED!
+void ModuleUIConfigurationManager::impl_resetElementTypeData(
+ UIElementType& rUserElementType,
+ UIElementType& rDefaultElementType,
+ ConfigEventNotifyContainer& rRemoveNotifyContainer,
+ ConfigEventNotifyContainer& rReplaceNotifyContainer )
+{
+ UIElementDataHashMap& rHashMap = rUserElementType.aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rHashMap.begin();
+
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+ Reference< XNameAccess > xDefaultNameAccess( rDefaultElementType.xStorage, UNO_QUERY );
+ sal_Int16 nType = rUserElementType.nElementType;
+
+ // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling
+ // our listeners!
+ while ( pIter != rHashMap.end() )
+ {
+ UIElementData& rElement = pIter->second;
+ if ( !rElement.bDefault )
+ {
+ if ( xDefaultNameAccess->hasByName( rElement.aName ))
+ {
+ // Replace settings with data from default layer
+ Reference< XIndexAccess > xOldSettings( rElement.xSettings );
+ impl_requestUIElementData( nType, LAYER_DEFAULT, rElement );
+
+ ConfigurationEvent aReplaceEvent;
+ aReplaceEvent.ResourceURL = rElement.aResourceURL;
+ aReplaceEvent.Accessor <<= xThis;
+ aReplaceEvent.Source = xIfac;
+ aReplaceEvent.ReplacedElement <<= xOldSettings;
+ aReplaceEvent.Element <<= rElement.xSettings;
+
+ rReplaceNotifyContainer.push_back( aReplaceEvent );
+
+ // Mark element as default and not modified. That means "not active"
+ // in the user layer anymore.
+ rElement.bModified = false;
+ rElement.bDefault = true;
+ }
+ else
+ {
+ // Remove user-defined settings from user layer
+ ConfigurationEvent aEvent;
+ aEvent.ResourceURL = rElement.aResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = xIfac;
+ aEvent.Element <<= rElement.xSettings;
+
+ rRemoveNotifyContainer.push_back( aEvent );
+
+ // Mark element as default and not modified. That means "not active"
+ // in the user layer anymore.
+ rElement.bModified = false;
+ rElement.bDefault = true;
+ }
+ }
+
+ ++pIter;
+ }
+
+ // Remove all settings from our user interface elements
+ rHashMap.clear();
+}
+
+void ModuleUIConfigurationManager::impl_reloadElementTypeData(
+ UIElementType& rUserElementType,
+ UIElementType& rDefaultElementType,
+ ConfigEventNotifyContainer& rRemoveNotifyContainer,
+ ConfigEventNotifyContainer& rReplaceNotifyContainer )
+{
+ UIElementDataHashMap& rHashMap = rUserElementType.aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rHashMap.begin();
+ Reference< XStorage > xUserStorage( rUserElementType.xStorage );
+ Reference< XStorage > xDefaultStorage( rDefaultElementType.xStorage );
+ Reference< XNameAccess > xUserNameAccess( rUserElementType.xStorage, UNO_QUERY );
+ Reference< XNameAccess > xDefaultNameAccess( rDefaultElementType.xStorage, UNO_QUERY );
+
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+ sal_Int16 nType = rUserElementType.nElementType;
+
+ while ( pIter != rHashMap.end() )
+ {
+ UIElementData& rElement = pIter->second;
+ if ( rElement.bModified )
+ {
+ if ( xUserNameAccess->hasByName( rElement.aName ))
+ {
+ // Replace settings with data from user layer
+ Reference< XIndexAccess > xOldSettings( rElement.xSettings );
+
+ impl_requestUIElementData( nType, LAYER_USERDEFINED, rElement );
+
+ ConfigurationEvent aReplaceEvent;
+
+ aReplaceEvent.ResourceURL = rElement.aResourceURL;
+ aReplaceEvent.Accessor <<= xThis;
+ aReplaceEvent.Source = xIfac;
+ aReplaceEvent.ReplacedElement <<= xOldSettings;
+ aReplaceEvent.Element <<= rElement.xSettings;
+ rReplaceNotifyContainer.push_back( aReplaceEvent );
+
+ rElement.bModified = false;
+ }
+ else if ( xDefaultNameAccess->hasByName( rElement.aName ))
+ {
+ // Replace settings with data from default layer
+ Reference< XIndexAccess > xOldSettings( rElement.xSettings );
+
+ impl_requestUIElementData( nType, LAYER_DEFAULT, rElement );
+
+ ConfigurationEvent aReplaceEvent;
+
+ aReplaceEvent.ResourceURL = rElement.aResourceURL;
+ aReplaceEvent.Accessor <<= xThis;
+ aReplaceEvent.Source = xIfac;
+ aReplaceEvent.ReplacedElement <<= xOldSettings;
+ aReplaceEvent.Element <<= rElement.xSettings;
+ rReplaceNotifyContainer.push_back( aReplaceEvent );
+
+ // Mark element as default and not modified. That means "not active"
+ // in the user layer anymore.
+ rElement.bModified = false;
+ rElement.bDefault = true;
+ }
+ else
+ {
+ // Element settings are not in any storage => remove
+ ConfigurationEvent aRemoveEvent;
+
+ aRemoveEvent.ResourceURL = rElement.aResourceURL;
+ aRemoveEvent.Accessor <<= xThis;
+ aRemoveEvent.Source = xIfac;
+ aRemoveEvent.Element <<= rElement.xSettings;
+
+ rRemoveNotifyContainer.push_back( aRemoveEvent );
+
+ // Mark element as default and not modified. That means "not active"
+ // in the user layer anymore.
+ rElement.bModified = false;
+ rElement.bDefault = true;
+ }
+ }
+ ++pIter;
+ }
+
+ rUserElementType.bModified = sal_False;
+}
+
+void ModuleUIConfigurationManager::impl_Initialize()
+{
+ // Initialize the top-level structures with the storage data
+ if ( m_xUserConfigStorage.is() )
+ {
+ // Try to access our module sub folder
+ for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT;
+ i++ )
+ {
+ Reference< XStorage > xElementTypeStorage;
+ try
+ {
+ if ( m_pStorageHandler[i] )
+ xElementTypeStorage = m_pStorageHandler[i]->getWorkingStorageUser();
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+
+ m_aUIElements[LAYER_USERDEFINED][i].nElementType = i;
+ m_aUIElements[LAYER_USERDEFINED][i].bModified = false;
+ m_aUIElements[LAYER_USERDEFINED][i].xStorage = xElementTypeStorage;
+ m_aUIElements[LAYER_USERDEFINED][i].bDefaultLayer = false;
+ }
+ }
+
+ if ( m_xDefaultConfigStorage.is() )
+ {
+ Reference< XNameAccess > xNameAccess( m_xDefaultConfigStorage, UNO_QUERY_THROW );
+
+ // Try to access our module sub folder
+ for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT;
+ i++ )
+ {
+ Reference< XStorage > xElementTypeStorage;
+ try
+ {
+ const OUString sName( OUString::createFromAscii( UIELEMENTTYPENAMES[i] ) );
+ if( xNameAccess->hasByName( sName ) )
+ xNameAccess->getByName( sName ) >>= xElementTypeStorage;
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+
+ m_aUIElements[LAYER_DEFAULT][i].nElementType = i;
+ m_aUIElements[LAYER_DEFAULT][i].bModified = false;
+ m_aUIElements[LAYER_DEFAULT][i].xStorage = xElementTypeStorage;
+ m_aUIElements[LAYER_DEFAULT][i].bDefaultLayer = true;
+ }
+ }
+}
+
+ModuleUIConfigurationManager::ModuleUIConfigurationManager( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xServiceManager ) :
+ ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_xDefaultConfigStorage( 0 )
+ , m_xUserConfigStorage( 0 )
+ , m_bReadOnly( true )
+ , m_bInitialized( false )
+ , m_bModified( false )
+ , m_bConfigRead( false )
+ , m_bDisposed( false )
+ , m_aXMLPostfix( RTL_CONSTASCII_USTRINGPARAM( ".xml" ))
+ , m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))
+ , m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ))
+ , m_xServiceManager( xServiceManager )
+ , m_aListenerContainer( m_aLock.getShareableOslMutex() )
+{
+ for ( int i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ m_pStorageHandler[i] = 0;
+
+ // Make sure we have a default initialized entry for every layer and user interface element type!
+ // The following code depends on this!
+ m_aUIElements[LAYER_DEFAULT].resize( ::com::sun::star::ui::UIElementType::COUNT );
+ m_aUIElements[LAYER_USERDEFINED].resize( ::com::sun::star::ui::UIElementType::COUNT );
+}
+
+ModuleUIConfigurationManager::~ModuleUIConfigurationManager()
+{
+ for ( int i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ delete m_pStorageHandler[i];
+}
+
+// XComponent
+void SAL_CALL ModuleUIConfigurationManager::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ css::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ ResetableGuard aGuard( m_aLock );
+ Reference< XComponent > xModuleImageManager( m_xModuleImageManager );
+ m_xModuleImageManager.clear();
+ m_xModuleAcceleratorManager.clear();
+ m_aUIElements[LAYER_USERDEFINED].clear();
+ m_aUIElements[LAYER_DEFAULT].clear();
+ m_xDefaultConfigStorage.clear();
+ m_xUserConfigStorage.clear();
+ m_xUserRootCommit.clear();
+ m_bConfigRead = false;
+ m_bModified = false;
+ m_bDisposed = true;
+ aGuard.unlock();
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+
+ try
+ {
+ if ( xModuleImageManager.is() )
+ xModuleImageManager->dispose();
+ }
+ catch ( Exception& )
+ {
+ }
+}
+
+void SAL_CALL ModuleUIConfigurationManager::addEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL ModuleUIConfigurationManager::removeEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+// XInitialization
+void SAL_CALL ModuleUIConfigurationManager::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bInitialized )
+ {
+ ::comphelper::SequenceAsHashMap lArgs(aArguments);
+ m_aModuleIdentifier = lArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleIdentifier")), ::rtl::OUString());
+ m_aModuleShortName = lArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleShortName")), ::rtl::OUString());
+
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ rtl::OUString aResourceType;
+ if ( i == ::com::sun::star::ui::UIElementType::MENUBAR )
+ aResourceType = PresetHandler::RESOURCETYPE_MENUBAR();
+ else if ( i == ::com::sun::star::ui::UIElementType::TOOLBAR )
+ aResourceType = PresetHandler::RESOURCETYPE_TOOLBAR();
+ else if ( i == ::com::sun::star::ui::UIElementType::STATUSBAR )
+ aResourceType = PresetHandler::RESOURCETYPE_STATUSBAR();
+
+ if ( aResourceType.getLength() > 0 )
+ {
+ m_pStorageHandler[i] = new PresetHandler( m_xServiceManager );
+ m_pStorageHandler[i]->connectToResource( PresetHandler::E_MODULES,
+ aResourceType, // this path wont be used later ... seee next lines!
+ m_aModuleShortName,
+ css::uno::Reference< css::embed::XStorage >()); // no document root used here!
+ }
+ }
+
+ // initialize root storages for all resource types
+ m_xUserRootCommit = css::uno::Reference< css::embed::XTransactedObject >(
+ m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getOrCreateRootStorageUser(), css::uno::UNO_QUERY); // can be empty
+ m_xDefaultConfigStorage = m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getParentStorageShare(
+ m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getWorkingStorageShare());
+ m_xUserConfigStorage = m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getParentStorageUser(
+ m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getWorkingStorageUser());
+
+ if ( m_xUserConfigStorage.is() )
+ {
+ Reference< XPropertySet > xPropSet( m_xUserConfigStorage, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ long nOpenMode = 0;
+ Any a = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" )));
+ if ( a >>= nOpenMode )
+ m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
+ }
+ }
+
+ impl_Initialize();
+
+ m_bInitialized = true;
+ }
+}
+
+// XUIConfiguration
+void SAL_CALL ModuleUIConfigurationManager::addConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL ModuleUIConfigurationManager::removeConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener );
+}
+
+
+// XUIConfigurationManager
+void SAL_CALL ModuleUIConfigurationManager::reset() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( !isReadOnly() )
+ {
+ // Remove all elements from our user-defined storage!
+ try
+ {
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i];
+ Reference< XStorage > xSubStorage( rElementType.xStorage, UNO_QUERY );
+
+ if ( xSubStorage.is() )
+ {
+ bool bCommitSubStorage( false );
+ Reference< XNameAccess > xSubStorageNameAccess( xSubStorage, UNO_QUERY );
+ Sequence< OUString > aUIElementStreamNames = xSubStorageNameAccess->getElementNames();
+ for ( sal_Int32 j = 0; j < aUIElementStreamNames.getLength(); j++ )
+ {
+ xSubStorage->removeElement( aUIElementStreamNames[j] );
+ bCommitSubStorage = true;
+ }
+
+ if ( bCommitSubStorage )
+ {
+ Reference< XTransactedObject > xTransactedObject( xSubStorage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+ m_pStorageHandler[i]->commitUserChanges();
+ }
+ }
+ }
+
+ // remove settings from user defined layer and notify listener about removed settings data!
+ ConfigEventNotifyContainer aRemoveEventNotifyContainer;
+ ConfigEventNotifyContainer aReplaceEventNotifyContainer;
+ for ( sal_Int16 j = 1; j < ::com::sun::star::ui::UIElementType::COUNT; j++ )
+ {
+ try
+ {
+ UIElementType& rUserElementType = m_aUIElements[LAYER_USERDEFINED][j];
+ UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][j];
+
+ impl_resetElementTypeData( rUserElementType, rDefaultElementType, aRemoveEventNotifyContainer, aReplaceEventNotifyContainer );
+ rUserElementType.bModified = sal_False;
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ m_bModified = sal_False;
+
+ // Unlock mutex before notify our listeners
+ aGuard.unlock();
+
+ // Notify our listeners
+ sal_uInt32 k = 0;
+ for ( k = 0; k < aRemoveEventNotifyContainer.size(); k++ )
+ implts_notifyContainerListener( aRemoveEventNotifyContainer[k], NotifyOp_Remove );
+ for ( k = 0; k < aReplaceEventNotifyContainer.size(); k++ )
+ implts_notifyContainerListener( aReplaceEventNotifyContainer[k], NotifyOp_Replace );
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+ }
+}
+
+Sequence< Sequence< PropertyValue > > SAL_CALL ModuleUIConfigurationManager::getUIElementsInfo( sal_Int16 ElementType )
+throw ( IllegalArgumentException, RuntimeException )
+{
+ if (( ElementType < 0 ) || ( ElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+
+ ResetableGuard aGuard( m_aLock );
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ Sequence< Sequence< PropertyValue > > aElementInfoSeq;
+ UIElementInfoHashMap aUIElementInfoCollection;
+
+ if ( ElementType == ::com::sun::star::ui::UIElementType::UNKNOWN )
+ {
+ for ( sal_Int16 i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, sal_Int16( i ) );
+ }
+ else
+ impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType );
+
+ Sequence< PropertyValue > aUIElementInfo( 2 );
+ aUIElementInfo[0].Name = m_aPropResourceURL;
+ aUIElementInfo[1].Name = m_aPropUIName;
+
+ aElementInfoSeq.realloc( aUIElementInfoCollection.size() );
+ UIElementInfoHashMap::const_iterator pIter = aUIElementInfoCollection.begin();
+
+ sal_Int32 n = 0;
+ while ( pIter != aUIElementInfoCollection.end() )
+ {
+ aUIElementInfo[0].Value <<= pIter->second.aResourceURL;
+ aUIElementInfo[1].Value <<= pIter->second.aUIName;
+ aElementInfoSeq[n++] = aUIElementInfo;
+ ++pIter;
+ }
+
+ return aElementInfoSeq;
+}
+
+Reference< XIndexContainer > SAL_CALL ModuleUIConfigurationManager::createSettings() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ // Creates an empty item container which can be filled from outside
+ return Reference< XIndexContainer >( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
+}
+
+sal_Bool SAL_CALL ModuleUIConfigurationManager::hasSettings( const ::rtl::OUString& ResourceURL )
+throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
+ if ( pDataSettings )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+Reference< XIndexAccess > SAL_CALL ModuleUIConfigurationManager::getSettings( const ::rtl::OUString& ResourceURL, sal_Bool bWriteable )
+throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
+ if ( pDataSettings )
+ {
+ // Create a copy of our data if someone wants to change the data.
+ if ( bWriteable )
+ return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( pDataSettings->xSettings ) ), UNO_QUERY );
+ else
+ return pDataSettings->xSettings;
+ }
+ }
+
+ throw NoSuchElementException();
+}
+
+void SAL_CALL ModuleUIConfigurationManager::replaceSettings( const ::rtl::OUString& ResourceURL, const Reference< ::com::sun::star::container::XIndexAccess >& aNewData )
+throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else if ( m_bReadOnly )
+ throw IllegalAccessException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
+ if ( pDataSettings )
+ {
+ if ( !pDataSettings->bDefaultNode )
+ {
+ // we have a settings entry in our user-defined layer - replace
+ Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings;
+
+ // Create a copy of the data if the container is not const
+ Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
+ if ( xReplace.is() )
+ pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
+ else
+ pDataSettings->xSettings = aNewData;
+ pDataSettings->bDefault = false;
+ pDataSettings->bModified = true;
+ m_bModified = true;
+
+ // Modify type container
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
+ rElementType.bModified = true;
+
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+
+ // Create event to notify listener about replaced element settings
+ ConfigurationEvent aEvent;
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+
+ aEvent.ResourceURL = ResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = xIfac;
+ aEvent.ReplacedElement <<= xOldSettings;
+ aEvent.Element <<= pDataSettings->xSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Replace );
+ }
+ else
+ {
+ // we have no settings in our user-defined layer - insert
+ UIElementData aUIElementData;
+
+ aUIElementData.bDefault = false;
+ aUIElementData.bDefaultNode = false;
+ aUIElementData.bModified = true;
+
+ // Create a copy of the data if the container is not const
+ Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
+ if ( xReplace.is() )
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
+ else
+ aUIElementData.xSettings = aNewData;
+ aUIElementData.aName = RetrieveNameFromResourceURL( ResourceURL ) + m_aXMLPostfix;
+ aUIElementData.aResourceURL = ResourceURL;
+ m_bModified = true;
+
+ // Modify type container
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
+ rElementType.bModified = true;
+
+ UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
+
+ // Check our user element settings hash map as it can already contain settings that have been set to default!
+ // If no node can be found, we have to insert it.
+ UIElementDataHashMap::iterator pIter = rElements.find( ResourceURL );
+ if ( pIter != rElements.end() )
+ pIter->second = aUIElementData;
+ else
+ rElements.insert( UIElementDataHashMap::value_type( ResourceURL, aUIElementData ));
+
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+
+ // Create event to notify listener about replaced element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = ResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = xIfac;
+ aEvent.ReplacedElement <<= pDataSettings->xSettings;
+ aEvent.Element <<= aUIElementData.xSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Replace );
+ }
+ }
+ else
+ throw NoSuchElementException();
+ }
+}
+
+void SAL_CALL ModuleUIConfigurationManager::removeSettings( const ::rtl::OUString& ResourceURL )
+throw ( NoSuchElementException, IllegalArgumentException, IllegalAccessException, RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else if ( m_bReadOnly )
+ throw IllegalAccessException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
+ if ( pDataSettings )
+ {
+ // If element settings are default, we don't need to change anything!
+ if ( pDataSettings->bDefault )
+ return;
+ else
+ {
+ Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings;
+ pDataSettings->bDefault = true;
+
+ // check if this is a default layer node
+ if ( !pDataSettings->bDefaultNode )
+ pDataSettings->bModified = true; // we have to remove this node from the user layer!
+ pDataSettings->xSettings.clear();
+ m_bModified = true; // user layer must be written
+
+ // Modify type container
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
+ rElementType.bModified = true;
+
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+
+ // Check if we have settings in the default layer which replaces the user-defined one!
+ UIElementData* pDefaultDataSettings = impl_findUIElementData( ResourceURL, nElementType );
+ if ( pDefaultDataSettings )
+ {
+ // Create event to notify listener about replaced element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = ResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = xIfac;
+ aEvent.Element <<= xRemovedSettings;
+ aEvent.ReplacedElement <<= pDefaultDataSettings->xSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Replace );
+ }
+ else
+ {
+ // Create event to notify listener about removed element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = ResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = xIfac;
+ aEvent.Element <<= xRemovedSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Remove );
+ }
+ }
+ }
+ else
+ throw NoSuchElementException();
+ }
+}
+
+void SAL_CALL ModuleUIConfigurationManager::insertSettings( const ::rtl::OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData )
+throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, RuntimeException )
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else if ( m_bReadOnly )
+ throw IllegalAccessException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType );
+ if ( !pDataSettings )
+ {
+ UIElementData aUIElementData;
+
+ aUIElementData.bDefault = false;
+ aUIElementData.bDefaultNode = false;
+ aUIElementData.bModified = true;
+
+ // Create a copy of the data if the container is not const
+ Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
+ if ( xReplace.is() )
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
+ else
+ aUIElementData.xSettings = aNewData;
+ aUIElementData.aName = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix;
+ aUIElementData.aResourceURL = NewResourceURL;
+ m_bModified = true;
+
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
+ rElementType.bModified = true;
+
+ UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
+ rElements.insert( UIElementDataHashMap::value_type( NewResourceURL, aUIElementData ));
+
+ Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings );
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+
+ // Create event to notify listener about removed element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = NewResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = xIfac;
+ aEvent.Element <<= xInsertSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Insert );
+ }
+ else
+ throw ElementExistException();
+ }
+}
+
+Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getImageManager() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( !m_xModuleImageManager.is() )
+ {
+ m_xModuleImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ModuleImageManager( m_xServiceManager )),
+ UNO_QUERY );
+ Reference< XInitialization > xInit( m_xModuleImageManager, UNO_QUERY );
+
+ Sequence< Any > aPropSeq( 3 );
+ PropertyValue aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" ));
+ aPropValue.Value = makeAny( m_xUserConfigStorage );
+ aPropSeq[0] = makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
+ aPropValue.Value = makeAny( m_aModuleIdentifier );
+ aPropSeq[1] = makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserRootCommit" ));
+ aPropValue.Value = makeAny( m_xUserRootCommit );
+ aPropSeq[2] = makeAny( aPropValue );
+
+ xInit->initialize( aPropSeq );
+ }
+
+ return Reference< XInterface >( m_xModuleImageManager, UNO_QUERY );
+}
+
+Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getShortCutManager() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ Reference< XMultiServiceFactory > xSMGR = m_xServiceManager;
+ ::rtl::OUString aModule = m_aModuleIdentifier;
+
+ if ( !m_xModuleAcceleratorManager.is() )
+ {
+ Reference< XInterface > xManager = xSMGR->createInstance(SERVICENAME_MODULEACCELERATORCONFIGURATION);
+ Reference< XInitialization > xInit (xManager, UNO_QUERY_THROW);
+
+ PropertyValue aProp;
+ aProp.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleIdentifier"));
+ aProp.Value <<= aModule;
+
+ Sequence< Any > lArgs(1);
+ lArgs[0] <<= aProp;
+
+ xInit->initialize(lArgs);
+ m_xModuleAcceleratorManager = Reference< XInterface >( xManager, UNO_QUERY );
+ }
+
+ return m_xModuleAcceleratorManager;
+}
+
+Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getEventsManager() throw (::com::sun::star::uno::RuntimeException)
+{
+ return Reference< XInterface >();
+}
+
+// XModuleUIConfigurationManager
+sal_Bool SAL_CALL ModuleUIConfigurationManager::isDefaultSettings( const ::rtl::OUString& ResourceURL )
+throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
+ if ( pDataSettings && pDataSettings->bDefaultNode )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+Reference< XIndexAccess > SAL_CALL ModuleUIConfigurationManager::getDefaultSettings( const ::rtl::OUString& ResourceURL )
+throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ // preload list of element types on demand
+ impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
+
+ // Look into our default vector/boost::unordered_map combination
+ UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rDefaultHashMap.find( ResourceURL );
+ if ( pIter != rDefaultHashMap.end() )
+ {
+ if ( !pIter->second.xSettings.is() )
+ impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
+ return pIter->second.xSettings;
+ }
+ }
+
+ // Nothing has been found!
+ throw NoSuchElementException();
+}
+
+// XUIConfigurationPersistence
+void SAL_CALL ModuleUIConfigurationManager::reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
+ {
+ // Try to access our module sub folder
+ ConfigEventNotifyContainer aRemoveNotifyContainer;
+ ConfigEventNotifyContainer aReplaceNotifyContainer;
+ for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ try
+ {
+ UIElementType& rUserElementType = m_aUIElements[LAYER_USERDEFINED][i];
+ UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][i];
+
+ if ( rUserElementType.bModified )
+ impl_reloadElementTypeData( rUserElementType, rDefaultElementType, aRemoveNotifyContainer, aReplaceNotifyContainer );
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ m_bModified = sal_False;
+
+ // Unlock mutex before notify our listeners
+ aGuard.unlock();
+
+ // Notify our listeners
+ for ( sal_uInt32 j = 0; j < aRemoveNotifyContainer.size(); j++ )
+ implts_notifyContainerListener( aRemoveNotifyContainer[j], NotifyOp_Remove );
+ for ( sal_uInt32 k = 0; k < aReplaceNotifyContainer.size(); k++ )
+ implts_notifyContainerListener( aReplaceNotifyContainer[k], NotifyOp_Replace );
+ }
+}
+
+void SAL_CALL ModuleUIConfigurationManager::store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
+ {
+ // Try to access our module sub folder
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ try
+ {
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i];
+ Reference< XStorage > xStorage( rElementType.xStorage, UNO_QUERY );
+
+ if ( rElementType.bModified && xStorage.is() )
+ {
+ impl_storeElementTypeData( xStorage, rElementType );
+ m_pStorageHandler[i]->commitUserChanges();
+ }
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ m_bModified = false;
+ }
+}
+
+void SAL_CALL ModuleUIConfigurationManager::storeToStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
+ {
+ // Try to access our module sub folder
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ try
+ {
+ Reference< XStorage > xElementTypeStorage( Storage->openStorageElement(
+ OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), ElementModes::READWRITE ));
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i];
+
+ if ( rElementType.bModified && xElementTypeStorage.is() )
+ impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag!
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+ }
+}
+
+sal_Bool SAL_CALL ModuleUIConfigurationManager::isModified() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ return m_bModified;
+}
+
+sal_Bool SAL_CALL ModuleUIConfigurationManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ return m_bReadOnly;
+}
+
+void ModuleUIConfigurationManager::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp )
+{
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >*) NULL ) );
+ if ( pContainer != NULL )
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
+ while ( pIterator.hasMoreElements() )
+ {
+ try
+ {
+ switch ( eOp )
+ {
+ case NotifyOp_Replace:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementReplaced( aEvent );
+ break;
+ case NotifyOp_Insert:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementInserted( aEvent );
+ break;
+ case NotifyOp_Remove:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementRemoved( aEvent );
+ break;
+ }
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/uicategorydescription.cxx b/framework/source/uiconfiguration/uicategorydescription.cxx
new file mode 100644
index 000000000000..1a04cf285ab1
--- /dev/null
+++ b/framework/source/uiconfiguration/uicategorydescription.cxx
@@ -0,0 +1,478 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "uiconfiguration/uicategorydescription.hxx"
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+#include "properties.h"
+
+#include "helper/mischelper.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <unotools/configmgr.hxx>
+#include <tools/string.hxx>
+
+#include <vcl/mnemonic.hxx>
+#include <comphelper/sequence.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::frame;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+struct ModuleToCategory
+{
+ const char* pModuleId;
+ const char* pCommands;
+};
+
+static const char CATEGORY[] = "Category";
+static const char GENERIC_MODULE_NAME[] = "generic";
+static const char CONFIGURATION_ROOT_ACCESS[] = "/org.openoffice.Office.UI.";
+static const char CONFIGURATION_CATEGORY_ELEMENT_ACCESS[] = "/Commands/Categories";
+static const char CONFIGURATION_PROPERTY_NAME[] = "Name";
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// Configuration access class for PopupMenuControllerFactory implementation
+//*****************************************************************************************************************
+
+class ConfigurationAccess_UICategory : // Order is neccessary for right initialization!
+ private ThreadHelpBase ,
+ public ::cppu::WeakImplHelper2<XNameAccess,XContainerListener>
+{
+ public:
+ ConfigurationAccess_UICategory( const ::rtl::OUString& aModuleName, const Reference< XNameAccess >& xGenericUICommands, const Reference< XMultiServiceFactory >& rServiceManager );
+ virtual ~ConfigurationAccess_UICategory();
+
+ // XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasElements()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // container.XContainerListener
+ virtual void SAL_CALL elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException);
+ virtual void SAL_CALL elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException);
+ virtual void SAL_CALL elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException);
+
+ // lang.XEventListener
+ virtual void SAL_CALL disposing( const EventObject& aEvent ) throw(RuntimeException);
+
+ protected:
+ Any getUINameFromID( const rtl::OUString& rId );
+ Any getUINameFromCache( const rtl::OUString& rId );
+ Sequence< rtl::OUString > getAllIds();
+ sal_Bool fillCache();
+
+ private:
+ typedef ::boost::unordered_map< ::rtl::OUString,
+ ::rtl::OUString,
+ OUStringHashCode,
+ ::std::equal_to< ::rtl::OUString > > IdToInfoCache;
+
+ sal_Bool initializeConfigAccess();
+
+ rtl::OUString m_aConfigCategoryAccess;
+ rtl::OUString m_aPropUIName;
+ Reference< XNameAccess > m_xGenericUICategories;
+ Reference< XMultiServiceFactory > m_xServiceManager;
+ Reference< XMultiServiceFactory > m_xConfigProvider;
+ Reference< XNameAccess > m_xConfigAccess;
+ Reference< XContainerListener > m_xConfigListener;
+ sal_Bool m_bConfigAccessInitialized;
+ sal_Bool m_bCacheFilled;
+ IdToInfoCache m_aIdCache;
+};
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+
+ConfigurationAccess_UICategory::ConfigurationAccess_UICategory( const rtl::OUString& aModuleName, const Reference< XNameAccess >& rGenericUICategories, const Reference< XMultiServiceFactory >& rServiceManager ) :
+ ThreadHelpBase(),
+ m_aConfigCategoryAccess( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_ROOT_ACCESS )),
+ m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_PROPERTY_NAME )),
+ m_xGenericUICategories( rGenericUICategories ),
+ m_xServiceManager( rServiceManager ),
+ m_bConfigAccessInitialized( sal_False ),
+ m_bCacheFilled( sal_False )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::ConfigurationAccess_UICategory" );
+ // Create configuration hierachical access name
+ m_aConfigCategoryAccess += aModuleName;
+ m_aConfigCategoryAccess += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_CATEGORY_ELEMENT_ACCESS ));
+
+ m_xConfigProvider = Reference< XMultiServiceFactory >( rServiceManager->createInstance(SERVICENAME_CFGPROVIDER),UNO_QUERY );
+}
+
+ConfigurationAccess_UICategory::~ConfigurationAccess_UICategory()
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ xContainer->removeContainerListener(m_xConfigListener);
+}
+
+// XNameAccess
+Any SAL_CALL ConfigurationAccess_UICategory::getByName( const ::rtl::OUString& rId )
+throw ( NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getByName" );
+ ResetableGuard aLock( m_aLock );
+ if ( !m_bConfigAccessInitialized )
+ {
+ initializeConfigAccess();
+ m_bConfigAccessInitialized = sal_True;
+ fillCache();
+ }
+
+ // SAFE
+ Any a = getUINameFromID( rId );
+
+ if ( !a.hasValue() )
+ throw NoSuchElementException();
+
+ return a;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ConfigurationAccess_UICategory::getElementNames()
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getElementNames" );
+ return getAllIds();
+}
+
+sal_Bool SAL_CALL ConfigurationAccess_UICategory::hasByName( const ::rtl::OUString& rId )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::hasByName" );
+ return getByName( rId ).hasValue();
+}
+
+// XElementAccess
+Type SAL_CALL ConfigurationAccess_UICategory::getElementType()
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getElementType" );
+ return( ::getCppuType( (const rtl::OUString*)NULL ) );
+}
+
+sal_Bool SAL_CALL ConfigurationAccess_UICategory::hasElements()
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::hasElements" );
+ // There must be global categories!
+ return sal_True;
+}
+
+sal_Bool ConfigurationAccess_UICategory::fillCache()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::fillCache" );
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ConfigurationAccess_UICategory::fillCache" );
+
+ if ( m_bCacheFilled )
+ return sal_True;
+
+ sal_Int32 i( 0 );
+ rtl::OUString aUIName;
+ Sequence< ::rtl::OUString > aNameSeq = m_xConfigAccess->getElementNames();
+
+ for ( i = 0; i < aNameSeq.getLength(); i++ )
+ {
+ try
+ {
+ Reference< XNameAccess > xNameAccess(m_xConfigAccess->getByName( aNameSeq[i] ),UNO_QUERY);
+ if ( xNameAccess.is() )
+ {
+ xNameAccess->getByName( m_aPropUIName ) >>= aUIName;
+
+ m_aIdCache.insert( IdToInfoCache::value_type( aNameSeq[i], aUIName ));
+ }
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ }
+
+ m_bCacheFilled = sal_True;
+
+ return sal_True;
+}
+
+Any ConfigurationAccess_UICategory::getUINameFromID( const rtl::OUString& rId )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getUINameFromID" );
+ Any a;
+
+ try
+ {
+ a = getUINameFromCache( rId );
+ if ( !a.hasValue() )
+ {
+ // Try to ask our global commands configuration access
+ if ( m_xGenericUICategories.is() )
+ {
+ try
+ {
+ return m_xGenericUICategories->getByName( rId );
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ }
+ }
+ }
+ catch( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+
+ return a;
+}
+
+Any ConfigurationAccess_UICategory::getUINameFromCache( const rtl::OUString& rId )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getUINameFromCache" );
+ Any a;
+
+ IdToInfoCache::const_iterator pIter = m_aIdCache.find( rId );
+ if ( pIter != m_aIdCache.end() )
+ a <<= pIter->second;
+
+ return a;
+}
+
+Sequence< rtl::OUString > ConfigurationAccess_UICategory::getAllIds()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::getAllIds" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigAccessInitialized )
+ {
+ initializeConfigAccess();
+ m_bConfigAccessInitialized = sal_True;
+ fillCache();
+ }
+
+ if ( m_xConfigAccess.is() )
+ {
+ Any a;
+ Reference< XNameAccess > xNameAccess;
+
+ try
+ {
+ Sequence< ::rtl::OUString > aNameSeq = m_xConfigAccess->getElementNames();
+
+ if ( m_xGenericUICategories.is() )
+ {
+ // Create concat list of supported user interface commands of the module
+ Sequence< ::rtl::OUString > aGenericNameSeq = m_xGenericUICategories->getElementNames();
+ sal_uInt32 nCount1 = aNameSeq.getLength();
+ sal_uInt32 nCount2 = aGenericNameSeq.getLength();
+
+ aNameSeq.realloc( nCount1 + nCount2 );
+ ::rtl::OUString* pNameSeq = aNameSeq.getArray();
+ const ::rtl::OUString* pGenericSeq = aGenericNameSeq.getConstArray();
+ for ( sal_uInt32 i = 0; i < nCount2; i++ )
+ pNameSeq[nCount1+i] = pGenericSeq[i];
+ }
+
+ return aNameSeq;
+ }
+ catch( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+
+ return Sequence< rtl::OUString >();
+}
+
+sal_Bool ConfigurationAccess_UICategory::initializeConfigAccess()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::initializeConfigAccess" );
+ Sequence< Any > aArgs( 1 );
+ PropertyValue aPropValue;
+
+ try
+ {
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
+ aPropValue.Value <<= m_aConfigCategoryAccess;
+ aArgs[0] <<= aPropValue;
+
+ m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ),UNO_QUERY );
+ if ( m_xConfigAccess.is() )
+ {
+ // Add as container listener
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ {
+ m_xConfigListener = new WeakContainerListener(this);
+ xContainer->addContainerListener(m_xConfigListener);
+ }
+ }
+
+ return sal_True;
+ }
+ catch ( WrappedTargetException& )
+ {
+ }
+ catch ( Exception& )
+ {
+ }
+
+ return sal_False;
+}
+
+// container.XContainerListener
+void SAL_CALL ConfigurationAccess_UICategory::elementInserted( const ContainerEvent& ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementInserted" );
+}
+
+void SAL_CALL ConfigurationAccess_UICategory::elementRemoved ( const ContainerEvent& ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementRemoved " );
+}
+
+void SAL_CALL ConfigurationAccess_UICategory::elementReplaced( const ContainerEvent& ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::elementReplaced" );
+}
+
+// lang.XEventListener
+void SAL_CALL ConfigurationAccess_UICategory::disposing( const EventObject& aEvent ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_UICategory::disposing" );
+ // SAFE
+ // remove our reference to the config access
+ ResetableGuard aLock( m_aLock );
+
+ Reference< XInterface > xIfac1( aEvent.Source, UNO_QUERY );
+ Reference< XInterface > xIfac2( m_xConfigAccess, UNO_QUERY );
+ if ( xIfac1 == xIfac2 )
+ m_xConfigAccess.clear();
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( UICategoryDescription ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_UICATEGORYDESCRIPTION ,
+ IMPLEMENTATIONNAME_UICATEGORYDESCRIPTION
+ )
+
+DEFINE_INIT_SERVICE ( UICategoryDescription, {} )
+
+UICategoryDescription::UICategoryDescription( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ UICommandDescription(xServiceManager,true)
+{
+ Reference< XNameAccess > xEmpty;
+ rtl::OUString aGenericCategories( RTL_CONSTASCII_USTRINGPARAM( "GenericCategories" ));
+ m_xGenericUICommands = new ConfigurationAccess_UICategory( aGenericCategories, xEmpty, xServiceManager );
+
+ // insert generic categories mappings
+ m_aModuleToCommandFileMap.insert( ModuleToCommandFileMap::value_type(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( GENERIC_MODULE_NAME )), aGenericCategories ));
+
+ UICommandsHashMap::iterator pCatIter = m_aUICommandsHashMap.find( aGenericCategories );
+ if ( pCatIter != m_aUICommandsHashMap.end() )
+ pCatIter->second = m_xGenericUICommands;
+
+ impl_fillElements("ooSetupFactoryCmdCategoryConfigRef");
+}
+
+UICategoryDescription::~UICategoryDescription()
+{
+}
+Reference< XNameAccess > UICategoryDescription::impl_createConfigAccess(const ::rtl::OUString& _sName)
+{
+ return new ConfigurationAccess_UICategory( _sName,m_xGenericUICommands,m_xServiceManager );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/uiconfigurationmanager.cxx b/framework/source/uiconfiguration/uiconfigurationmanager.cxx
new file mode 100644
index 000000000000..d52bcffcb8ed
--- /dev/null
+++ b/framework/source/uiconfiguration/uiconfigurationmanager.cxx
@@ -0,0 +1,1354 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uiconfiguration/uiconfigurationmanager.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <services.h>
+#include <uielement/rootitemcontainer.hxx>
+#include <uielement/constitemcontainer.hxx>
+#include <uielement/uielementtypenames.hxx>
+#include <framework/menuconfiguration.hxx>
+#include <framework/toolboxconfiguration.hxx>
+
+#include <framework/statusbarconfiguration.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/ui/ConfigurationEvent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/io/XStream.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+using namespace com::sun::star::embed;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_7 ( UIConfigurationManager ,
+ OWeakObject ,
+ DIRECT_INTERFACE( css::lang::XTypeProvider ),
+ DIRECT_INTERFACE( css::lang::XServiceInfo ),
+ DIRECT_INTERFACE( css::lang::XComponent ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfiguration ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationManager ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationPersistence ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationStorage )
+ )
+
+DEFINE_XTYPEPROVIDER_7 ( UIConfigurationManager ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::lang::XComponent ,
+ ::com::sun::star::ui::XUIConfiguration ,
+ ::com::sun::star::ui::XUIConfigurationManager ,
+ ::com::sun::star::ui::XUIConfigurationPersistence ,
+ ::com::sun::star::ui::XUIConfigurationStorage
+ )
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( UIConfigurationManager ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_UICONFIGURATIONMANAGER ,
+ IMPLEMENTATIONNAME_UICONFIGURATIONMANAGER
+ )
+
+DEFINE_INIT_SERVICE ( UIConfigurationManager, {} )
+
+
+// important: The order and position of the elements must match the constant
+// definition of "::com::sun::star::ui::UIElementType"
+static const char* UIELEMENTTYPENAMES[] =
+{
+ "", // Dummy value for unknown!
+ UIELEMENTTYPE_MENUBAR_NAME,
+ UIELEMENTTYPE_POPUPMENU_NAME,
+ UIELEMENTTYPE_TOOLBAR_NAME,
+ UIELEMENTTYPE_STATUSBAR_NAME,
+ UIELEMENTTYPE_FLOATINGWINDOW_NAME,
+ UIELEMENTTYPE_PROGRESSBAR_NAME,
+ UIELEMENTTYPE_TOOLPANEL_NAME
+};
+
+static const char RESOURCEURL_PREFIX[] = "private:resource/";
+static const sal_Int32 RESOURCEURL_PREFIX_SIZE = 17;
+
+static sal_Int16 RetrieveTypeFromResourceURL( const rtl::OUString& aResourceURL )
+{
+
+ if (( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) &&
+ ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
+ {
+ rtl::OUString aTmpStr = aResourceURL.copy( RESOURCEURL_PREFIX_SIZE );
+ sal_Int32 nIndex = aTmpStr.indexOf( '/' );
+ if (( nIndex > 0 ) && ( aTmpStr.getLength() > nIndex ))
+ {
+ rtl::OUString aTypeStr( aTmpStr.copy( 0, nIndex ));
+ for ( int i = 0; i < UIElementType::COUNT; i++ )
+ {
+ if ( aTypeStr.equalsAscii( UIELEMENTTYPENAMES[i] ))
+ return sal_Int16( i );
+ }
+ }
+ }
+
+ return UIElementType::UNKNOWN;
+}
+
+static rtl::OUString RetrieveNameFromResourceURL( const rtl::OUString& aResourceURL )
+{
+ if (( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) &&
+ ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
+ {
+ sal_Int32 nIndex = aResourceURL.lastIndexOf( '/' );
+ if (( nIndex > 0 ) && (( nIndex+1 ) < aResourceURL.getLength()))
+ return aResourceURL.copy( nIndex+1 );
+ }
+
+ return rtl::OUString();
+}
+
+void UIConfigurationManager::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType )
+{
+ // preload list of element types on demand
+ impl_preloadUIElementTypeList( nElementType );
+
+ UIElementDataHashMap& rUserElements = m_aUIElements[nElementType].aElementsHashMap;
+ UIElementDataHashMap::const_iterator pUserIter = rUserElements.begin();
+
+ while ( pUserIter != rUserElements.end() )
+ {
+ UIElementData* pDataSettings = impl_findUIElementData( pUserIter->second.aResourceURL, nElementType );
+ if ( pDataSettings && !pDataSettings->bDefault )
+ {
+ // Retrieve user interface name from XPropertySet interface
+ rtl::OUString aUIName;
+ Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ Any a = xPropSet->getPropertyValue( m_aPropUIName );
+ a >>= aUIName;
+ }
+
+ UIElementInfo aInfo( pUserIter->second.aResourceURL, aUIName );
+ aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo ));
+ }
+ ++pUserIter;
+ }
+}
+
+void UIConfigurationManager::impl_preloadUIElementTypeList( sal_Int16 nElementType )
+{
+ UIElementType& rElementTypeData = m_aUIElements[nElementType];
+
+ if ( !rElementTypeData.bLoaded )
+ {
+ Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
+ if ( xElementTypeStorage.is() )
+ {
+ rtl::OUStringBuffer aBuf( RESOURCEURL_PREFIX_SIZE );
+ aBuf.appendAscii( RESOURCEURL_PREFIX );
+ aBuf.appendAscii( UIELEMENTTYPENAMES[ nElementType ] );
+ aBuf.appendAscii( "/" );
+ rtl::OUString aResURLPrefix( aBuf.makeStringAndClear() );
+
+ UIElementDataHashMap& rHashMap = rElementTypeData.aElementsHashMap;
+ Reference< XNameAccess > xNameAccess( xElementTypeStorage, UNO_QUERY );
+ Sequence< rtl::OUString > aUIElementNames = xNameAccess->getElementNames();
+ for ( sal_Int32 n = 0; n < aUIElementNames.getLength(); n++ )
+ {
+ UIElementData aUIElementData;
+
+ // Resource name must be without ".xml"
+ sal_Int32 nIndex = aUIElementNames[n].lastIndexOf( '.' );
+ if (( nIndex > 0 ) && ( nIndex < aUIElementNames[n].getLength() ))
+ {
+ rtl::OUString aExtension( aUIElementNames[n].copy( nIndex+1 ));
+ rtl::OUString aUIElementName( aUIElementNames[n].copy( 0, nIndex ));
+
+ if (( aUIElementName.getLength() > 0 ) &&
+ ( aExtension.equalsIgnoreAsciiCaseAsciiL( "xml", 3 )))
+ {
+ aUIElementData.aResourceURL = aResURLPrefix + aUIElementName;
+ aUIElementData.aName = aUIElementNames[n];
+ aUIElementData.bModified = false;
+ aUIElementData.bDefault = false;
+
+ // Create boost::unordered_map entries for all user interface elements inside the storage. We don't load the
+ // settings to speed up the process.
+ rHashMap.insert( UIElementDataHashMap::value_type( aUIElementData.aResourceURL, aUIElementData ));
+ }
+ }
+ }
+ }
+ }
+
+ rElementTypeData.bLoaded = true;
+}
+
+void UIConfigurationManager::impl_requestUIElementData( sal_Int16 nElementType, UIElementData& aUIElementData )
+{
+ UIElementType& rElementTypeData = m_aUIElements[nElementType];
+
+ Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
+ if ( xElementTypeStorage.is() && aUIElementData.aName.getLength() )
+ {
+ try
+ {
+ Reference< XStream > xStream = xElementTypeStorage->openStreamElement( aUIElementData.aName, ElementModes::READ );
+ Reference< XInputStream > xInputStream = xStream->getInputStream();
+
+ if ( xInputStream.is() )
+ {
+ switch ( nElementType )
+ {
+ case ::com::sun::star::ui::UIElementType::UNKNOWN:
+ break;
+
+ case ::com::sun::star::ui::UIElementType::MENUBAR:
+ {
+ try
+ {
+ MenuConfiguration aMenuCfg( m_xServiceManager );
+ Reference< XIndexAccess > xContainer( aMenuCfg.CreateMenuBarConfigurationFromXML( xInputStream ));
+ RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xContainer );
+ if ( pRootItemContainer )
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY );
+ else
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xContainer, sal_True ) ), UNO_QUERY );
+ return;
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ case ::com::sun::star::ui::UIElementType::POPUPMENU:
+ {
+ break;
+ }
+
+ case ::com::sun::star::ui::UIElementType::TOOLBAR:
+ {
+ try
+ {
+ Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
+ ToolBoxConfiguration::LoadToolBox( m_xServiceManager, xInputStream, xIndexContainer );
+ RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY );
+ return;
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+
+ break;
+ }
+
+ case ::com::sun::star::ui::UIElementType::STATUSBAR:
+ {
+ try
+ {
+ Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
+ StatusBarConfiguration::LoadStatusBar( m_xServiceManager, xInputStream, xIndexContainer );
+ RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY );
+ return;
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+
+ break;
+ }
+
+ case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW:
+ {
+ break;
+ }
+ }
+ }
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+ }
+
+ // At least we provide an empty settings container!
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer()), UNO_QUERY );
+}
+
+UIConfigurationManager::UIElementData* UIConfigurationManager::impl_findUIElementData( const rtl::OUString& aResourceURL, sal_Int16 nElementType, bool bLoad )
+{
+ // preload list of element types on demand
+ impl_preloadUIElementTypeList( nElementType );
+
+ // try to look into our document vector/boost::unordered_map combination
+ UIElementDataHashMap& rUserHashMap = m_aUIElements[nElementType].aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rUserHashMap.find( aResourceURL );
+ if ( pIter != rUserHashMap.end() )
+ {
+ // Default data settings data means removed!
+ if ( pIter->second.bDefault )
+ return &(pIter->second);
+ else
+ {
+ if ( !pIter->second.xSettings.is() && bLoad )
+ impl_requestUIElementData( nElementType, pIter->second );
+ return &(pIter->second);
+ }
+ }
+
+ // Nothing has been found!
+ return NULL;
+}
+
+void UIConfigurationManager::impl_storeElementTypeData( Reference< XStorage >& xStorage, UIElementType& rElementType, bool bResetModifyState )
+{
+ UIElementDataHashMap& rHashMap = rElementType.aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rHashMap.begin();
+
+ while ( pIter != rHashMap.end() )
+ {
+ UIElementData& rElement = pIter->second;
+ if ( rElement.bModified )
+ {
+ if ( rElement.bDefault )
+ {
+ xStorage->removeElement( rElement.aName );
+ rElement.bModified = sal_False; // mark as not modified
+ }
+ else
+ {
+ Reference< XStream > xStream( xStorage->openStreamElement( rElement.aName, ElementModes::WRITE|ElementModes::TRUNCATE ), UNO_QUERY );
+ Reference< XOutputStream > xOutputStream( xStream->getOutputStream() );
+
+ if ( xOutputStream.is() )
+ {
+ switch( rElementType.nElementType )
+ {
+ case ::com::sun::star::ui::UIElementType::MENUBAR:
+ {
+ try
+ {
+ MenuConfiguration aMenuCfg( m_xServiceManager );
+ aMenuCfg.StoreMenuBarConfigurationToXML( rElement.xSettings, xOutputStream );
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ case ::com::sun::star::ui::UIElementType::TOOLBAR:
+ {
+ try
+ {
+ ToolBoxConfiguration::StoreToolBox( m_xServiceManager, xOutputStream, rElement.xSettings );
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ case ::com::sun::star::ui::UIElementType::STATUSBAR:
+ {
+ try
+ {
+ StatusBarConfiguration::StoreStatusBar( m_xServiceManager, xOutputStream, rElement.xSettings );
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // mark as not modified if we store to our own storage
+ if ( bResetModifyState )
+ rElement.bModified = sal_False;
+ }
+ }
+
+ ++pIter;
+ }
+
+ // commit element type storage
+ Reference< XTransactedObject > xTransactedObject( xStorage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+
+ // mark UIElementType as not modified if we store to our own storage
+ if ( bResetModifyState )
+ rElementType.bModified = sal_False;
+}
+
+void UIConfigurationManager::impl_resetElementTypeData(
+ UIElementType& rDocElementType,
+ ConfigEventNotifyContainer& rRemoveNotifyContainer )
+{
+ UIElementDataHashMap& rHashMap = rDocElementType.aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rHashMap.begin();
+
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+
+ // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling
+ // our listeners!
+ while ( pIter != rHashMap.end() )
+ {
+ UIElementData& rElement = pIter->second;
+ if ( !rElement.bDefault )
+ {
+ // Remove user-defined settings from document
+ ConfigurationEvent aEvent;
+ aEvent.ResourceURL = rElement.aResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = xIfac;
+ aEvent.Element <<= rElement.xSettings;
+
+ rRemoveNotifyContainer.push_back( aEvent );
+
+ // Mark element as default.
+ rElement.bModified = false;
+ rElement.bDefault = true;
+ }
+ else
+ rElement.bModified = false;
+
+ ++pIter;
+ }
+
+ // Remove all settings from our user interface elements
+ rHashMap.clear();
+}
+
+void UIConfigurationManager::impl_reloadElementTypeData(
+ UIElementType& rDocElementType,
+ ConfigEventNotifyContainer& rRemoveNotifyContainer,
+ ConfigEventNotifyContainer& rReplaceNotifyContainer )
+{
+ UIElementDataHashMap& rHashMap = rDocElementType.aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rHashMap.begin();
+ Reference< XStorage > xElementStorage( rDocElementType.xStorage );
+ Reference< XNameAccess > xElementNameAccess( xElementStorage, UNO_QUERY );
+
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+ sal_Int16 nType = rDocElementType.nElementType;
+
+ while ( pIter != rHashMap.end() )
+ {
+ UIElementData& rElement = pIter->second;
+ if ( rElement.bModified )
+ {
+ if ( xElementNameAccess->hasByName( rElement.aName ))
+ {
+ // Replace settings with data from user layer
+ Reference< XIndexAccess > xOldSettings( rElement.xSettings );
+
+ impl_requestUIElementData( nType, rElement );
+
+ ConfigurationEvent aReplaceEvent;
+
+ aReplaceEvent.ResourceURL = rElement.aResourceURL;
+ aReplaceEvent.Accessor <<= xThis;
+ aReplaceEvent.Source = xIfac;
+ aReplaceEvent.ReplacedElement <<= xOldSettings;
+ aReplaceEvent.Element <<= rElement.xSettings;
+ rReplaceNotifyContainer.push_back( aReplaceEvent );
+
+ rElement.bModified = false;
+ }
+ else
+ {
+ // Element settings are not in any storage => remove
+ ConfigurationEvent aRemoveEvent;
+
+ aRemoveEvent.ResourceURL = rElement.aResourceURL;
+ aRemoveEvent.Accessor <<= xThis;
+ aRemoveEvent.Source = xIfac;
+ aRemoveEvent.Element <<= rElement.xSettings;
+
+ rRemoveNotifyContainer.push_back( aRemoveEvent );
+
+ // Mark element as default and not modified. That means "not active" in the document anymore
+ rElement.bModified = false;
+ rElement.bDefault = true;
+ }
+ }
+ ++pIter;
+ }
+
+ rDocElementType.bModified = sal_False;
+}
+
+void UIConfigurationManager::impl_Initialize()
+{
+ // Initialize the top-level structures with the storage data
+ if ( m_xDocConfigStorage.is() )
+ {
+ long nModes = m_bReadOnly ? ElementModes::READ : ElementModes::READWRITE;
+
+ // Try to access our module sub folder
+ for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT;
+ i++ )
+ {
+ Reference< XStorage > xElementTypeStorage;
+ try
+ {
+ xElementTypeStorage = m_xDocConfigStorage->openStorageElement( rtl::OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), nModes );
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+
+ m_aUIElements[i].nElementType = i;
+ m_aUIElements[i].bModified = false;
+ m_aUIElements[i].xStorage = xElementTypeStorage;
+ m_aUIElements[i].bDefaultLayer = false;
+ }
+ }
+ else
+ {
+ // We have no storage, just initialize ui element types with empty storage!
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ m_aUIElements[i].xStorage = m_xDocConfigStorage;
+ }
+}
+
+UIConfigurationManager::UIConfigurationManager( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xServiceManager ) :
+ ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_xDocConfigStorage( 0 )
+ , m_bReadOnly( true )
+ , m_bInitialized( false )
+ , m_bModified( false )
+ , m_bConfigRead( false )
+ , m_bDisposed( false )
+ , m_aXMLPostfix( RTL_CONSTASCII_USTRINGPARAM( ".xml" ))
+ , m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))
+ , m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ))
+ , m_xServiceManager( xServiceManager )
+ , m_aListenerContainer( m_aLock.getShareableOslMutex() )
+{
+ // Make sure we have a default initialized entry for every layer and user interface element type!
+ // The following code depends on this!
+ m_aUIElements.resize( ::com::sun::star::ui::UIElementType::COUNT );
+}
+
+UIConfigurationManager::~UIConfigurationManager()
+{
+}
+
+// XComponent
+void SAL_CALL UIConfigurationManager::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ css::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ {
+ ResetableGuard aGuard( m_aLock );
+ try
+ {
+ if ( m_xImageManager.is() )
+ m_xImageManager->dispose();
+ }
+ catch ( Exception& )
+ {
+ }
+
+ m_xImageManager.clear();
+ m_aUIElements.clear();
+ m_xDocConfigStorage.clear();
+ m_bConfigRead = false;
+ m_bModified = false;
+ m_bDisposed = true;
+ }
+}
+
+void SAL_CALL UIConfigurationManager::addEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL UIConfigurationManager::removeEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+// XUIConfigurationManager
+void SAL_CALL UIConfigurationManager::addConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL UIConfigurationManager::removeConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener );
+}
+
+
+void SAL_CALL UIConfigurationManager::reset() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( isReadOnly() )
+ return;
+
+ if ( m_xDocConfigStorage.is() )
+ {
+ try
+ {
+ // Remove all elements from our user-defined storage!
+ bool bCommit( false );
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ UIElementType& rElementType = m_aUIElements[i];
+ Reference< XStorage > xSubStorage( rElementType.xStorage, UNO_QUERY );
+
+ if ( xSubStorage.is() )
+ {
+ bool bCommitSubStorage( false );
+ Reference< XNameAccess > xSubStorageNameAccess( xSubStorage, UNO_QUERY );
+ Sequence< rtl::OUString > aUIElementStreamNames = xSubStorageNameAccess->getElementNames();
+ for ( sal_Int32 j = 0; j < aUIElementStreamNames.getLength(); j++ )
+ {
+ xSubStorage->removeElement( aUIElementStreamNames[j] );
+ bCommitSubStorage = true;
+ bCommit = true;
+ }
+
+ if ( bCommitSubStorage )
+ {
+ Reference< XTransactedObject > xTransactedObject( xSubStorage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+ }
+ }
+ }
+
+ // Commit changes
+ if ( bCommit )
+ {
+ Reference< XTransactedObject > xTransactedObject( m_xDocConfigStorage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+ }
+
+ // remove settings from user defined layer and notify listener about removed settings data!
+ // Try to access our module sub folder
+ ConfigEventNotifyContainer aRemoveEventNotifyContainer;
+ for ( sal_Int16 j = 1; j < ::com::sun::star::ui::UIElementType::COUNT; j++ )
+ {
+ UIElementType& rDocElementType = m_aUIElements[j];
+
+ impl_resetElementTypeData( rDocElementType, aRemoveEventNotifyContainer );
+ rDocElementType.bModified = sal_False;
+ }
+
+ m_bModified = sal_False;
+
+ // Unlock mutex before notify our listeners
+ aGuard.unlock();
+
+ // Notify our listeners
+ for ( sal_uInt32 k = 0; k < aRemoveEventNotifyContainer.size(); k++ )
+ implts_notifyContainerListener( aRemoveEventNotifyContainer[k], NotifyOp_Remove );
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+ }
+}
+
+Sequence< Sequence< PropertyValue > > SAL_CALL UIConfigurationManager::getUIElementsInfo( sal_Int16 ElementType )
+throw ( IllegalArgumentException, RuntimeException )
+{
+ if (( ElementType < 0 ) || ( ElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+
+ ResetableGuard aGuard( m_aLock );
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ Sequence< Sequence< PropertyValue > > aElementInfoSeq;
+ UIElementInfoHashMap aUIElementInfoCollection;
+
+ if ( ElementType == ::com::sun::star::ui::UIElementType::UNKNOWN )
+ {
+ for ( sal_Int16 i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, sal_Int16( i ) );
+ }
+ else
+ impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType );
+
+ Sequence< PropertyValue > aUIElementInfo( 2 );
+ aUIElementInfo[0].Name = m_aPropResourceURL;
+ aUIElementInfo[1].Name = m_aPropUIName;
+
+ aElementInfoSeq.realloc( aUIElementInfoCollection.size() );
+ UIElementInfoHashMap::const_iterator pIter = aUIElementInfoCollection.begin();
+
+ sal_Int32 n = 0;
+ while ( pIter != aUIElementInfoCollection.end() )
+ {
+ aUIElementInfo[0].Value <<= pIter->second.aResourceURL;
+ aUIElementInfo[1].Value <<= pIter->second.aUIName;
+ aElementInfoSeq[n++] = aUIElementInfo;
+ ++pIter;
+ }
+
+ return aElementInfoSeq;
+}
+
+Reference< XIndexContainer > SAL_CALL UIConfigurationManager::createSettings() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ // Creates an empty item container which can be filled from outside
+ return Reference< XIndexContainer >( static_cast< OWeakObject * >( new RootItemContainer()), UNO_QUERY );
+}
+
+sal_Bool SAL_CALL UIConfigurationManager::hasSettings( const ::rtl::OUString& ResourceURL )
+throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else
+ {
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
+ if ( pDataSettings && !pDataSettings->bDefault )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+Reference< XIndexAccess > SAL_CALL UIConfigurationManager::getSettings( const ::rtl::OUString& ResourceURL, sal_Bool bWriteable )
+throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
+ if ( pDataSettings && !pDataSettings->bDefault )
+ {
+ // Create a copy of our data if someone wants to change the data.
+ if ( bWriteable )
+ return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( pDataSettings->xSettings ) ), UNO_QUERY );
+ else
+ return pDataSettings->xSettings;
+ }
+ }
+
+ throw NoSuchElementException();
+}
+
+void SAL_CALL UIConfigurationManager::replaceSettings( const ::rtl::OUString& ResourceURL, const Reference< ::com::sun::star::container::XIndexAccess >& aNewData )
+throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else if ( m_bReadOnly )
+ throw IllegalAccessException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
+ if ( pDataSettings && !pDataSettings->bDefault )
+ {
+ // we have a settings entry in our user-defined layer - replace
+ Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings;
+
+ // Create a copy of the data if the container is not const
+ Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
+ if ( xReplace.is() )
+ pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
+ else
+ pDataSettings->xSettings = aNewData;
+
+ pDataSettings->bDefault = false;
+ pDataSettings->bModified = true;
+ m_bModified = true;
+
+ // Modify type container
+ UIElementType& rElementType = m_aUIElements[nElementType];
+ rElementType.bModified = true;
+
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+
+ // Create event to notify listener about replaced element settings
+ ConfigurationEvent aEvent;
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+
+ aEvent.ResourceURL = ResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = xIfac;
+ aEvent.ReplacedElement <<= xOldSettings;
+ aEvent.Element <<= pDataSettings->xSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Replace );
+ }
+ else
+ throw NoSuchElementException();
+ }
+}
+
+void SAL_CALL UIConfigurationManager::removeSettings( const ::rtl::OUString& ResourceURL )
+throw ( NoSuchElementException, IllegalArgumentException, IllegalAccessException, RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else if ( m_bReadOnly )
+ throw IllegalAccessException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
+ if ( pDataSettings )
+ {
+ // If element settings are default, we don't need to change anything!
+ if ( pDataSettings->bDefault )
+ return;
+ else
+ {
+ Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings;
+ pDataSettings->bDefault = true;
+
+ // check if this is a default layer node
+ pDataSettings->bModified = true; // we have to remove this node from the user layer!
+ pDataSettings->xSettings.clear();
+ m_bModified = true; // user layer must be written
+
+ // Modify type container
+ UIElementType& rElementType = m_aUIElements[nElementType];
+ rElementType.bModified = true;
+
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+
+ // Create event to notify listener about removed element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = ResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = xIfac;
+ aEvent.Element <<= xRemovedSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Remove );
+ }
+ }
+ else
+ throw NoSuchElementException();
+ }
+}
+
+void SAL_CALL UIConfigurationManager::insertSettings( const ::rtl::OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData )
+throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, RuntimeException )
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else if ( m_bReadOnly )
+ throw IllegalAccessException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ bool bInsertData( false );
+ UIElementData aUIElementData;
+ UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType );
+
+ if ( pDataSettings && !pDataSettings->bDefault )
+ throw ElementExistException();
+
+ if ( !pDataSettings )
+ {
+ pDataSettings = &aUIElementData;
+ bInsertData = true;
+ }
+
+ {
+ pDataSettings->bDefault = false;
+ pDataSettings->bModified = true;
+
+ // Create a copy of the data if the container is not const
+ Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
+ if ( xReplace.is() )
+ pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
+ else
+ pDataSettings->xSettings = aNewData;
+
+ m_bModified = true;
+
+ UIElementType& rElementType = m_aUIElements[nElementType];
+ rElementType.bModified = true;
+
+ if ( bInsertData )
+ {
+ pDataSettings->aName = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix;
+ pDataSettings->aResourceURL = NewResourceURL;
+
+ UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
+ rElements.insert( UIElementDataHashMap::value_type( NewResourceURL, *pDataSettings ));
+ }
+
+ Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings );
+ Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XInterface > xIfac( xThis, UNO_QUERY );
+
+ // Create event to notify listener about removed element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = NewResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = xIfac;
+ aEvent.Element <<= xInsertSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Insert );
+ }
+ }
+}
+
+Reference< XInterface > SAL_CALL UIConfigurationManager::getImageManager() throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( !m_xImageManager.is() )
+ {
+ m_xImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ImageManager( m_xServiceManager )),
+ UNO_QUERY );
+ Reference< XInitialization > xInit( m_xImageManager, UNO_QUERY );
+
+ Sequence< Any > aPropSeq( 2 );
+ PropertyValue aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" ));
+ aPropValue.Value = makeAny( m_xDocConfigStorage );
+ aPropSeq[0] = makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
+ aPropValue.Value = makeAny( m_aModuleIdentifier );
+ aPropSeq[1] = makeAny( aPropValue );
+
+ xInit->initialize( aPropSeq );
+ }
+
+ return Reference< XInterface >( m_xImageManager, UNO_QUERY );
+}
+
+Reference< XInterface > SAL_CALL UIConfigurationManager::getShortCutManager() throw (::com::sun::star::uno::RuntimeException)
+{
+ // SAFE ->
+ ResetableGuard aGuard( m_aLock );
+
+ if (m_xAccConfig.is())
+ return m_xAccConfig;
+
+ Reference< XMultiServiceFactory > xSMGR = m_xServiceManager;
+ Reference< XStorage > xDocumentRoot = m_xDocConfigStorage;
+
+ aGuard.unlock();
+ // <- SAFE
+
+ Reference< XInterface > xAccConfig = xSMGR->createInstance(SERVICENAME_DOCUMENTACCELERATORCONFIGURATION);
+ Reference< XInitialization > xInit (xAccConfig, UNO_QUERY_THROW);
+
+ PropertyValue aProp;
+ aProp.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentRoot"));
+ aProp.Value <<= xDocumentRoot;
+
+ Sequence< Any > lArgs(1);
+ lArgs[0] <<= aProp;
+
+ xInit->initialize(lArgs);
+
+ // SAFE ->
+ aGuard.lock();
+ m_xAccConfig = xAccConfig;
+ aGuard.unlock();
+ // <- SAFE
+
+ return xAccConfig;
+}
+
+Reference< XInterface > SAL_CALL UIConfigurationManager::getEventsManager() throw (::com::sun::star::uno::RuntimeException)
+{
+ return Reference< XInterface >();
+}
+
+// XUIConfigurationStorage
+void SAL_CALL UIConfigurationManager::setStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xDocConfigStorage.is() )
+ {
+ try
+ {
+ // Dispose old storage to be sure that it will be closed
+ Reference< XComponent > xComponent( m_xDocConfigStorage, UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ // We store the new storage. Be careful it could be an empty reference!
+ m_xDocConfigStorage = Storage;
+ m_bReadOnly = sal_True;
+
+ Reference< XUIConfigurationStorage > xAccUpdate(m_xAccConfig, UNO_QUERY);
+ if ( xAccUpdate.is() )
+ xAccUpdate->setStorage( m_xDocConfigStorage );
+
+ if ( m_xImageManager.is() )
+ {
+ ImageManager* pImageManager = (ImageManager*)m_xImageManager.get();
+ if ( pImageManager )
+ pImageManager->setStorage( m_xDocConfigStorage );
+ }
+
+ if ( m_xDocConfigStorage.is() )
+ {
+ Reference< XPropertySet > xPropSet( m_xDocConfigStorage, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ long nOpenMode = 0;
+ Any a = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" )));
+ if ( a >>= nOpenMode )
+ m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
+ }
+ catch ( com::sun::star::beans::UnknownPropertyException& )
+ {
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ }
+
+ impl_Initialize();
+}
+
+sal_Bool SAL_CALL UIConfigurationManager::hasStorage() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ return ( m_xDocConfigStorage.is() );
+}
+
+// XUIConfigurationPersistence
+void SAL_CALL UIConfigurationManager::reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly )
+ {
+ // Try to access our module sub folder
+ ConfigEventNotifyContainer aRemoveNotifyContainer;
+ ConfigEventNotifyContainer aReplaceNotifyContainer;
+ for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ try
+ {
+ UIElementType& rDocElementType = m_aUIElements[i];
+ if ( rDocElementType.bModified )
+ impl_reloadElementTypeData( rDocElementType, aRemoveNotifyContainer, aReplaceNotifyContainer );
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ m_bModified = sal_False;
+
+ // Unlock mutex before notify our listeners
+ aGuard.unlock();
+
+ // Notify our listeners
+ for ( sal_uInt32 j = 0; j < aRemoveNotifyContainer.size(); j++ )
+ implts_notifyContainerListener( aRemoveNotifyContainer[j], NotifyOp_Remove );
+ for ( sal_uInt32 k = 0; k < aReplaceNotifyContainer.size(); k++ )
+ implts_notifyContainerListener( aReplaceNotifyContainer[k], NotifyOp_Replace );
+ }
+}
+
+void SAL_CALL UIConfigurationManager::store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly )
+ {
+ // Try to access our module sub folder
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ try
+ {
+ UIElementType& rElementType = m_aUIElements[i];
+ Reference< XStorage > xStorage( rElementType.xStorage, UNO_QUERY );
+
+ if ( rElementType.bModified && xStorage.is() )
+ impl_storeElementTypeData( xStorage, rElementType );
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ m_bModified = false;
+ Reference< XTransactedObject > xTransactedObject( m_xDocConfigStorage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+ }
+}
+
+void SAL_CALL UIConfigurationManager::storeToStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly )
+ {
+ // Try to access our module sub folder
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ try
+ {
+ Reference< XStorage > xElementTypeStorage( Storage->openStorageElement(
+ rtl::OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), ElementModes::READWRITE ));
+ UIElementType& rElementType = m_aUIElements[i];
+
+ if ( rElementType.bModified && xElementTypeStorage.is() )
+ impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag!
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+ }
+}
+
+sal_Bool SAL_CALL UIConfigurationManager::isModified() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ return m_bModified;
+}
+
+sal_Bool SAL_CALL UIConfigurationManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ return m_bReadOnly;
+}
+
+void UIConfigurationManager::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp )
+{
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >*) NULL ) );
+ if ( pContainer != NULL )
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
+ while ( pIterator.hasMoreElements() )
+ {
+ try
+ {
+ switch ( eOp )
+ {
+ case NotifyOp_Replace:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementReplaced( aEvent );
+ break;
+ case NotifyOp_Insert:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementInserted( aEvent );
+ break;
+ case NotifyOp_Remove:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementRemoved( aEvent );
+ break;
+ }
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/uiconfigurationmanagerimpl.cxx b/framework/source/uiconfiguration/uiconfigurationmanagerimpl.cxx
new file mode 100644
index 000000000000..46f919d37678
--- /dev/null
+++ b/framework/source/uiconfiguration/uiconfigurationmanagerimpl.cxx
@@ -0,0 +1,1704 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uiconfigurationmanagerimpl.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <services.h>
+#include <uielement/constitemcontainer.hxx>
+#include <uielement/rootitemcontainer.hxx>
+#include <uielement/uielementtypenames.hxx>
+#include <framework/menuconfiguration.hxx>
+#include <framework/toolboxconfiguration.hxx>
+#include <uiconfiguration/imagemanager.hxx>
+
+#include <framework/statusbarconfiguration.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/ui/ConfigurationEvent.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/io/XStream.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <boost/bind.hpp>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using rtl::OUString;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::io;
+using namespace com::sun::star::embed;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+using namespace ::com::sun::star::ui;
+using namespace ::cppu;
+
+namespace framework
+{
+
+
+// important: The order and position of the elements must match the constant
+// definition of "::com::sun::star::ui::UIElementType"
+static const char* UIELEMENTTYPENAMES[] =
+{
+ "", // Dummy value for unknown!
+ UIELEMENTTYPE_MENUBAR_NAME,
+ UIELEMENTTYPE_POPUPMENU_NAME,
+ UIELEMENTTYPE_TOOLBAR_NAME,
+ UIELEMENTTYPE_STATUSBAR_NAME,
+ UIELEMENTTYPE_FLOATINGWINDOW_NAME,
+ UIELEMENTTYPE_PROGRESSBAR_NAME
+};
+
+static const char RESOURCEURL_PREFIX[] = "private:resource/";
+static const sal_Int32 RESOURCEURL_PREFIX_SIZE = 17;
+static const char RESOURCEURL_CUSTOM_ELEMENT[] = "custom_";
+
+static sal_Int16 RetrieveTypeFromResourceURL( const rtl::OUString& aResourceURL )
+{
+
+ if (( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) &&
+ ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
+ {
+ rtl::OUString aTmpStr = aResourceURL.copy( RESOURCEURL_PREFIX_SIZE );
+ sal_Int32 nIndex = aTmpStr.indexOf( '/' );
+ if (( nIndex > 0 ) && ( aTmpStr.getLength() > nIndex ))
+ {
+ rtl::OUString aTypeStr( aTmpStr.copy( 0, nIndex ));
+ for ( int i = 0; i < UIElementType::COUNT; i++ )
+ {
+ if ( aTypeStr.equalsAscii( UIELEMENTTYPENAMES[i] ))
+ return sal_Int16( i );
+ }
+ }
+ }
+
+ return UIElementType::UNKNOWN;
+}
+
+static rtl::OUString RetrieveNameFromResourceURL( const rtl::OUString& aResourceURL )
+{
+ if (( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) &&
+ ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
+ {
+ sal_Int32 nIndex = aResourceURL.lastIndexOf( '/' );
+ if (( nIndex > 0 ) && (( nIndex+1 ) < aResourceURL.getLength()))
+ return aResourceURL.copy( nIndex+1 );
+ }
+
+ return rtl::OUString();
+}
+
+void UIConfigurationManagerImpl::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType )
+{
+ // preload list of element types on demand
+ impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType );
+ if ( m_bUseDefault )
+ impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
+
+ UIElementDataHashMap& rUserElements = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap;
+ UIElementDataHashMap::const_iterator pUserIter = rUserElements.begin();
+
+ rtl::OUString aCustomUrlPrefix( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_CUSTOM_ELEMENT ));
+ while ( pUserIter != rUserElements.end() )
+ {
+ sal_Int32 nIndex = pUserIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE );
+ if ( nIndex > RESOURCEURL_PREFIX_SIZE )
+ {
+ // Performance: Retrieve user interface name only for custom user interface elements.
+ // It's only used by them!
+ UIElementData* pDataSettings = impl_findUIElementData( pUserIter->second.aResourceURL, nElementType );
+ if ( pDataSettings && ( m_bUseDefault || !pDataSettings->bDefault ))
+ {
+ // Retrieve user interface name from XPropertySet interface
+ rtl::OUString aUIName;
+ Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ xPropSet->getPropertyValue( m_aPropUIName ) >>= aUIName;
+ }
+
+ UIElementInfo aInfo( pUserIter->second.aResourceURL, aUIName );
+ aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo ));
+ }
+ }
+ else
+ {
+ // The user interface name for standard user interface elements is stored in the WindowState.xcu file
+ UIElementInfo aInfo( pUserIter->second.aResourceURL, rtl::OUString() );
+ aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo ));
+ }
+ ++pUserIter;
+ }
+
+ if ( m_bUseDefault )
+ {
+ UIElementDataHashMap& rDefaultElements = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
+ UIElementDataHashMap::const_iterator pDefIter = rDefaultElements.begin();
+
+ while ( pDefIter != rDefaultElements.end() )
+ {
+ UIElementInfoHashMap::const_iterator pIterInfo = aUIElementInfoCollection.find( pDefIter->second.aResourceURL );
+ if ( pIterInfo == aUIElementInfoCollection.end() )
+ {
+ sal_Int32 nIndex = pDefIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE );
+ if ( nIndex > RESOURCEURL_PREFIX_SIZE )
+ {
+ // Performance: Retrieve user interface name only for custom user interface elements.
+ // It's only used by them!
+ UIElementData* pDataSettings = impl_findUIElementData( pDefIter->second.aResourceURL, nElementType );
+ if ( pDataSettings )
+ {
+ // Retrieve user interface name from XPropertySet interface
+ rtl::OUString aUIName;
+ Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ xPropSet->getPropertyValue( m_aPropUIName ) >>= aUIName;
+ }
+
+ UIElementInfo aInfo( pDefIter->second.aResourceURL, aUIName );
+ aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pDefIter->second.aResourceURL, aInfo ));
+ }
+ }
+ else
+ {
+ // The user interface name for standard user interface elements is stored in the WindowState.xcu file
+ UIElementInfo aInfo( pDefIter->second.aResourceURL, rtl::OUString() );
+ aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pDefIter->second.aResourceURL, aInfo ));
+ }
+ }
+
+ ++pDefIter;
+ } // while ( pDefIter != rDefaultElements.end() )
+ }
+}
+
+void UIConfigurationManagerImpl::impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType )
+{
+ UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType];
+
+ if ( !rElementTypeData.bLoaded )
+ {
+ Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
+ if ( xElementTypeStorage.is() )
+ {
+ rtl::OUStringBuffer aBuf( RESOURCEURL_PREFIX_SIZE );
+ aBuf.appendAscii( RESOURCEURL_PREFIX );
+ aBuf.appendAscii( UIELEMENTTYPENAMES[ nElementType ] );
+ aBuf.appendAscii( "/" );
+ rtl::OUString aResURLPrefix( aBuf.makeStringAndClear() );
+
+ UIElementDataHashMap& rHashMap = rElementTypeData.aElementsHashMap;
+ Reference< XNameAccess > xNameAccess( xElementTypeStorage, UNO_QUERY );
+ Sequence< rtl::OUString > aUIElementNames = xNameAccess->getElementNames();
+ for ( sal_Int32 n = 0; n < aUIElementNames.getLength(); n++ )
+ {
+ UIElementData aUIElementData;
+
+ // Resource name must be without ".xml"
+ sal_Int32 nIndex = aUIElementNames[n].lastIndexOf( '.' );
+ if (( nIndex > 0 ) && ( nIndex < aUIElementNames[n].getLength() ))
+ {
+ rtl::OUString aExtension( aUIElementNames[n].copy( nIndex+1 ));
+ rtl::OUString aUIElementName( aUIElementNames[n].copy( 0, nIndex ));
+
+ if (( aUIElementName.getLength() > 0 ) &&
+ ( aExtension.equalsIgnoreAsciiCaseAsciiL( "xml", 3 )))
+ {
+ aUIElementData.aResourceURL = aResURLPrefix + aUIElementName;
+ aUIElementData.aName = aUIElementNames[n];
+
+ if ( eLayer == LAYER_USERDEFINED )
+ {
+ aUIElementData.bModified = false;
+ aUIElementData.bDefault = false;
+ aUIElementData.bDefaultNode = false;
+ }
+
+ // Create boost::unordered_map entries for all user interface elements inside the storage. We don't load the
+ // settings to speed up the process.
+ rHashMap.insert( UIElementDataHashMap::value_type( aUIElementData.aResourceURL, aUIElementData ));
+ }
+ }
+ }
+ }
+ }
+
+ rElementTypeData.bLoaded = true;
+}
+
+void UIConfigurationManagerImpl::impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData )
+{
+ UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType];
+
+ Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
+ if ( xElementTypeStorage.is() && aUIElementData.aName.getLength() )
+ {
+ try
+ {
+ Reference< XStream > xStream = xElementTypeStorage->openStreamElement( aUIElementData.aName, ElementModes::READ );
+ Reference< XInputStream > xInputStream = xStream->getInputStream();
+
+ if ( xInputStream.is() )
+ {
+ switch ( nElementType )
+ {
+ case ::com::sun::star::ui::UIElementType::UNKNOWN:
+ break;
+
+ case ::com::sun::star::ui::UIElementType::MENUBAR:
+ {
+ try
+ {
+ MenuConfiguration aMenuCfg( m_xServiceManager );
+ Reference< XIndexAccess > xContainer( aMenuCfg.CreateMenuBarConfigurationFromXML( xInputStream ));
+ RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xContainer );
+ if ( pRootItemContainer )
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY );
+ else
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xContainer, sal_True ) ), UNO_QUERY );
+ return;
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ case ::com::sun::star::ui::UIElementType::POPUPMENU:
+ {
+ break;
+ }
+
+ case ::com::sun::star::ui::UIElementType::TOOLBAR:
+ {
+ try
+ {
+ Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
+ ToolBoxConfiguration::LoadToolBox( m_xServiceManager, xInputStream, xIndexContainer );
+ RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY );
+ return;
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+
+ break;
+ }
+
+ case ::com::sun::star::ui::UIElementType::STATUSBAR:
+ {
+ try
+ {
+ Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
+ StatusBarConfiguration::LoadStatusBar( m_xServiceManager, xInputStream, xIndexContainer );
+ RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY );
+ return;
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+
+ break;
+ }
+
+ case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW:
+ {
+ break;
+ }
+ }
+ }
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+ }
+
+ // At least we provide an empty settings container!
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer() ), UNO_QUERY );
+}
+
+UIConfigurationManagerImpl::UIElementData* UIConfigurationManagerImpl::impl_findUIElementData( const rtl::OUString& aResourceURL, sal_Int16 nElementType, bool bLoad )
+{
+ // preload list of element types on demand
+ impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType );
+ if ( m_bUseDefault )
+ impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
+
+ // first try to look into our user-defined vector/boost::unordered_map combination
+ UIElementDataHashMap& rUserHashMap = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rUserHashMap.find( aResourceURL );
+ if ( pIter != rUserHashMap.end() )
+ {
+ // Default data settings data must be retrieved from the default layer!
+ if ( !pIter->second.bDefault )
+ {
+ if ( !pIter->second.xSettings.is() && bLoad )
+ impl_requestUIElementData( nElementType, LAYER_USERDEFINED, pIter->second );
+ return &(pIter->second);
+ }
+ }
+
+ if ( m_bUseDefault )
+ {
+ // Not successfull, we have to look into our default vector/boost::unordered_map combination
+ UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
+ pIter = rDefaultHashMap.find( aResourceURL );
+ if ( pIter != rDefaultHashMap.end() )
+ {
+ if ( !pIter->second.xSettings.is() && bLoad )
+ impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
+ return &(pIter->second);
+ } // if ( pIter != rDefaultHashMap.end() )
+ }
+
+ // Nothing has been found!
+ return NULL;
+}
+
+void UIConfigurationManagerImpl::impl_storeElementTypeData( Reference< XStorage > xStorage, UIElementType& rElementType, bool bResetModifyState )
+{
+ UIElementDataHashMap& rHashMap = rElementType.aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rHashMap.begin();
+
+ while ( pIter != rHashMap.end() )
+ {
+ UIElementData& rElement = pIter->second;
+ if ( rElement.bModified )
+ {
+ if ( rElement.bDefault )
+ {
+ xStorage->removeElement( rElement.aName );
+ rElement.bModified = sal_False; // mark as not modified
+ }
+ else
+ {
+ Reference< XStream > xStream( xStorage->openStreamElement( rElement.aName, ElementModes::WRITE|ElementModes::TRUNCATE ), UNO_QUERY );
+ Reference< XOutputStream > xOutputStream( xStream->getOutputStream() );
+
+ if ( xOutputStream.is() )
+ {
+ switch( rElementType.nElementType )
+ {
+ case ::com::sun::star::ui::UIElementType::MENUBAR:
+ {
+ try
+ {
+ MenuConfiguration aMenuCfg( m_xServiceManager );
+ aMenuCfg.StoreMenuBarConfigurationToXML( rElement.xSettings, xOutputStream );
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ case ::com::sun::star::ui::UIElementType::TOOLBAR:
+ {
+ try
+ {
+ ToolBoxConfiguration::StoreToolBox( m_xServiceManager, xOutputStream, rElement.xSettings );
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ case ::com::sun::star::ui::UIElementType::STATUSBAR:
+ {
+ try
+ {
+ StatusBarConfiguration::StoreStatusBar( m_xServiceManager, xOutputStream, rElement.xSettings );
+ }
+ catch ( ::com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // mark as not modified if we store to our own storage
+ if ( bResetModifyState )
+ rElement.bModified = sal_False;
+ }
+ }
+
+ ++pIter;
+ }
+
+ // commit element type storage
+ Reference< XTransactedObject > xTransactedObject( xStorage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+
+ // mark UIElementType as not modified if we store to our own storage
+ if ( bResetModifyState )
+ rElementType.bModified = sal_False;
+}
+
+// This is only allowed to be called on the LAYER_USER_DEFINED!
+void UIConfigurationManagerImpl::impl_resetElementTypeData(
+ UIElementType& rUserElementType,
+ UIElementType& rDefaultElementType,
+ ConfigEventNotifyContainer& rRemoveNotifyContainer,
+ ConfigEventNotifyContainer& rReplaceNotifyContainer )
+{
+ UIElementDataHashMap& rHashMap = rUserElementType.aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rHashMap.begin();
+
+ Reference< XUIConfigurationManager > xThis( m_xOwner, UNO_QUERY );
+ Reference< XNameAccess > xDefaultNameAccess( rDefaultElementType.xStorage, UNO_QUERY );
+ sal_Int16 nType = rUserElementType.nElementType;
+
+ // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling
+ // our listeners!
+ while ( pIter != rHashMap.end() )
+ {
+ UIElementData& rElement = pIter->second;
+ if ( !rElement.bDefault )
+ {
+ if ( m_bUseDefault && xDefaultNameAccess->hasByName( rElement.aName ))
+ {
+ // Replace settings with data from default layer
+ Reference< XIndexAccess > xOldSettings( rElement.xSettings );
+ impl_requestUIElementData( nType, LAYER_DEFAULT, rElement );
+
+ ConfigurationEvent aReplaceEvent;
+ aReplaceEvent.ResourceURL = rElement.aResourceURL;
+ aReplaceEvent.Accessor <<= xThis;
+ aReplaceEvent.Source = m_xOwner;
+ aReplaceEvent.ReplacedElement <<= xOldSettings;
+ aReplaceEvent.Element <<= rElement.xSettings;
+
+ rReplaceNotifyContainer.push_back( aReplaceEvent );
+
+ // Mark element as default and not modified. That means "not active"
+ // in the user layer anymore.
+ rElement.bModified = false;
+ rElement.bDefault = true;
+ }
+ else
+ {
+ // Remove user-defined settings from user layer
+ ConfigurationEvent aEvent;
+ aEvent.ResourceURL = rElement.aResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = m_xOwner;
+ aEvent.Element <<= rElement.xSettings;
+
+ rRemoveNotifyContainer.push_back( aEvent );
+
+ // Mark element as default and not modified. That means "not active"
+ // in the user layer anymore.
+ rElement.bModified = false;
+ rElement.bDefault = true;
+ }
+ } // if ( !rElement.bDefault )
+ else
+ rElement.bModified = false;
+
+ ++pIter;
+ }
+
+ // Remove all settings from our user interface elements
+ rHashMap.clear();
+}
+
+void UIConfigurationManagerImpl::impl_reloadElementTypeData(
+ UIElementType& rUserElementType,
+ UIElementType& rDefaultElementType,
+ ConfigEventNotifyContainer& rRemoveNotifyContainer,
+ ConfigEventNotifyContainer& rReplaceNotifyContainer )
+{
+ UIElementDataHashMap& rHashMap = rUserElementType.aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rHashMap.begin();
+ Reference< XStorage > xUserStorage( rUserElementType.xStorage );
+ Reference< XStorage > xDefaultStorage( rDefaultElementType.xStorage );
+ Reference< XNameAccess > xUserNameAccess( rUserElementType.xStorage, UNO_QUERY );
+ Reference< XNameAccess > xDefaultNameAccess( rDefaultElementType.xStorage, UNO_QUERY );
+
+ Reference< XUIConfigurationManager > xThis( m_xOwner, UNO_QUERY );
+ sal_Int16 nType = rUserElementType.nElementType;
+
+ while ( pIter != rHashMap.end() )
+ {
+ UIElementData& rElement = pIter->second;
+ if ( rElement.bModified )
+ {
+ if ( xUserNameAccess->hasByName( rElement.aName ))
+ {
+ // Replace settings with data from user layer
+ Reference< XIndexAccess > xOldSettings( rElement.xSettings );
+
+ impl_requestUIElementData( nType, LAYER_USERDEFINED, rElement );
+
+ ConfigurationEvent aReplaceEvent;
+
+ aReplaceEvent.ResourceURL = rElement.aResourceURL;
+ aReplaceEvent.Accessor <<= xThis;
+ aReplaceEvent.Source = m_xOwner;
+ aReplaceEvent.ReplacedElement <<= xOldSettings;
+ aReplaceEvent.Element <<= rElement.xSettings;
+ rReplaceNotifyContainer.push_back( aReplaceEvent );
+
+ rElement.bModified = false;
+ }
+ else if ( m_bUseDefault && xDefaultNameAccess->hasByName( rElement.aName ))
+ {
+ // Replace settings with data from default layer
+ Reference< XIndexAccess > xOldSettings( rElement.xSettings );
+
+ impl_requestUIElementData( nType, LAYER_DEFAULT, rElement );
+
+ ConfigurationEvent aReplaceEvent;
+
+ aReplaceEvent.ResourceURL = rElement.aResourceURL;
+ aReplaceEvent.Accessor <<= xThis;
+ aReplaceEvent.Source = m_xOwner;
+ aReplaceEvent.ReplacedElement <<= xOldSettings;
+ aReplaceEvent.Element <<= rElement.xSettings;
+ rReplaceNotifyContainer.push_back( aReplaceEvent );
+
+ // Mark element as default and not modified. That means "not active"
+ // in the user layer anymore.
+ rElement.bModified = false;
+ rElement.bDefault = true;
+ }
+ else
+ {
+ // Element settings are not in any storage => remove
+ ConfigurationEvent aRemoveEvent;
+
+ aRemoveEvent.ResourceURL = rElement.aResourceURL;
+ aRemoveEvent.Accessor <<= xThis;
+ aRemoveEvent.Source = m_xOwner;
+ aRemoveEvent.Element <<= rElement.xSettings;
+
+ rRemoveNotifyContainer.push_back( aRemoveEvent );
+
+ // Mark element as default and not modified. That means "not active"
+ // in the user layer anymore.
+ rElement.bModified = false;
+ rElement.bDefault = true;
+ }
+ }
+ ++pIter;
+ }
+
+ rUserElementType.bModified = sal_False;
+}
+
+void UIConfigurationManagerImpl::impl_Initialize()
+{
+ // Initialize the top-level structures with the storage data
+ if ( m_xUserConfigStorage.is() )
+ {
+ // Try to access our module sub folder
+ for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT;
+ i++ )
+ {
+ Reference< XStorage > xElementTypeStorage;
+ try
+ {
+ if ( m_pStorageHandler[i] )
+ xElementTypeStorage = m_pStorageHandler[i]->getWorkingStorageUser();
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::io::IOException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+
+ m_aUIElements[LAYER_USERDEFINED][i].nElementType = i;
+ m_aUIElements[LAYER_USERDEFINED][i].bModified = false;
+ m_aUIElements[LAYER_USERDEFINED][i].xStorage = xElementTypeStorage;
+ m_aUIElements[LAYER_USERDEFINED][i].bDefaultLayer = false;
+ }
+ } // if ( m_xUserConfigStorage.is() )
+ else if ( !m_bUseDefault )
+ {
+ // We have no storage, just initialize ui element types with empty storage!
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ m_aUIElements[LAYER_USERDEFINED][i].xStorage.clear();
+ }
+
+ if ( m_bUseDefault && m_xUserConfigStorage.is() )
+ {
+ Reference< XNameAccess > xNameAccess( m_xDefaultConfigStorage, UNO_QUERY_THROW );
+
+ // Try to access our module sub folder
+ for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT;
+ i++ )
+ {
+ Reference< XStorage > xElementTypeStorage;
+ try
+ {
+ xNameAccess->getByName( rtl::OUString::createFromAscii( UIELEMENTTYPENAMES[i] )) >>= xElementTypeStorage;
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+
+ m_aUIElements[LAYER_DEFAULT][i].nElementType = i;
+ m_aUIElements[LAYER_DEFAULT][i].bModified = false;
+ m_aUIElements[LAYER_DEFAULT][i].xStorage = xElementTypeStorage;
+ m_aUIElements[LAYER_DEFAULT][i].bDefaultLayer = true;
+ }
+ }
+}
+
+UIConfigurationManagerImpl::UIConfigurationManagerImpl( const Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager
+ ,const Reference< XInterface >& _xOwner
+ , bool _bUseDefault) :
+ ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_xOwner( _xOwner )
+ , m_bUseDefault(_bUseDefault)
+ , m_bReadOnly( true )
+ , m_bInitialized( false )
+ , m_bModified( false )
+ , m_bConfigRead( false )
+ , m_bDisposed( false )
+ , m_aXMLPostfix( RTL_CONSTASCII_USTRINGPARAM( ".xml" ))
+ , m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))
+ , m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ))
+ , m_xServiceManager( xServiceManager )
+ , m_aListenerContainer( m_aLock.getShareableOslMutex() )
+{
+ for ( int i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ m_pStorageHandler[i] = 0;
+
+ // Make sure we have a default initialized entry for every layer and user interface element type!
+ // The following code depends on this!
+ m_aUIElements[LAYER_DEFAULT].resize( ::com::sun::star::ui::UIElementType::COUNT );
+ m_aUIElements[LAYER_USERDEFINED].resize( ::com::sun::star::ui::UIElementType::COUNT );
+}
+
+UIConfigurationManagerImpl::~UIConfigurationManagerImpl()
+{
+ for ( int i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ delete m_pStorageHandler[i];
+}
+
+// XComponent
+void UIConfigurationManagerImpl::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ css::lang::EventObject aEvent( m_xOwner );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ {
+ ResetableGuard aGuard( m_aLock );
+ try
+ {
+ if ( m_xModuleImageManager.is() )
+ m_xModuleImageManager->dispose();
+ }
+ catch ( Exception& )
+ {
+ }
+
+ m_xModuleImageManager.clear();
+ m_aUIElements[LAYER_USERDEFINED].clear();
+ m_aUIElements[LAYER_DEFAULT].clear();
+ m_xDefaultConfigStorage.clear();
+ m_xUserConfigStorage.clear();
+ m_xUserRootCommit.clear();
+ m_bConfigRead = false;
+ m_bModified = false;
+ m_bDisposed = true;
+ }
+}
+
+void UIConfigurationManagerImpl::addEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+void UIConfigurationManagerImpl::removeEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+// XInitialization
+void UIConfigurationManagerImpl::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bInitialized )
+ {
+ ::comphelper::SequenceAsHashMap lArgs(aArguments);
+ m_aModuleIdentifier = lArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleIdentifier")), ::rtl::OUString());
+ m_aModuleShortName = lArgs.getUnpackedValueOrDefault(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleShortName")), ::rtl::OUString());
+
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ rtl::OUString aResourceType;
+ if ( i == ::com::sun::star::ui::UIElementType::MENUBAR )
+ aResourceType = PresetHandler::RESOURCETYPE_MENUBAR();
+ else if ( i == ::com::sun::star::ui::UIElementType::TOOLBAR )
+ aResourceType = PresetHandler::RESOURCETYPE_TOOLBAR();
+ else if ( i == ::com::sun::star::ui::UIElementType::STATUSBAR )
+ aResourceType = PresetHandler::RESOURCETYPE_STATUSBAR();
+
+ if ( aResourceType.getLength() > 0 )
+ {
+ m_pStorageHandler[i] = new PresetHandler( m_xServiceManager );
+ m_pStorageHandler[i]->connectToResource( PresetHandler::E_MODULES,
+ aResourceType, // this path wont be used later ... seee next lines!
+ m_aModuleShortName,
+ css::uno::Reference< css::embed::XStorage >()); // no document root used here!
+ }
+ }
+
+ // initialize root storages for all resource types
+ m_xUserRootCommit = css::uno::Reference< css::embed::XTransactedObject >(
+ m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getOrCreateRootStorageUser(), css::uno::UNO_QUERY); // can be empty
+ m_xDefaultConfigStorage = m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getParentStorageShare(
+ m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getWorkingStorageShare());
+ m_xUserConfigStorage = m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getParentStorageUser(
+ m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getWorkingStorageUser());
+
+ if ( m_xUserConfigStorage.is() )
+ {
+ Reference< XPropertySet > xPropSet( m_xUserConfigStorage, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ long nOpenMode = 0;
+ if ( xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))) >>= nOpenMode )
+ m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
+ }
+ }
+
+ impl_Initialize();
+
+ m_bInitialized = true;
+ }
+}
+
+// XUIConfiguration
+void UIConfigurationManagerImpl::addConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+ }
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener );
+}
+
+void UIConfigurationManagerImpl::removeConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener );
+}
+
+
+// XUIConfigurationManager
+void UIConfigurationManagerImpl::reset() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( !isReadOnly() )
+ {
+ // Remove all elements from our user-defined storage!
+ try
+ {
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i];
+ Reference< XStorage > xSubStorage( rElementType.xStorage, UNO_QUERY );
+
+ if ( xSubStorage.is() )
+ {
+ bool bCommitSubStorage( false );
+ Reference< XNameAccess > xSubStorageNameAccess( xSubStorage, UNO_QUERY );
+ Sequence< rtl::OUString > aUIElementStreamNames = xSubStorageNameAccess->getElementNames();
+ for ( sal_Int32 j = 0; j < aUIElementStreamNames.getLength(); j++ )
+ {
+ xSubStorage->removeElement( aUIElementStreamNames[j] );
+ bCommitSubStorage = true;
+ }
+
+ if ( bCommitSubStorage )
+ {
+ Reference< XTransactedObject > xTransactedObject( xSubStorage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+ m_pStorageHandler[i]->commitUserChanges();
+ }
+ }
+ }
+
+ // remove settings from user defined layer and notify listener about removed settings data!
+ ConfigEventNotifyContainer aRemoveEventNotifyContainer;
+ ConfigEventNotifyContainer aReplaceEventNotifyContainer;
+ for ( sal_Int16 j = 1; j < ::com::sun::star::ui::UIElementType::COUNT; j++ )
+ {
+ try
+ {
+ UIElementType& rUserElementType = m_aUIElements[LAYER_USERDEFINED][j];
+ UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][j];
+
+ impl_resetElementTypeData( rUserElementType, rDefaultElementType, aRemoveEventNotifyContainer, aReplaceEventNotifyContainer );
+ rUserElementType.bModified = sal_False;
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ m_bModified = sal_False;
+
+ // Unlock mutex before notify our listeners
+ aGuard.unlock();
+
+ // Notify our listeners
+ ::std::for_each(aRemoveEventNotifyContainer.begin(),aRemoveEventNotifyContainer.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener,this,_1,NotifyOp_Remove));
+ ::std::for_each(aReplaceEventNotifyContainer.begin(),aReplaceEventNotifyContainer.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener,this,_1,NotifyOp_Replace));
+ }
+ catch ( ::com::sun::star::lang::IllegalArgumentException& )
+ {
+ }
+ catch ( ::com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::InvalidStorageException& )
+ {
+ }
+ catch ( ::com::sun::star::embed::StorageWrappedTargetException& )
+ {
+ }
+ }
+}
+
+Sequence< Sequence< PropertyValue > > UIConfigurationManagerImpl::getUIElementsInfo( sal_Int16 ElementType )
+throw ( IllegalArgumentException, RuntimeException )
+{
+ if (( ElementType < 0 ) || ( ElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+
+ ResetableGuard aGuard( m_aLock );
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ Sequence< Sequence< PropertyValue > > aElementInfoSeq;
+ UIElementInfoHashMap aUIElementInfoCollection;
+
+ if ( ElementType == ::com::sun::star::ui::UIElementType::UNKNOWN )
+ {
+ for ( sal_Int16 i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, sal_Int16( i ) );
+ }
+ else
+ impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType );
+
+ Sequence< PropertyValue > aUIElementInfo( 2 );
+ aUIElementInfo[0].Name = m_aPropResourceURL;
+ aUIElementInfo[1].Name = m_aPropUIName;
+
+ aElementInfoSeq.realloc( aUIElementInfoCollection.size() );
+ UIElementInfoHashMap::const_iterator pIter = aUIElementInfoCollection.begin();
+
+ sal_Int32 n = 0;
+ while ( pIter != aUIElementInfoCollection.end() )
+ {
+ aUIElementInfo[0].Value <<= pIter->second.aResourceURL;
+ aUIElementInfo[1].Value <<= pIter->second.aUIName;
+ aElementInfoSeq[n++] = aUIElementInfo;
+ ++pIter;
+ }
+
+ return aElementInfoSeq;
+}
+
+Reference< XIndexContainer > UIConfigurationManagerImpl::createSettings() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ // Creates an empty item container which can be filled from outside
+ return Reference< XIndexContainer >( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
+}
+
+sal_Bool UIConfigurationManagerImpl::hasSettings( const ::rtl::OUString& ResourceURL )
+throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
+ if ( pDataSettings && ( m_bUseDefault || !pDataSettings->bDefault) )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+Reference< XIndexAccess > UIConfigurationManagerImpl::getSettings( const ::rtl::OUString& ResourceURL, sal_Bool bWriteable )
+throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
+ if ( pDataSettings && ( m_bUseDefault || !pDataSettings->bDefault) )
+ {
+ // Create a copy of our data if someone wants to change the data.
+ if ( bWriteable )
+ return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( pDataSettings->xSettings ) ), UNO_QUERY );
+ else
+ return pDataSettings->xSettings;
+ }
+ }
+
+ throw NoSuchElementException();
+}
+
+void UIConfigurationManagerImpl::replaceSettings( const ::rtl::OUString& ResourceURL, const Reference< ::com::sun::star::container::XIndexAccess >& aNewData )
+throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else if ( m_bReadOnly )
+ throw IllegalAccessException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
+ if ( pDataSettings && ( m_bUseDefault || !pDataSettings->bDefault) )
+ {
+ if ( !m_bUseDefault || !pDataSettings->bDefaultNode )
+ {
+ // we have a settings entry in our user-defined layer - replace
+ Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings;
+
+ // Create a copy of the data if the container is not const
+ Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
+ if ( xReplace.is() )
+ pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
+ else
+ pDataSettings->xSettings = aNewData;
+ pDataSettings->bDefault = false;
+ pDataSettings->bModified = true;
+ m_bModified = true;
+
+ // Modify type container
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
+ rElementType.bModified = true;
+
+ Reference< XUIConfigurationManager > xThis( m_xOwner, UNO_QUERY );
+
+ // Create event to notify listener about replaced element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = ResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = m_xOwner;
+ aEvent.ReplacedElement <<= xOldSettings;
+ aEvent.Element <<= pDataSettings->xSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Replace );
+ }
+ else
+ {
+ // we have no settings in our user-defined layer - insert
+ UIElementData aUIElementData;
+
+ aUIElementData.bDefault = false;
+ aUIElementData.bDefaultNode = false;
+ aUIElementData.bModified = true;
+
+ // Create a copy of the data if the container is not const
+ Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
+ if ( xReplace.is() )
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
+ else
+ aUIElementData.xSettings = aNewData;
+ aUIElementData.aName = RetrieveNameFromResourceURL( ResourceURL ) + m_aXMLPostfix;
+ aUIElementData.aResourceURL = ResourceURL;
+ m_bModified = true;
+
+ // Modify type container
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
+ rElementType.bModified = true;
+
+ UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
+
+ // Check our user element settings hash map as it can already contain settings that have been set to default!
+ // If no node can be found, we have to insert it.
+ UIElementDataHashMap::iterator pIter = rElements.find( ResourceURL );
+ if ( pIter != rElements.end() )
+ pIter->second = aUIElementData;
+ else
+ rElements.insert( UIElementDataHashMap::value_type( ResourceURL, aUIElementData ));
+
+ Reference< XUIConfigurationManager > xThis( m_xOwner, UNO_QUERY );
+
+ // Create event to notify listener about replaced element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = ResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = m_xOwner;
+ aEvent.ReplacedElement <<= pDataSettings->xSettings;
+ aEvent.Element <<= aUIElementData.xSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Replace );
+ }
+ }
+ else
+ throw NoSuchElementException();
+ }
+}
+
+void UIConfigurationManagerImpl::removeSettings( const ::rtl::OUString& ResourceURL )
+throw ( NoSuchElementException, IllegalArgumentException, IllegalAccessException, RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else if ( m_bReadOnly )
+ throw IllegalAccessException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
+ if ( pDataSettings )
+ {
+ // If element settings are default, we don't need to change anything!
+ if ( pDataSettings->bDefault )
+ return;
+ else
+ {
+ Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings;
+ pDataSettings->bDefault = true;
+
+ // check if this is a default layer node
+ if ( !m_bUseDefault || !pDataSettings->bDefaultNode )
+ pDataSettings->bModified = true; // we have to remove this node from the user layer!
+ pDataSettings->xSettings.clear();
+ m_bModified = true; // user layer must be written
+
+ // Modify type container
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
+ rElementType.bModified = true;
+
+ Reference< XUIConfigurationManager > xThis( m_xOwner, UNO_QUERY );
+ // Check if we have settings in the default layer which replaces the user-defined one!
+ UIElementData* pDefaultDataSettings = m_bUseDefault ? impl_findUIElementData( ResourceURL, nElementType ) : NULL;
+ if ( pDefaultDataSettings )
+ {
+ // Create event to notify listener about replaced element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = ResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = m_xOwner;
+ aEvent.Element <<= xRemovedSettings;
+ aEvent.ReplacedElement <<= pDefaultDataSettings->xSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Replace );
+ }
+ else
+ {
+ // Create event to notify listener about removed element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = ResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = m_xOwner;
+ aEvent.Element <<= xRemovedSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Remove );
+ }
+ }
+ }
+ else
+ throw NoSuchElementException();
+ }
+}
+
+void UIConfigurationManagerImpl::insertSettings( const ::rtl::OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData )
+throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, RuntimeException )
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else if ( m_bReadOnly )
+ throw IllegalAccessException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ bool bInsertData( false );
+ UIElementData aUIElementData;
+ UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType );
+ if ( !m_bUseDefault )
+ {
+ if ( pDataSettings && !pDataSettings->bDefault )
+ throw ElementExistException();
+ if ( !pDataSettings )
+ {
+ pDataSettings = &aUIElementData;
+ bInsertData = true;
+ }
+ }
+ if ( !pDataSettings || !m_bUseDefault )
+ {
+ aUIElementData.bDefault = false;
+ if ( !m_bUseDefault )
+ aUIElementData.bDefaultNode = false;
+ aUIElementData.bModified = true;
+
+ // Create a copy of the data if the container is not const
+ Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
+ if ( xReplace.is() )
+ aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
+ else
+ aUIElementData.xSettings = aNewData;
+
+ m_bModified = true;
+
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
+ rElementType.bModified = true;
+
+ if ( bInsertData )
+ {
+ aUIElementData.aName = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix;
+ aUIElementData.aResourceURL = NewResourceURL;
+ UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
+ rElements.insert( UIElementDataHashMap::value_type( NewResourceURL, aUIElementData ));
+ }
+
+ Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings );
+ Reference< XUIConfigurationManager > xThis( m_xOwner, UNO_QUERY );
+
+ // Create event to notify listener about removed element settings
+ ConfigurationEvent aEvent;
+
+ aEvent.ResourceURL = NewResourceURL;
+ aEvent.Accessor <<= xThis;
+ aEvent.Source = m_xOwner;
+ aEvent.Element <<= xInsertSettings;
+
+ aGuard.unlock();
+
+ implts_notifyContainerListener( aEvent, NotifyOp_Insert );
+ }
+ else
+ throw ElementExistException();
+ }
+}
+
+Reference< XInterface > UIConfigurationManagerImpl::getImageManager() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( !m_xModuleImageManager.is() )
+ {
+ if ( m_bUseDefault )
+ m_xModuleImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ModuleImageManager( m_xServiceManager )),
+ UNO_QUERY );
+ else
+ m_xModuleImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ImageManager( m_xServiceManager )),
+ UNO_QUERY );
+ Reference< XInitialization > xInit( m_xModuleImageManager, UNO_QUERY );
+
+ Sequence< Any > aPropSeq( m_bUseDefault ? 3 : 2 );
+ PropertyValue aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" ));
+ aPropValue.Value <<= m_xUserConfigStorage;
+ aPropSeq[0] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
+ aPropValue.Value <<= m_aModuleIdentifier;
+ aPropSeq[1] <<= aPropValue;
+ if ( m_bUseDefault )
+ {
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserRootCommit" ));
+ aPropValue.Value <<= m_xUserRootCommit;
+ aPropSeq[2] <<= aPropValue;
+ }
+
+ xInit->initialize( aPropSeq );
+ }
+
+ return Reference< XInterface >( m_xModuleImageManager, UNO_QUERY );
+
+}
+
+Reference< XInterface > UIConfigurationManagerImpl::getShortCutManager() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+ if ( !m_bUseDefault && m_xAccConfig.is())
+ return m_xAccConfig;
+
+ Reference< XMultiServiceFactory > xSMGR = m_xServiceManager;
+ ::rtl::OUString aModule = m_aModuleIdentifier;
+ Reference< XStorage > xDocumentRoot = m_xUserConfigStorage;
+ aGuard.unlock();
+ Reference< XInterface > xManager = xSMGR->createInstance(m_bUseDefault ? SERVICENAME_MODULEACCELERATORCONFIGURATION : SERVICENAME_DOCUMENTACCELERATORCONFIGURATION );
+ Reference< XInitialization > xInit (xManager, UNO_QUERY_THROW);
+
+ PropertyValue aProp;
+ Sequence< Any > lArgs(1);
+ if ( m_bUseDefault )
+ {
+ aProp.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleIdentifier"));
+ aProp.Value <<= aModule;
+ } // if ( m_bUseDefault )
+ else
+ {
+ aProp.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentRoot"));
+ aProp.Value <<= xDocumentRoot;
+ }
+ lArgs[0] <<= aProp;
+ xInit->initialize(lArgs);
+
+ if ( !m_bUseDefault )
+ {
+ // SAFE ->
+ aGuard.lock();
+ m_xAccConfig = xManager;
+ aGuard.unlock();
+ // <- SAFE
+ }
+
+ return xManager;
+}
+
+Reference< XInterface > UIConfigurationManagerImpl::getEventsManager() throw (::com::sun::star::uno::RuntimeException)
+{
+ return Reference< XInterface >();
+}
+// XUIConfigurationStorage
+void UIConfigurationManagerImpl::setStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xUserConfigStorage.is() )
+ {
+ try
+ {
+ // Dispose old storage to be sure that it will be closed
+ Reference< XComponent > xComponent( m_xUserConfigStorage, UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ // We store the new storage. Be careful it could be an empty reference!
+ m_xUserConfigStorage = Storage;
+ m_bReadOnly = sal_True;
+
+ Reference< XUIConfigurationStorage > xAccUpdate(m_xAccConfig, UNO_QUERY);
+ if ( xAccUpdate.is() )
+ xAccUpdate->setStorage( m_xUserConfigStorage );
+
+ if ( m_xModuleImageManager.is() )
+ {
+ ImageManager* pImageManager = (ImageManager*)m_xModuleImageManager.get();
+ if ( pImageManager )
+ pImageManager->setStorage( m_xUserConfigStorage );
+ }
+
+ if ( m_xUserConfigStorage.is() )
+ {
+ ::rtl::OUString sEmpty;
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ rtl::OUString aResourceType;
+ if ( i == ::com::sun::star::ui::UIElementType::MENUBAR )
+ aResourceType = PresetHandler::RESOURCETYPE_MENUBAR();
+ else if ( i == ::com::sun::star::ui::UIElementType::TOOLBAR )
+ aResourceType = PresetHandler::RESOURCETYPE_TOOLBAR();
+ else if ( i == ::com::sun::star::ui::UIElementType::STATUSBAR )
+ aResourceType = PresetHandler::RESOURCETYPE_STATUSBAR();
+
+
+ m_pStorageHandler[i] = new PresetHandler( m_xServiceManager );
+ m_pStorageHandler[i]->connectToResource( PresetHandler::E_DOCUMENT,
+ rtl::OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), // this path wont be used later ... see next lines!
+ sEmpty,
+ m_xUserConfigStorage);
+ }
+ Reference< XPropertySet > xPropSet( m_xUserConfigStorage, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ long nOpenMode = 0;
+ if ( xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))) >>= nOpenMode )
+ m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
+ }
+ catch ( com::sun::star::beans::UnknownPropertyException& )
+ {
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+ }
+
+ impl_Initialize();
+}
+// -----------------------------------------------------------------------------
+sal_Bool UIConfigurationManagerImpl::hasStorage() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ return ( m_xUserConfigStorage.is() );
+}
+
+// XUIConfigurationManagerImpl
+sal_Bool UIConfigurationManagerImpl::isDefaultSettings( const ::rtl::OUString& ResourceURL )
+throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
+ if ( pDataSettings && pDataSettings->bDefaultNode )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+Reference< XIndexAccess > UIConfigurationManagerImpl::getDefaultSettings( const ::rtl::OUString& ResourceURL )
+throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
+
+ if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
+ ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
+ throw IllegalArgumentException();
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ // preload list of element types on demand
+ impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
+
+ // Look into our default vector/boost::unordered_map combination
+ UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
+ UIElementDataHashMap::iterator pIter = rDefaultHashMap.find( ResourceURL );
+ if ( pIter != rDefaultHashMap.end() )
+ {
+ if ( !pIter->second.xSettings.is() )
+ impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
+ return pIter->second.xSettings;
+ }
+ }
+
+ // Nothing has been found!
+ throw NoSuchElementException();
+}
+
+// XUIConfigurationPersistence
+void UIConfigurationManagerImpl::reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
+ {
+ // Try to access our module sub folder
+ ConfigEventNotifyContainer aRemoveNotifyContainer;
+ ConfigEventNotifyContainer aReplaceNotifyContainer;
+ for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ try
+ {
+ UIElementType& rUserElementType = m_aUIElements[LAYER_USERDEFINED][i];
+ UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][i];
+
+ if ( rUserElementType.bModified )
+ impl_reloadElementTypeData( rUserElementType, rDefaultElementType, aRemoveNotifyContainer, aReplaceNotifyContainer );
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ m_bModified = sal_False;
+
+ // Unlock mutex before notify our listeners
+ aGuard.unlock();
+
+ // Notify our listeners
+ ::std::for_each(aRemoveNotifyContainer.begin(),aRemoveNotifyContainer.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener,this,_1,NotifyOp_Remove));
+ ::std::for_each(aReplaceNotifyContainer.begin(),aReplaceNotifyContainer.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener,this,_1,NotifyOp_Replace));
+ }
+}
+
+void UIConfigurationManagerImpl::store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
+ {
+ // Try to access our module sub folder
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ try
+ {
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i];
+ Reference< XStorage > xStorage( rElementType.xStorage, UNO_QUERY );
+
+ if ( rElementType.bModified && xStorage.is() )
+ {
+ impl_storeElementTypeData( xStorage, rElementType );
+ m_pStorageHandler[i]->commitUserChanges();
+ }
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ m_bModified = false;
+ }
+}
+
+void UIConfigurationManagerImpl::storeToStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
+ {
+ // Try to access our module sub folder
+ for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
+ {
+ try
+ {
+ Reference< XStorage > xElementTypeStorage( Storage->openStorageElement(
+ rtl::OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), ElementModes::READWRITE ));
+ UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i];
+
+ if ( rElementType.bModified && xElementTypeStorage.is() )
+ impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag!
+ }
+ catch ( Exception& )
+ {
+ throw IOException();
+ }
+ }
+
+ Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY );
+ if ( xTransactedObject.is() )
+ xTransactedObject->commit();
+ }
+}
+
+sal_Bool UIConfigurationManagerImpl::isModified() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ return m_bModified;
+}
+
+sal_Bool UIConfigurationManagerImpl::isReadOnly() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aGuard( m_aLock );
+
+ return m_bReadOnly;
+}
+
+void UIConfigurationManagerImpl::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp )
+{
+ ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >*) NULL ) );
+ if ( pContainer != NULL )
+ {
+ ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
+ while ( pIterator.hasMoreElements() )
+ {
+ try
+ {
+ switch ( eOp )
+ {
+ case NotifyOp_Replace:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementReplaced( aEvent );
+ break;
+ case NotifyOp_Insert:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementInserted( aEvent );
+ break;
+ case NotifyOp_Remove:
+ ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementRemoved( aEvent );
+ break;
+ }
+ }
+ catch( css::uno::RuntimeException& )
+ {
+ pIterator.remove();
+ }
+ }
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/uiconfigurationmanagerimpl.hxx b/framework/source/uiconfiguration/uiconfigurationmanagerimpl.hxx
new file mode 100644
index 000000000000..a2be907122d0
--- /dev/null
+++ b/framework/source/uiconfiguration/uiconfigurationmanagerimpl.hxx
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_UICONFIGURATION_UICONFIGMANAGERIMPL_HXX_
+#define __FRAMEWORK_UICONFIGURATION_UICONFIGMANAGERIMPL_HXX_
+
+
+/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
+ with solaris headers ...
+*/
+#include <vector>
+#include <list>
+#include <boost/unordered_map.hpp>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <accelerators/presethandler.hxx>
+#include <threadhelp/threadhelpbase.hxx>
+#include <macros/generic.hxx>
+#include <macros/xinterface.hxx>
+#include <macros/xtypeprovider.hxx>
+#include <macros/xserviceinfo.hxx>
+#include <stdtypes.h>
+#include <uiconfiguration/moduleimagemanager.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+#include <com/sun/star/ui/XUIConfiguration.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/ConfigurationEvent.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <rtl/ustring.hxx>
+
+
+namespace framework
+{
+ class UIConfigurationManagerImpl : public ThreadHelpBase // Struct for right initalization of mutex member! Must be first of baseclasses.
+ {
+ public:
+ // XInterface, XTypeProvider, XServiceInfo
+ UIConfigurationManagerImpl( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager
+ , const com::sun::star::uno::Reference< com::sun::star::uno::XInterface >& _xOwner
+ , bool _bUseDefault);
+ ~UIConfigurationManagerImpl();
+
+ // XComponent
+ void dispose() throw (::com::sun::star::uno::RuntimeException);
+ void addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ void removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ void initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XUIConfiguration
+ void addConfigurationListener( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+ void removeConfigurationListener( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XUIConfigurationManager
+ void reset() throw (::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > > getUIElementsInfo( sal_Int16 ElementType ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > createSettings( ) throw (::com::sun::star::uno::RuntimeException);
+ sal_Bool hasSettings( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > getSettings( const ::rtl::OUString& ResourceURL, sal_Bool bWriteable ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ void replaceSettings( const ::rtl::OUString& ResourceURL, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& aNewData ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+ void removeSettings( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+ void insertSettings( const ::rtl::OUString& NewResourceURL, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& aNewData ) throw (::com::sun::star::container::ElementExistException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getImageManager() throw (::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getShortCutManager() throw (::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getEventsManager() throw (::com::sun::star::uno::RuntimeException);
+
+ // XUIConfigurationManagerImpl
+ sal_Bool isDefaultSettings( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > getDefaultSettings( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ // XUIConfigurationPersistence
+ void reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ void store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ void storeToStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ sal_Bool isModified() throw (::com::sun::star::uno::RuntimeException);
+ sal_Bool isReadOnly() throw (::com::sun::star::uno::RuntimeException);
+
+ // XUIConfigurationStorage
+ void setStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& Storage ) throw (::com::sun::star::uno::RuntimeException);
+ sal_Bool hasStorage() throw (::com::sun::star::uno::RuntimeException);
+
+ enum Layer
+ {
+ LAYER_DEFAULT,
+ LAYER_USERDEFINED,
+ LAYER_COUNT
+ };
+
+ enum NotifyOp
+ {
+ NotifyOp_Remove,
+ NotifyOp_Insert,
+ NotifyOp_Replace
+ };
+
+ struct UIElementInfo
+ {
+ UIElementInfo( const rtl::OUString& rResourceURL, const rtl::OUString& rUIName ) :
+ aResourceURL( rResourceURL), aUIName( rUIName ) {}
+ rtl::OUString aResourceURL;
+ rtl::OUString aUIName;
+ };
+
+ struct UIElementData
+ {
+ UIElementData() : bModified( false ), bDefault( true ), bDefaultNode( true ) {};
+
+ rtl::OUString aResourceURL;
+ rtl::OUString aName;
+ bool bModified; // has been changed since last storing
+ bool bDefault; // default settings
+ bool bDefaultNode; // this is a default layer element data
+ com::sun::star::uno::Reference< com::sun::star::container::XIndexAccess > xSettings;
+ };
+
+ struct UIElementType;
+ friend struct UIElementType;
+ typedef ::boost::unordered_map< rtl::OUString, UIElementData, OUStringHashCode, ::std::equal_to< rtl::OUString > > UIElementDataHashMap;
+
+ struct UIElementType
+ {
+ UIElementType() : bModified( false ),
+ bLoaded( false ),
+ bDefaultLayer( false ),
+ nElementType( ::com::sun::star::ui::UIElementType::UNKNOWN ) {}
+
+
+ bool bModified;
+ bool bLoaded;
+ bool bDefaultLayer;
+ sal_Int16 nElementType;
+ UIElementDataHashMap aElementsHashMap;
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage > xStorage;
+ };
+
+ typedef ::std::vector< UIElementType > UIElementTypesVector;
+ typedef ::std::vector< ::com::sun::star::ui::ConfigurationEvent > ConfigEventNotifyContainer;
+ typedef ::boost::unordered_map< rtl::OUString, UIElementInfo, OUStringHashCode, ::std::equal_to< rtl::OUString > > UIElementInfoHashMap;
+
+ // private methods
+ void impl_Initialize();
+ void implts_notifyContainerListener( const ::com::sun::star::ui::ConfigurationEvent& aEvent, NotifyOp eOp );
+ void impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType );
+ void impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType );
+ UIElementData* impl_findUIElementData( const rtl::OUString& aResourceURL, sal_Int16 nElementType, bool bLoad = true );
+ void impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData );
+ void impl_storeElementTypeData( com::sun::star::uno::Reference< com::sun::star::embed::XStorage > xStorage, UIElementType& rElementType, bool bResetModifyState = true );
+ void impl_resetElementTypeData( UIElementType& rUserElementType, UIElementType& rDefaultElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer );
+ void impl_reloadElementTypeData( UIElementType& rUserElementType, UIElementType& rDefaultElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer );
+
+ UIElementTypesVector m_aUIElements[LAYER_COUNT];
+ PresetHandler* m_pStorageHandler[::com::sun::star::ui::UIElementType::COUNT];
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage > m_xDefaultConfigStorage;
+ com::sun::star::uno::Reference< com::sun::star::embed::XStorage > m_xUserConfigStorage;
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > m_xOwner;
+ bool m_bUseDefault;
+ bool m_bReadOnly;
+ bool m_bInitialized;
+ bool m_bModified;
+ bool m_bConfigRead;
+ bool m_bDisposed;
+ rtl::OUString m_aXMLPostfix;
+ rtl::OUString m_aPropUIName;
+ rtl::OUString m_aPropResourceURL;
+ rtl::OUString m_aModuleIdentifier;
+ rtl::OUString m_aModuleShortName;
+ com::sun::star::uno::Reference< com::sun::star::embed::XTransactedObject > m_xUserRootCommit;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xServiceManager;
+ ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer; /// container for ALL Listener
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > m_xAccConfig;
+ com::sun::star::uno::Reference< com::sun::star::lang::XComponent > m_xModuleImageManager;
+ };
+}
+
+#endif // __FRAMEWORK_UICONFIGURATION_UICONFIGMANAGERIMPL_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/windowstateconfiguration.cxx b/framework/source/uiconfiguration/windowstateconfiguration.cxx
new file mode 100644
index 000000000000..4366700eb890
--- /dev/null
+++ b/framework/source/uiconfiguration/windowstateconfiguration.cxx
@@ -0,0 +1,1504 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "uiconfiguration/windowstateconfiguration.hxx"
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+#include "helper/mischelper.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/ui/DockingArea.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/weak.hxx>
+#include <tools/debug.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::ui;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+static const char CONFIGURATION_ROOT_ACCESS[] = "/org.openoffice.Office.UI.";
+static const char CONFIGURATION_WINDOWSTATE_ACCESS[] = "/UIElements/States";
+
+static const char CONFIGURATION_PROPERTY_LOCKED[] = WINDOWSTATE_PROPERTY_LOCKED;
+static const char CONFIGURATION_PROPERTY_DOCKED[] = WINDOWSTATE_PROPERTY_DOCKED;
+static const char CONFIGURATION_PROPERTY_VISIBLE[] = WINDOWSTATE_PROPERTY_VISIBLE;
+static const char CONFIGURATION_PROPERTY_DOCKINGAREA[] = WINDOWSTATE_PROPERTY_DOCKINGAREA;
+static const char CONFIGURATION_PROPERTY_DOCKPOS[] = WINDOWSTATE_PROPERTY_DOCKPOS;
+static const char CONFIGURATION_PROPERTY_DOCKSIZE[] = WINDOWSTATE_PROPERTY_DOCKSIZE;
+static const char CONFIGURATION_PROPERTY_POS[] = WINDOWSTATE_PROPERTY_POS;
+static const char CONFIGURATION_PROPERTY_SIZE[] = WINDOWSTATE_PROPERTY_SIZE;
+static const char CONFIGURATION_PROPERTY_UINAME[] = WINDOWSTATE_PROPERTY_UINAME;
+static const char CONFIGURATION_PROPERTY_INTERNALSTATE[] = WINDOWSTATE_PROPERTY_INTERNALSTATE;
+static const char CONFIGURATION_PROPERTY_STYLE[] = WINDOWSTATE_PROPERTY_STYLE;
+static const char CONFIGURATION_PROPERTY_CONTEXT[] = WINDOWSTATE_PROPERTY_CONTEXT;
+static const char CONFIGURATION_PROPERTY_HIDEFROMMENU[] = WINDOWSTATE_PROPERTY_HIDEFROMENU;
+static const char CONFIGURATION_PROPERTY_NOCLOSE[] = WINDOWSTATE_PROPERTY_NOCLOSE;
+static const char CONFIGURATION_PROPERTY_SOFTCLOSE[] = WINDOWSTATE_PROPERTY_SOFTCLOSE;
+static const char CONFIGURATION_PROPERTY_CONTEXTACTIVE[] = WINDOWSTATE_PROPERTY_CONTEXTACTIVE;
+
+// Zero based indexes, order must be the same as WindowStateMask && CONFIGURATION_PROPERTIES!
+static const sal_Int16 PROPERTY_LOCKED = 0;
+static const sal_Int16 PROPERTY_DOCKED = 1;
+static const sal_Int16 PROPERTY_VISIBLE = 2;
+static const sal_Int16 PROPERTY_CONTEXT = 3;
+static const sal_Int16 PROPERTY_HIDEFROMMENU = 4;
+static const sal_Int16 PROPERTY_NOCLOSE = 5;
+static const sal_Int16 PROPERTY_SOFTCLOSE = 6;
+static const sal_Int16 PROPERTY_CONTEXTACTIVE = 7;
+static const sal_Int16 PROPERTY_DOCKINGAREA = 8;
+static const sal_Int16 PROPERTY_POS = 9;
+static const sal_Int16 PROPERTY_SIZE = 10;
+static const sal_Int16 PROPERTY_UINAME = 11;
+static const sal_Int16 PROPERTY_INTERNALSTATE = 12;
+static const sal_Int16 PROPERTY_STYLE = 13;
+static const sal_Int16 PROPERTY_DOCKPOS = 14;
+static const sal_Int16 PROPERTY_DOCKSIZE = 15;
+
+// Order must be the same as WindowStateMask!!
+static const char* CONFIGURATION_PROPERTIES[] =
+{
+ CONFIGURATION_PROPERTY_LOCKED,
+ CONFIGURATION_PROPERTY_DOCKED,
+ CONFIGURATION_PROPERTY_VISIBLE,
+ CONFIGURATION_PROPERTY_CONTEXT,
+ CONFIGURATION_PROPERTY_HIDEFROMMENU,
+ CONFIGURATION_PROPERTY_NOCLOSE,
+ CONFIGURATION_PROPERTY_SOFTCLOSE,
+ CONFIGURATION_PROPERTY_CONTEXTACTIVE,
+ CONFIGURATION_PROPERTY_DOCKINGAREA,
+ CONFIGURATION_PROPERTY_POS,
+ CONFIGURATION_PROPERTY_SIZE,
+ CONFIGURATION_PROPERTY_UINAME,
+ CONFIGURATION_PROPERTY_INTERNALSTATE,
+ CONFIGURATION_PROPERTY_STYLE,
+ CONFIGURATION_PROPERTY_DOCKPOS,
+ CONFIGURATION_PROPERTY_DOCKSIZE,
+ 0
+};
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// Configuration access class for WindowState supplier implementation
+//*****************************************************************************************************************
+
+class ConfigurationAccess_WindowState : // interfaces
+ public XTypeProvider ,
+ public XNameContainer ,
+ public XContainerListener ,
+ // baseclasses
+ // Order is neccessary for right initialization!
+ private ThreadHelpBase ,
+ public ::cppu::OWeakObject
+{
+ public:
+ ConfigurationAccess_WindowState( const ::rtl::OUString& aWindowStateConfigFile, const Reference< XMultiServiceFactory >& rServiceManager );
+ virtual ~ConfigurationAccess_WindowState();
+
+ // XInterface, XTypeProvider
+ FWK_DECLARE_XINTERFACE
+ FWK_DECLARE_XTYPEPROVIDER
+
+ // XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XNameContainer
+ virtual void SAL_CALL removeByName( const ::rtl::OUString& sName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL insertByName( const ::rtl::OUString& sName, const css::uno::Any& aPropertySet )
+ throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, css::uno::RuntimeException );
+
+ // XNameReplace
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& sName, const css::uno::Any& aPropertySet )
+ throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException );
+
+ // XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasElements()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // container.XContainerListener
+ virtual void SAL_CALL elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException);
+ virtual void SAL_CALL elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException);
+ virtual void SAL_CALL elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException);
+
+ // lang.XEventListener
+ virtual void SAL_CALL disposing( const EventObject& aEvent ) throw(RuntimeException);
+
+ protected:
+ enum WindowStateMask
+ {
+ WINDOWSTATE_MASK_LOCKED = 1,
+ WINDOWSTATE_MASK_DOCKED = 2,
+ WINDOWSTATE_MASK_VISIBLE = 4,
+ WINDOWSTATE_MASK_CONTEXT = 8,
+ WINDOWSTATE_MASK_HIDEFROMMENU = 16,
+ WINDOWSTATE_MASK_NOCLOSE = 32,
+ WINDOWSTATE_MASK_SOFTCLOSE = 64,
+ WINDOWSTATE_MASK_CONTEXTACTIVE = 128,
+ WINDOWSTATE_MASK_DOCKINGAREA = 256,
+ WINDOWSTATE_MASK_POS = 512,
+ WINDOWSTATE_MASK_SIZE = 1024,
+ WINDOWSTATE_MASK_UINAME = 2048,
+ WINDOWSTATE_MASK_INTERNALSTATE = 4096,
+ WINDOWSTATE_MASK_STYLE = 8192,
+ WINDOWSTATE_MASK_DOCKPOS = 16384,
+ WINDOWSTATE_MASK_DOCKSIZE = 32768
+ };
+
+ // Cache structure. Valid values are described by tje eMask member. All other values should not be
+ // provided to outside code!
+ struct WindowStateInfo
+ {
+ WindowStateInfo() : aDockingArea( ::com::sun::star::ui::DockingArea_DOCKINGAREA_TOP ),
+ aDockPos( 0, 0 ),
+ aPos( 0, 0 ),
+ aSize( 0, 0 ),
+ nInternalState( 0 ),
+ nStyle( 0 ),
+ nMask( 0 ) {}
+
+ bool bLocked : 1,
+ bDocked : 1,
+ bVisible : 1,
+ bContext : 1,
+ bHideFromMenu : 1,
+ bNoClose : 1,
+ bSoftClose : 1,
+ bContextActive : 1;
+ ::com::sun::star::ui::DockingArea aDockingArea;
+ com::sun::star::awt::Point aDockPos;
+ com::sun::star::awt::Size aDockSize;
+ com::sun::star::awt::Point aPos;
+ com::sun::star::awt::Size aSize;
+ rtl::OUString aUIName;
+ sal_uInt32 nInternalState;
+ sal_uInt16 nStyle;
+ sal_uInt32 nMask; // see WindowStateMask
+ };
+
+ void impl_putPropertiesFromStruct( const WindowStateInfo& rWinStateInfo, Reference< XPropertySet >& xPropSet );
+ Any impl_insertCacheAndReturnSequence( const rtl::OUString& rResourceURL, Reference< XNameAccess >& rNameAccess );
+ WindowStateInfo& impl_insertCacheAndReturnWinState( const rtl::OUString& rResourceURL, Reference< XNameAccess >& rNameAccess );
+ Any impl_getSequenceFromStruct( const WindowStateInfo& rWinStateInfo );
+ void impl_fillStructFromSequence( WindowStateInfo& rWinStateInfo, const Sequence< PropertyValue >& rSeq );
+ Any impl_getWindowStateFromResourceURL( const rtl::OUString& rResourceURL );
+ sal_Bool impl_initializeConfigAccess();
+
+ private:
+ typedef ::boost::unordered_map< ::rtl::OUString,
+ WindowStateInfo,
+ OUStringHashCode,
+ ::std::equal_to< ::rtl::OUString > > ResourceURLToInfoCache;
+
+ rtl::OUString m_aConfigWindowAccess;
+ Reference< XMultiServiceFactory > m_xServiceManager;
+ Reference< XMultiServiceFactory > m_xConfigProvider;
+ Reference< XNameAccess > m_xConfigAccess;
+ Reference< XContainerListener > m_xConfigListener;
+ ResourceURLToInfoCache m_aResourceURLToInfoCache;
+ sal_Bool m_bConfigAccessInitialized : 1,
+ m_bModified : 1;
+ std::vector< ::rtl::OUString > m_aPropArray;
+};
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_7 ( ConfigurationAccess_WindowState ,
+ OWeakObject ,
+ DIRECT_INTERFACE ( css::container::XNameContainer ),
+ DIRECT_INTERFACE ( css::container::XContainerListener ),
+ DIRECT_INTERFACE ( css::lang::XTypeProvider ),
+ DERIVED_INTERFACE( css::container::XElementAccess, css::container::XNameAccess ),
+ DERIVED_INTERFACE( css::container::XNameAccess, css::container::XNameReplace ),
+ DERIVED_INTERFACE( css::container::XNameReplace, css::container::XNameContainer ),
+ DERIVED_INTERFACE( css::lang::XEventListener, XContainerListener )
+ )
+
+DEFINE_XTYPEPROVIDER_7 ( ConfigurationAccess_WindowState ,
+ css::container::XNameContainer ,
+ css::container::XNameReplace ,
+ css::container::XNameAccess ,
+ css::container::XElementAccess ,
+ css::container::XContainerListener ,
+ css::lang::XEventListener ,
+ css::lang::XTypeProvider
+ )
+
+ConfigurationAccess_WindowState::ConfigurationAccess_WindowState( const rtl::OUString& aModuleName, const Reference< XMultiServiceFactory >& rServiceManager ) :
+ ThreadHelpBase(),
+ m_aConfigWindowAccess( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_ROOT_ACCESS )),
+ m_xServiceManager( rServiceManager ),
+ m_bConfigAccessInitialized( sal_False ),
+ m_bModified( sal_False )
+{
+ // Create configuration hierachical access name
+ m_aConfigWindowAccess += aModuleName;
+ m_aConfigWindowAccess += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_WINDOWSTATE_ACCESS ));
+ m_xConfigProvider = Reference< XMultiServiceFactory >( rServiceManager->createInstance( SERVICENAME_CFGPROVIDER ), UNO_QUERY );
+
+ // Initialize access array with property names.
+ sal_Int32 n = 0;
+ while ( CONFIGURATION_PROPERTIES[n] )
+ {
+ m_aPropArray.push_back( ::rtl::OUString::createFromAscii( CONFIGURATION_PROPERTIES[n] ));
+ ++n;
+ }
+}
+
+ConfigurationAccess_WindowState::~ConfigurationAccess_WindowState()
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ xContainer->removeContainerListener(m_xConfigListener);
+}
+
+// XNameAccess
+Any SAL_CALL ConfigurationAccess_WindowState::getByName( const ::rtl::OUString& rResourceURL )
+throw ( NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ ResourceURLToInfoCache::const_iterator pIter = m_aResourceURLToInfoCache.find( rResourceURL );
+ if ( pIter != m_aResourceURLToInfoCache.end() )
+ return impl_getSequenceFromStruct( pIter->second );
+ else
+ {
+ Any a( impl_getWindowStateFromResourceURL( rResourceURL ) );
+ if ( a == Any() )
+ throw NoSuchElementException();
+ else
+ return a;
+ }
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ConfigurationAccess_WindowState::getElementNames()
+throw ( RuntimeException )
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigAccessInitialized )
+ {
+ impl_initializeConfigAccess();
+ m_bConfigAccessInitialized = sal_True;
+ }
+
+ if ( m_xConfigAccess.is() )
+ return m_xConfigAccess->getElementNames();
+ else
+ return Sequence< ::rtl::OUString > ();
+}
+
+sal_Bool SAL_CALL ConfigurationAccess_WindowState::hasByName( const ::rtl::OUString& rResourceURL )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ ResourceURLToInfoCache::const_iterator pIter = m_aResourceURLToInfoCache.find( rResourceURL );
+ if ( pIter != m_aResourceURLToInfoCache.end() )
+ return sal_True;
+ else
+ {
+ Any a( impl_getWindowStateFromResourceURL( rResourceURL ) );
+ if ( a == Any() )
+ return sal_False;
+ else
+ return sal_True;
+ }
+}
+
+// XElementAccess
+Type SAL_CALL ConfigurationAccess_WindowState::getElementType()
+throw ( RuntimeException )
+{
+ return( ::getCppuType( (const Sequence< PropertyValue >*)NULL ) );
+}
+
+sal_Bool SAL_CALL ConfigurationAccess_WindowState::hasElements()
+throw ( RuntimeException )
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigAccessInitialized )
+ {
+ impl_initializeConfigAccess();
+ m_bConfigAccessInitialized = sal_True;
+ }
+
+ if ( m_xConfigAccess.is() )
+ return m_xConfigAccess->hasElements();
+ else
+ return sal_False;
+}
+
+// XNameContainer
+void SAL_CALL ConfigurationAccess_WindowState::removeByName( const ::rtl::OUString& rResourceURL )
+throw( NoSuchElementException, WrappedTargetException, RuntimeException )
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ ResourceURLToInfoCache::iterator pIter = m_aResourceURLToInfoCache.find( rResourceURL );
+ if ( pIter != m_aResourceURLToInfoCache.end() )
+ m_aResourceURLToInfoCache.erase( pIter );
+
+ if ( !m_bConfigAccessInitialized )
+ {
+ impl_initializeConfigAccess();
+ m_bConfigAccessInitialized = sal_True;
+ }
+
+ try
+ {
+ // Remove must be write-through => remove element from configuration
+ Reference< XNameContainer > xNameContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xNameContainer.is() )
+ {
+ aLock.unlock();
+
+ xNameContainer->removeByName( rResourceURL );
+ Reference< XChangesBatch > xFlush( m_xConfigAccess, UNO_QUERY );
+ if ( xFlush.is() )
+ xFlush->commitChanges();
+ }
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+}
+
+void SAL_CALL ConfigurationAccess_WindowState::insertByName( const ::rtl::OUString& rResourceURL, const css::uno::Any& aPropertySet )
+throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ Sequence< PropertyValue > aPropSet;
+ if ( aPropertySet >>= aPropSet )
+ {
+ ResourceURLToInfoCache::const_iterator pIter = m_aResourceURLToInfoCache.find( rResourceURL );
+ if ( pIter != m_aResourceURLToInfoCache.end() )
+ throw ElementExistException();
+ else
+ {
+ if ( !m_bConfigAccessInitialized )
+ {
+ impl_initializeConfigAccess();
+ m_bConfigAccessInitialized = sal_True;
+ }
+
+ // Try to ask our configuration access
+ if ( m_xConfigAccess.is() )
+ {
+ if ( m_xConfigAccess->hasByName( rResourceURL ) )
+ throw ElementExistException();
+ else
+ {
+ WindowStateInfo aWinStateInfo;
+ impl_fillStructFromSequence( aWinStateInfo, aPropSet );
+ m_aResourceURLToInfoCache.insert( ResourceURLToInfoCache::value_type( rResourceURL, aWinStateInfo ));
+
+ // insert must be write-through => insert element into configuration
+ Reference< XNameContainer > xNameContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xNameContainer.is() )
+ {
+ Reference< XSingleServiceFactory > xFactory( m_xConfigAccess, UNO_QUERY );
+ aLock.unlock();
+
+ try
+ {
+ Reference< XPropertySet > xPropSet( xFactory->createInstance(), UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ Any a;
+ impl_putPropertiesFromStruct( aWinStateInfo, xPropSet );
+ a <<= xPropSet;
+ xNameContainer->insertByName( rResourceURL, a );
+ Reference< XChangesBatch > xFlush( xFactory, UNO_QUERY );
+ if ( xFlush.is() )
+ xFlush->commitChanges();
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ throw IllegalArgumentException();
+}
+
+// XNameReplace
+void SAL_CALL ConfigurationAccess_WindowState::replaceByName( const ::rtl::OUString& rResourceURL, const css::uno::Any& aPropertySet )
+throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ Sequence< PropertyValue > aPropSet;
+ if ( aPropertySet >>= aPropSet )
+ {
+ ResourceURLToInfoCache::iterator pIter = m_aResourceURLToInfoCache.find( rResourceURL );
+ if ( pIter != m_aResourceURLToInfoCache.end() )
+ {
+ WindowStateInfo& rWinStateInfo = pIter->second;
+ impl_fillStructFromSequence( rWinStateInfo, aPropSet );
+ m_bModified = sal_True;
+ }
+ else
+ {
+ if ( !m_bConfigAccessInitialized )
+ {
+ impl_initializeConfigAccess();
+ m_bConfigAccessInitialized = sal_True;
+ }
+
+ // Try to ask our configuration access
+ Reference< XNameAccess > xNameAccess;
+ Any a( m_xConfigAccess->getByName( rResourceURL ));
+
+ if ( a >>= xNameAccess )
+ {
+ WindowStateInfo& rWinStateInfo( impl_insertCacheAndReturnWinState( rResourceURL, xNameAccess ));
+ impl_fillStructFromSequence( rWinStateInfo, aPropSet );
+ m_bModified = sal_True;
+ pIter = m_aResourceURLToInfoCache.find( rResourceURL );
+ }
+ else
+ throw NoSuchElementException();
+ }
+
+ if ( m_bModified && pIter != m_aResourceURLToInfoCache.end() )
+ {
+ Reference< XNameContainer > xNameContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xNameContainer.is() )
+ {
+ WindowStateInfo aWinStateInfo( pIter->second );
+ ::rtl::OUString aResourceURL( pIter->first );
+ m_bModified = sal_False;
+ aLock.unlock();
+
+ try
+ {
+ Reference< XPropertySet > xPropSet;
+ if ( xNameContainer->getByName( aResourceURL ) >>= xPropSet )
+ {
+ impl_putPropertiesFromStruct( aWinStateInfo, xPropSet );
+
+ Reference< XChangesBatch > xFlush( m_xConfigAccess, UNO_QUERY );
+ if ( xFlush.is() )
+ xFlush->commitChanges();
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+ }
+ else
+ throw IllegalArgumentException();
+}
+
+// container.XContainerListener
+void SAL_CALL ConfigurationAccess_WindowState::elementInserted( const ContainerEvent& ) throw(RuntimeException)
+{
+ // do nothing - next time someone wants to retrieve this node we will find it in the configuration
+}
+
+void SAL_CALL ConfigurationAccess_WindowState::elementRemoved ( const ContainerEvent& ) throw(RuntimeException)
+{
+}
+
+void SAL_CALL ConfigurationAccess_WindowState::elementReplaced( const ContainerEvent& ) throw(RuntimeException)
+{
+}
+
+// lang.XEventListener
+void SAL_CALL ConfigurationAccess_WindowState::disposing( const EventObject& aEvent ) throw(RuntimeException)
+{
+ // SAFE
+ // remove our reference to the config access
+ ResetableGuard aLock( m_aLock );
+
+ Reference< XInterface > xIfac1( aEvent.Source, UNO_QUERY );
+ Reference< XInterface > xIfac2( m_xConfigAccess, UNO_QUERY );
+ if ( xIfac1 == xIfac2 )
+ m_xConfigAccess.clear();
+}
+
+// private helper methods
+Any ConfigurationAccess_WindowState::impl_getSequenceFromStruct( const WindowStateInfo& rWinStateInfo )
+{
+ sal_Int32 i( 0 );
+ sal_Int32 nCount( m_aPropArray.size() );
+ Sequence< PropertyValue > aPropSeq;
+
+ for ( i = 0; i < nCount; i++ )
+ {
+ if ( rWinStateInfo.nMask & ( 1 << i ))
+ {
+ // put value into the return sequence
+ sal_Int32 nIndex( aPropSeq.getLength());
+ aPropSeq.realloc( nIndex+1 );
+ aPropSeq[nIndex].Name = m_aPropArray[i];
+
+ switch ( i )
+ {
+ case PROPERTY_LOCKED:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bLocked ); break;
+ case PROPERTY_DOCKED:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bDocked ); break;
+ case PROPERTY_VISIBLE:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bVisible ); break;
+ case PROPERTY_CONTEXT:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bContext ); break;
+ case PROPERTY_HIDEFROMMENU:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bHideFromMenu ); break;
+ case PROPERTY_NOCLOSE:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bNoClose ); break;
+ case PROPERTY_SOFTCLOSE:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bSoftClose ); break;
+ case PROPERTY_CONTEXTACTIVE:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.bContextActive ); break;
+ case PROPERTY_DOCKINGAREA:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aDockingArea ); break;
+ case PROPERTY_POS:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aPos ); break;
+ case PROPERTY_SIZE:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aSize ); break;
+ case PROPERTY_UINAME:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aUIName ); break;
+ case PROPERTY_INTERNALSTATE:
+ aPropSeq[nIndex].Value = makeAny( sal_Int32( rWinStateInfo.nInternalState )); break;
+ case PROPERTY_STYLE:
+ aPropSeq[nIndex].Value = makeAny( sal_Int16( rWinStateInfo.nStyle )); break;
+ case PROPERTY_DOCKPOS:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aDockPos ); break;
+ case PROPERTY_DOCKSIZE:
+ aPropSeq[nIndex].Value = makeAny( rWinStateInfo.aDockSize ); break;
+ default:
+ DBG_ASSERT( sal_False, "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
+ }
+ }
+ }
+
+ return makeAny( aPropSeq );
+}
+
+Any ConfigurationAccess_WindowState::impl_insertCacheAndReturnSequence( const rtl::OUString& rResourceURL, Reference< XNameAccess >& xNameAccess )
+{
+ sal_Int32 nMask( 0 );
+ sal_Int32 nCount( m_aPropArray.size() );
+ sal_Int32 i( 0 );
+ sal_Int32 nIndex( 0 );
+ Sequence< PropertyValue > aPropSeq;
+ WindowStateInfo aWindowStateInfo;
+
+ for ( i = 0; i < nCount; i++ )
+ {
+ try
+ {
+ bool bAddToSeq( false );
+ Any a( xNameAccess->getByName( m_aPropArray[i] ) );
+ switch ( i )
+ {
+ case PROPERTY_LOCKED:
+ case PROPERTY_DOCKED:
+ case PROPERTY_VISIBLE:
+ case PROPERTY_CONTEXT:
+ case PROPERTY_HIDEFROMMENU:
+ case PROPERTY_NOCLOSE:
+ case PROPERTY_SOFTCLOSE:
+ case PROPERTY_CONTEXTACTIVE:
+ {
+ sal_Bool bValue = sal_Bool();
+ if ( a >>= bValue )
+ {
+ sal_Int32 nValue( 1 << i );
+ nMask |= nValue;
+ bAddToSeq = true;
+ switch ( i )
+ {
+ case PROPERTY_LOCKED:
+ aWindowStateInfo.bLocked = bValue; break;
+ case PROPERTY_DOCKED:
+ aWindowStateInfo.bDocked = bValue; break;
+ case PROPERTY_VISIBLE:
+ aWindowStateInfo.bVisible = bValue; break;
+ case PROPERTY_CONTEXT:
+ aWindowStateInfo.bContext = bValue; break;
+ case PROPERTY_HIDEFROMMENU:
+ aWindowStateInfo.bHideFromMenu = bValue; break;
+ case PROPERTY_NOCLOSE:
+ aWindowStateInfo.bNoClose = bValue; break;
+ case PROPERTY_SOFTCLOSE:
+ aWindowStateInfo.bSoftClose = bValue; break;
+ case PROPERTY_CONTEXTACTIVE:
+ aWindowStateInfo.bContextActive = bValue; break;
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_DOCKINGAREA:
+ {
+ sal_Int32 nDockingArea = 0;
+ if ( a >>= nDockingArea )
+ {
+ if (( nDockingArea >= 0 ) &&
+ ( nDockingArea <= sal_Int32( DockingArea_DOCKINGAREA_RIGHT )))
+ {
+ aWindowStateInfo.aDockingArea = (DockingArea)nDockingArea;
+ nMask |= WINDOWSTATE_MASK_DOCKINGAREA;
+ a = makeAny( aWindowStateInfo.aDockingArea );
+ bAddToSeq = true;
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_POS:
+ case PROPERTY_DOCKPOS:
+ {
+ ::rtl::OUString aString;
+ if ( a >>= aString )
+ {
+ sal_Int32 nToken( 0 );
+ ::rtl::OUString aXStr = aString.getToken( 0, ',', nToken );
+ if ( nToken > 0 )
+ {
+ com::sun::star::awt::Point aPos;
+ aPos.X = aXStr.toInt32();
+ aPos.Y = aString.getToken( 0, ',', nToken ).toInt32();
+
+ if ( i == PROPERTY_POS )
+ {
+ aWindowStateInfo.aPos = aPos;
+ nMask |= WINDOWSTATE_MASK_POS;
+ }
+ else
+ {
+ aWindowStateInfo.aDockPos = aPos;
+ nMask |= WINDOWSTATE_MASK_DOCKPOS;
+ }
+
+ a <<= aPos;
+ bAddToSeq = true;
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_SIZE:
+ case PROPERTY_DOCKSIZE:
+ {
+ ::rtl::OUString aString;
+ if ( a >>= aString )
+ {
+ sal_Int32 nToken( 0 );
+ ::rtl::OUString aStr = aString.getToken( 0, ',', nToken );
+ if ( nToken > 0 )
+ {
+ com::sun::star::awt::Size aSize;
+ aSize.Width = aStr.toInt32();
+ aSize.Height = aString.getToken( 0, ',', nToken ).toInt32();
+ if ( i == PROPERTY_SIZE )
+ {
+ aWindowStateInfo.aSize = aSize;
+ nMask |= WINDOWSTATE_MASK_SIZE;
+ }
+ else
+ {
+ aWindowStateInfo.aDockSize = aSize;
+ nMask |= WINDOWSTATE_MASK_DOCKSIZE;
+ }
+
+ a <<= aSize;
+ bAddToSeq = true;
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_UINAME:
+ {
+ ::rtl::OUString aValue;
+ if ( a >>= aValue )
+ {
+ nMask |= WINDOWSTATE_MASK_UINAME;
+ aWindowStateInfo.aUIName = aValue;
+ bAddToSeq = true;
+ }
+ }
+ break;
+
+ case PROPERTY_INTERNALSTATE:
+ {
+ sal_uInt32 nValue = 0;
+ if ( a >>= nValue )
+ {
+ nMask |= WINDOWSTATE_MASK_INTERNALSTATE;
+ aWindowStateInfo.nInternalState = nValue;
+ bAddToSeq = true;
+ }
+ }
+ break;
+
+ case PROPERTY_STYLE:
+ {
+ sal_Int32 nValue = 0;
+ if ( a >>= nValue )
+ {
+ nMask |= WINDOWSTATE_MASK_STYLE;
+ aWindowStateInfo.nStyle = sal_uInt16( nValue );
+ bAddToSeq = true;
+ }
+ }
+ break;
+
+ default:
+ DBG_ASSERT( sal_False, "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
+ }
+
+ if ( bAddToSeq )
+ {
+ // put value into the return sequence
+ nIndex = aPropSeq.getLength();
+ aPropSeq.realloc( nIndex+1 );
+ aPropSeq[nIndex].Name = m_aPropArray[i];
+ aPropSeq[nIndex].Value = a;
+ }
+ }
+ catch( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+
+ aWindowStateInfo.nMask = nMask;
+ m_aResourceURLToInfoCache.insert( ResourceURLToInfoCache::value_type( rResourceURL, aWindowStateInfo ));
+ return makeAny( aPropSeq );
+}
+
+ConfigurationAccess_WindowState::WindowStateInfo& ConfigurationAccess_WindowState::impl_insertCacheAndReturnWinState( const rtl::OUString& rResourceURL, Reference< XNameAccess >& rNameAccess )
+{
+ sal_Int32 nMask( 0 );
+ sal_Int32 nCount( m_aPropArray.size() );
+ sal_Int32 i( 0 );
+ Sequence< PropertyValue > aPropSeq;
+ WindowStateInfo aWindowStateInfo;
+
+ for ( i = 0; i < nCount; i++ )
+ {
+ try
+ {
+ Any a( rNameAccess->getByName( m_aPropArray[i] ) );
+ switch ( i )
+ {
+ case PROPERTY_LOCKED:
+ case PROPERTY_DOCKED:
+ case PROPERTY_VISIBLE:
+ case PROPERTY_CONTEXT:
+ case PROPERTY_HIDEFROMMENU:
+ case PROPERTY_NOCLOSE:
+ case PROPERTY_SOFTCLOSE:
+ case PROPERTY_CONTEXTACTIVE:
+ {
+ sal_Bool bValue = sal_Bool();
+ if ( a >>= bValue )
+ {
+ sal_Int32 nValue( 1 << i );
+ nMask |= nValue;
+ switch ( i )
+ {
+ case PROPERTY_LOCKED:
+ aWindowStateInfo.bLocked = bValue; break;
+ case PROPERTY_DOCKED:
+ aWindowStateInfo.bDocked = bValue; break;
+ case PROPERTY_VISIBLE:
+ aWindowStateInfo.bVisible = bValue; break;
+ case PROPERTY_CONTEXT:
+ aWindowStateInfo.bContext = bValue; break;
+ case PROPERTY_HIDEFROMMENU:
+ aWindowStateInfo.bHideFromMenu = bValue; break;
+ case PROPERTY_NOCLOSE:
+ aWindowStateInfo.bNoClose = bValue; break;
+ case PROPERTY_SOFTCLOSE:
+ aWindowStateInfo.bNoClose = bValue; break;
+ case PROPERTY_CONTEXTACTIVE:
+ aWindowStateInfo.bContextActive = bValue; break;
+ default:
+ DBG_ASSERT( sal_False, "Unknown boolean property in WindowState found!" );
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_DOCKINGAREA:
+ {
+ sal_Int32 nDockingArea = 0;
+ if ( a >>= nDockingArea )
+ {
+ if (( nDockingArea >= 0 ) &&
+ ( nDockingArea <= sal_Int32( DockingArea_DOCKINGAREA_RIGHT )))
+ {
+ aWindowStateInfo.aDockingArea = (DockingArea)nDockingArea;
+ nMask |= WINDOWSTATE_MASK_DOCKINGAREA;
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_POS:
+ case PROPERTY_DOCKPOS:
+ {
+ ::rtl::OUString aString;
+ if ( a >>= aString )
+ {
+ sal_Int32 nToken( 0 );
+ ::rtl::OUString aXStr = aString.getToken( 0, ',', nToken );
+ if ( nToken > 0 )
+ {
+ com::sun::star::awt::Point aPos;
+ aPos.X = aXStr.toInt32();
+ aPos.Y = aString.getToken( 0, ',', nToken ).toInt32();
+
+ if ( i == PROPERTY_POS )
+ {
+ aWindowStateInfo.aPos = aPos;
+ nMask |= WINDOWSTATE_MASK_POS;
+ }
+ else
+ {
+ aWindowStateInfo.aDockPos = aPos;
+ nMask |= WINDOWSTATE_MASK_DOCKPOS;
+ }
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_SIZE:
+ case PROPERTY_DOCKSIZE:
+ {
+ ::rtl::OUString aString;
+ if ( a >>= aString )
+ {
+ sal_Int32 nToken( 0 );
+ ::rtl::OUString aStr = aString.getToken( 0, ',', nToken );
+ if ( nToken > 0 )
+ {
+ com::sun::star::awt::Size aSize;
+ aSize.Width = aStr.toInt32();
+ aSize.Height = aString.getToken( 0, ',', nToken ).toInt32();
+ if ( i == PROPERTY_SIZE )
+ {
+ aWindowStateInfo.aSize = aSize;
+ nMask |= WINDOWSTATE_MASK_SIZE;
+ }
+ else
+ {
+ aWindowStateInfo.aDockSize = aSize;
+ nMask |= WINDOWSTATE_MASK_DOCKSIZE;
+ }
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_UINAME:
+ {
+ ::rtl::OUString aValue;
+ if ( a >>= aValue )
+ {
+ nMask |= WINDOWSTATE_MASK_UINAME;
+ aWindowStateInfo.aUIName = aValue;
+ }
+ }
+ break;
+
+ case PROPERTY_INTERNALSTATE:
+ {
+ sal_Int32 nValue = 0;
+ if ( a >>= nValue )
+ {
+ nMask |= WINDOWSTATE_MASK_INTERNALSTATE;
+ aWindowStateInfo.nInternalState = sal_uInt32( nValue );
+ }
+ }
+ break;
+
+ case PROPERTY_STYLE:
+ {
+ sal_Int32 nValue = 0;
+ if ( a >>= nValue )
+ {
+ nMask |= WINDOWSTATE_MASK_STYLE;
+ aWindowStateInfo.nStyle = sal_uInt16( nValue );
+ }
+ }
+
+ default:
+ DBG_ASSERT( sal_False, "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
+ }
+ }
+ catch( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+
+ aWindowStateInfo.nMask = nMask;
+ ResourceURLToInfoCache::iterator pIter = (m_aResourceURLToInfoCache.insert( ResourceURLToInfoCache::value_type( rResourceURL, aWindowStateInfo ))).first;
+ return pIter->second;
+}
+
+Any ConfigurationAccess_WindowState::impl_getWindowStateFromResourceURL( const rtl::OUString& rResourceURL )
+{
+ if ( !m_bConfigAccessInitialized )
+ {
+ impl_initializeConfigAccess();
+ m_bConfigAccessInitialized = sal_True;
+ }
+
+ try
+ {
+ // Try to ask our configuration access
+ if ( m_xConfigAccess.is() && m_xConfigAccess->hasByName( rResourceURL ) )
+ {
+
+ Reference< XNameAccess > xNameAccess( m_xConfigAccess->getByName( rResourceURL ), UNO_QUERY );
+ if ( xNameAccess.is() )
+ return impl_insertCacheAndReturnSequence( rResourceURL, xNameAccess );
+ }
+ }
+ catch( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+
+ return Any();
+}
+
+void ConfigurationAccess_WindowState::impl_fillStructFromSequence( WindowStateInfo& rWinStateInfo, const Sequence< PropertyValue >& rSeq )
+{
+ sal_Int32 nCompareCount( m_aPropArray.size() );
+ sal_Int32 nCount( rSeq.getLength() );
+ sal_Int32 i( 0 );
+
+ for ( i = 0; i < nCount; i++ )
+ {
+ for ( sal_Int32 j = 0; j < nCompareCount; j++ )
+ {
+ if ( rSeq[i].Name.equals( m_aPropArray[j] ))
+ {
+ switch ( j )
+ {
+ case PROPERTY_LOCKED:
+ case PROPERTY_DOCKED:
+ case PROPERTY_VISIBLE:
+ case PROPERTY_CONTEXT:
+ case PROPERTY_HIDEFROMMENU:
+ case PROPERTY_NOCLOSE:
+ case PROPERTY_SOFTCLOSE:
+ case PROPERTY_CONTEXTACTIVE:
+ {
+ sal_Bool bValue = sal_Bool();
+ if ( rSeq[i].Value >>= bValue )
+ {
+ sal_Int32 nValue( 1 << j );
+ rWinStateInfo.nMask |= nValue;
+ switch ( j )
+ {
+ case PROPERTY_LOCKED:
+ rWinStateInfo.bLocked = bValue;
+ break;
+ case PROPERTY_DOCKED:
+ rWinStateInfo.bDocked = bValue;
+ break;
+ case PROPERTY_VISIBLE:
+ rWinStateInfo.bVisible = bValue;
+ break;
+ case PROPERTY_CONTEXT:
+ rWinStateInfo.bContext = bValue;
+ break;
+ case PROPERTY_HIDEFROMMENU:
+ rWinStateInfo.bHideFromMenu = bValue;
+ break;
+ case PROPERTY_NOCLOSE:
+ rWinStateInfo.bNoClose = bValue;
+ break;
+ case PROPERTY_SOFTCLOSE:
+ rWinStateInfo.bSoftClose = bValue;
+ break;
+ case PROPERTY_CONTEXTACTIVE:
+ rWinStateInfo.bContextActive = bValue;
+ break;
+ default:
+ DBG_ASSERT( sal_False, "Unknown boolean property in WindowState found!" );
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_DOCKINGAREA:
+ {
+ ::com::sun::star::ui::DockingArea eDockingArea;
+ if ( rSeq[i].Value >>= eDockingArea )
+ {
+ rWinStateInfo.aDockingArea = eDockingArea;
+ rWinStateInfo.nMask |= WINDOWSTATE_MASK_DOCKINGAREA;
+ }
+ }
+ break;
+
+ case PROPERTY_POS:
+ case PROPERTY_DOCKPOS:
+ {
+ com::sun::star::awt::Point aPoint;
+ if ( rSeq[i].Value >>= aPoint )
+ {
+ if ( j == PROPERTY_POS )
+ {
+ rWinStateInfo.aPos = aPoint;
+ rWinStateInfo.nMask |= WINDOWSTATE_MASK_POS;
+ }
+ else
+ {
+ rWinStateInfo.aDockPos = aPoint;
+ rWinStateInfo.nMask |= WINDOWSTATE_MASK_DOCKPOS;
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_SIZE:
+ case PROPERTY_DOCKSIZE:
+ {
+ com::sun::star::awt::Size aSize;
+ if ( rSeq[i].Value >>= aSize )
+ {
+ if ( j == PROPERTY_SIZE )
+ {
+ rWinStateInfo.aSize = aSize;
+ rWinStateInfo.nMask |= WINDOWSTATE_MASK_SIZE;
+ }
+ else
+ {
+ rWinStateInfo.aDockSize = aSize;
+ rWinStateInfo.nMask |= WINDOWSTATE_MASK_DOCKSIZE;
+ }
+ }
+ }
+ break;
+
+ case PROPERTY_UINAME:
+ {
+ ::rtl::OUString aValue;
+ if ( rSeq[i].Value >>= aValue )
+ {
+ rWinStateInfo.aUIName = aValue;
+ rWinStateInfo.nMask |= WINDOWSTATE_MASK_UINAME;
+ }
+ }
+ break;
+
+ case PROPERTY_INTERNALSTATE:
+ {
+ sal_Int32 nValue = 0;
+ if ( rSeq[i].Value >>= nValue )
+ {
+ rWinStateInfo.nInternalState = sal_uInt32( nValue );
+ rWinStateInfo.nMask |= WINDOWSTATE_MASK_INTERNALSTATE;
+ }
+ }
+ break;
+
+ case PROPERTY_STYLE:
+ {
+ sal_Int32 nValue = 0;
+ if ( rSeq[i].Value >>= nValue )
+ {
+ rWinStateInfo.nStyle = sal_uInt16( nValue );
+ rWinStateInfo.nMask |= WINDOWSTATE_MASK_STYLE;
+ }
+ }
+ break;
+
+ default:
+ DBG_ASSERT( sal_False, "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
+ }
+
+ break;
+ }
+ }
+ }
+}
+
+void ConfigurationAccess_WindowState::impl_putPropertiesFromStruct( const WindowStateInfo& rWinStateInfo, Reference< XPropertySet >& xPropSet )
+{
+ sal_Int32 i( 0 );
+ sal_Int32 nCount( m_aPropArray.size() );
+ Sequence< PropertyValue > aPropSeq;
+ ::rtl::OUString aDelim( RTL_CONSTASCII_USTRINGPARAM(",") );
+
+ for ( i = 0; i < nCount; i++ )
+ {
+ if ( rWinStateInfo.nMask & ( 1 << i ))
+ {
+ try
+ {
+ // put values into the property set
+ switch ( i )
+ {
+ case PROPERTY_LOCKED:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bLocked )) ); break;
+ case PROPERTY_DOCKED:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bDocked )) ); break;
+ case PROPERTY_VISIBLE:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bVisible )) ); break;
+ case PROPERTY_CONTEXT:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bContext )) ); break;
+ case PROPERTY_HIDEFROMMENU:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bHideFromMenu )) ); break;
+ case PROPERTY_NOCLOSE:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bNoClose )) ); break;
+ case PROPERTY_SOFTCLOSE:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bSoftClose )) ); break;
+ case PROPERTY_CONTEXTACTIVE:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Bool( rWinStateInfo.bContextActive )) ); break;
+ case PROPERTY_DOCKINGAREA:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Int16( rWinStateInfo.aDockingArea ) ) ); break;
+ case PROPERTY_POS:
+ case PROPERTY_DOCKPOS:
+ {
+ ::rtl::OUString aPosStr;
+ if ( i == PROPERTY_POS )
+ aPosStr = ::rtl::OUString::valueOf( rWinStateInfo.aPos.X );
+ else
+ aPosStr = ::rtl::OUString::valueOf( rWinStateInfo.aDockPos.X );
+ aPosStr += aDelim;
+ if ( i == PROPERTY_POS )
+ aPosStr += ::rtl::OUString::valueOf( rWinStateInfo.aPos.Y );
+ else
+ aPosStr += ::rtl::OUString::valueOf( rWinStateInfo.aDockPos.Y );
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( aPosStr ) );
+ break;
+ }
+ case PROPERTY_SIZE:
+ case PROPERTY_DOCKSIZE:
+ {
+ ::rtl::OUString aSizeStr;
+ if ( i == PROPERTY_SIZE )
+ aSizeStr = ( ::rtl::OUString::valueOf( rWinStateInfo.aSize.Width ));
+ else
+ aSizeStr = ( ::rtl::OUString::valueOf( rWinStateInfo.aDockSize.Width ));
+ aSizeStr += aDelim;
+ if ( i == PROPERTY_SIZE )
+ aSizeStr += ::rtl::OUString::valueOf( rWinStateInfo.aSize.Height );
+ else
+ aSizeStr += ::rtl::OUString::valueOf( rWinStateInfo.aDockSize.Height );
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( aSizeStr ) );
+ break;
+ }
+ case PROPERTY_UINAME:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( rWinStateInfo.aUIName ) ); break;
+ case PROPERTY_INTERNALSTATE:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Int32( rWinStateInfo.nInternalState )) ); break;
+ case PROPERTY_STYLE:
+ xPropSet->setPropertyValue( m_aPropArray[i], makeAny( sal_Int32( rWinStateInfo.nStyle )) ); break;
+ default:
+ DBG_ASSERT( sal_False, "Wrong value for ConfigurationAccess_WindowState. Who has forgotten to add this new property!" );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+}
+
+sal_Bool ConfigurationAccess_WindowState::impl_initializeConfigAccess()
+{
+ Sequence< Any > aArgs( 2 );
+ PropertyValue aPropValue;
+
+ try
+ {
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
+ aPropValue.Value <<= m_aConfigWindowAccess;
+ aArgs[0] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "lazywrite" ));
+ aPropValue.Value <<= sal_True;
+ aArgs[1] <<= aPropValue;
+
+ m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(
+ SERVICENAME_CFGUPDATEACCESS, aArgs ),
+ UNO_QUERY );
+ if ( m_xConfigAccess.is() )
+ {
+ // Add as container listener
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ {
+ m_xConfigListener = new WeakContainerListener(this);
+ xContainer->addContainerListener(m_xConfigListener);
+ }
+ }
+
+ return sal_True;
+ }
+ catch ( WrappedTargetException& )
+ {
+ }
+ catch ( Exception& )
+ {
+ }
+
+ return sal_False;
+}
+
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_4 ( WindowStateConfiguration ,
+ OWeakObject ,
+ DIRECT_INTERFACE( css::lang::XTypeProvider ),
+ DIRECT_INTERFACE( css::lang::XServiceInfo ),
+ DIRECT_INTERFACE( css::container::XNameAccess ),
+ DERIVED_INTERFACE( css::container::XElementAccess, css::container::XNameAccess )
+ )
+
+DEFINE_XTYPEPROVIDER_4 ( WindowStateConfiguration ,
+ css::lang::XTypeProvider ,
+ css::lang::XServiceInfo ,
+ css::container::XNameAccess ,
+ css::container::XElementAccess
+ )
+
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( WindowStateConfiguration ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_WINDOWSTATECONFIGURATION ,
+ IMPLEMENTATIONNAME_WINDOWSTATECONFIGURATION
+ )
+
+DEFINE_INIT_SERVICE ( WindowStateConfiguration, {} )
+
+WindowStateConfiguration::WindowStateConfiguration( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase(),
+ m_xServiceManager( xServiceManager )
+{
+ m_xModuleManager = Reference< XModuleManager >( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ),
+ UNO_QUERY );
+ Reference< XNameAccess > xEmptyNameAccess;
+ Reference< XNameAccess > xNameAccess( m_xModuleManager, UNO_QUERY_THROW );
+ Sequence< rtl::OUString > aElementNames;
+ try
+ {
+ aElementNames = xNameAccess->getElementNames();
+ }
+ catch (::com::sun::star::uno::RuntimeException &)
+ {
+ }
+ Sequence< PropertyValue > aSeq;
+ ::rtl::OUString aModuleIdentifier;
+
+ for ( sal_Int32 i = 0; i < aElementNames.getLength(); i++ )
+ {
+ aModuleIdentifier = aElementNames[i];
+ if ( xNameAccess->getByName( aModuleIdentifier ) >>= aSeq )
+ {
+ ::rtl::OUString aWindowStateFileStr;
+ for ( sal_Int32 y = 0; y < aSeq.getLength(); y++ )
+ {
+ if ( aSeq[y].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ooSetupFactoryWindowStateConfigRef")) )
+ {
+ aSeq[y].Value >>= aWindowStateFileStr;
+ break;
+ }
+ }
+
+ if ( aWindowStateFileStr.getLength() > 0 )
+ {
+ // Create first mapping ModuleIdentifier ==> Window state configuration file
+ m_aModuleToFileHashMap.insert( ModuleToWindowStateFileMap::value_type( aModuleIdentifier, aWindowStateFileStr ));
+
+ // Create second mapping Command File ==> Window state configuration instance
+ ModuleToWindowStateConfigHashMap::iterator pIter = m_aModuleToWindowStateHashMap.find( aWindowStateFileStr );
+ if ( pIter == m_aModuleToWindowStateHashMap.end() )
+ m_aModuleToWindowStateHashMap.insert( ModuleToWindowStateConfigHashMap::value_type( aWindowStateFileStr, xEmptyNameAccess ));
+ }
+ }
+ }
+}
+
+WindowStateConfiguration::~WindowStateConfiguration()
+{
+ ResetableGuard aLock( m_aLock );
+ m_aModuleToFileHashMap.clear();
+ m_aModuleToWindowStateHashMap.clear();
+}
+
+Any SAL_CALL WindowStateConfiguration::getByName( const ::rtl::OUString& aModuleIdentifier )
+throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ ModuleToWindowStateFileMap::const_iterator pIter = m_aModuleToFileHashMap.find( aModuleIdentifier );
+ if ( pIter != m_aModuleToFileHashMap.end() )
+ {
+ Any a;
+ ::rtl::OUString aWindowStateConfigFile( pIter->second );
+
+ ModuleToWindowStateConfigHashMap::iterator pModuleIter = m_aModuleToWindowStateHashMap.find( aWindowStateConfigFile );
+ if ( pModuleIter != m_aModuleToWindowStateHashMap.end() )
+ {
+ if ( pModuleIter->second.is() )
+ a = makeAny( pModuleIter->second );
+ else
+ {
+ Reference< XNameAccess > xResourceURLWindowState;
+ ConfigurationAccess_WindowState* pModuleWindowState = new ConfigurationAccess_WindowState( aWindowStateConfigFile, m_xServiceManager );
+ xResourceURLWindowState = Reference< XNameAccess >( static_cast< cppu::OWeakObject* >( pModuleWindowState ),UNO_QUERY );
+ pModuleIter->second = xResourceURLWindowState;
+ a <<= xResourceURLWindowState;
+ }
+
+ return a;
+ }
+ }
+
+ throw NoSuchElementException();
+}
+
+Sequence< ::rtl::OUString > SAL_CALL WindowStateConfiguration::getElementNames()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ Sequence< rtl::OUString > aSeq( m_aModuleToFileHashMap.size() );
+
+ sal_Int32 n = 0;
+ ModuleToWindowStateFileMap::const_iterator pIter = m_aModuleToFileHashMap.begin();
+ while ( pIter != m_aModuleToFileHashMap.end() )
+ {
+ aSeq[n] = pIter->first;
+ ++pIter;
+ }
+
+ return aSeq;
+}
+
+sal_Bool SAL_CALL WindowStateConfiguration::hasByName( const ::rtl::OUString& aName )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ ModuleToWindowStateFileMap::const_iterator pIter = m_aModuleToFileHashMap.find( aName );
+ return ( pIter != m_aModuleToFileHashMap.end() );
+}
+
+// XElementAccess
+Type SAL_CALL WindowStateConfiguration::getElementType()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return( ::getCppuType( (const Reference< XNameAccess >*)NULL ) );
+}
+
+sal_Bool SAL_CALL WindowStateConfiguration::hasElements()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ // We always have at least one module. So it is valid to return true!
+ return sal_True;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/addonstoolbarmanager.cxx b/framework/source/uielement/addonstoolbarmanager.cxx
new file mode 100644
index 000000000000..a8c98847d7d1
--- /dev/null
+++ b/framework/source/uielement/addonstoolbarmanager.cxx
@@ -0,0 +1,540 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/addonstoolbarmanager.hxx>
+#include <uielement/toolbarmerger.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+
+#include <uielement/toolbar.hxx>
+#include <uielement/generictoolbarcontroller.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+#include <framework/imageproducer.hxx>
+#include <framework/sfxhelperfunctions.hxx>
+#include <classes/fwkresid.hxx>
+#include <classes/resource.hrc>
+#include <framework/addonsoptions.hxx>
+#include <uielement/comboboxtoolbarcontroller.hxx>
+#include <uielement/imagebuttontoolbarcontroller.hxx>
+#include <uielement/togglebuttontoolbarcontroller.hxx>
+#include <uielement/buttontoolbarcontroller.hxx>
+#include <uielement/spinfieldtoolbarcontroller.hxx>
+#include <uielement/edittoolbarcontroller.hxx>
+#include <uielement/dropdownboxtoolbarcontroller.hxx>
+#include <uielement/toolbarmerger.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/frame/XToolbarController.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/ui/DockingArea.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <svtools/imgdef.hxx>
+#include <svtools/toolboxcontroller.hxx>
+#include <toolkit/unohlp.hxx>
+
+#include <svtools/miscopt.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/syswin.hxx>
+#include <vcl/taskpanelist.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+static const char TOOLBOXITEM_SEPARATOR_STR[] = "private:separator";
+static const sal_uInt16 TOOLBOXITEM_SEPARATOR_STR_LEN = sizeof( TOOLBOXITEM_SEPARATOR_STR )-1;
+
+AddonsToolBarManager::AddonsToolBarManager( const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ const rtl::OUString& rResourceName,
+ ToolBar* pToolBar ) :
+ ToolBarManager( rServiceManager, rFrame, rResourceName, pToolBar )
+{
+ // Configuration data is retrieved from non-writable configuration layer. Therefor we
+ // must disable some menu entries.
+ m_bCanBeCustomized = sal_False;
+
+ m_pToolBar->SetMenuType( TOOLBOX_MENUTYPE_CLIPPEDITEMS );
+ m_pToolBar->SetSelectHdl( LINK( this, AddonsToolBarManager, Select) );
+ m_pToolBar->SetActivateHdl( LINK( this, AddonsToolBarManager, Activate) );
+ m_pToolBar->SetDeactivateHdl( LINK( this, AddonsToolBarManager, Deactivate) );
+ m_pToolBar->SetClickHdl( LINK( this, AddonsToolBarManager, Click ) );
+ m_pToolBar->SetDoubleClickHdl( LINK( this, AddonsToolBarManager, DoubleClick ) );
+ m_pToolBar->SetCommandHdl( LINK( this, AddonsToolBarManager, Command ) );
+ m_pToolBar->SetStateChangedHdl( LINK( this, AddonsToolBarManager, StateChanged ) );
+ m_pToolBar->SetDataChangedHdl( LINK( this, AddonsToolBarManager, DataChanged ) );
+}
+
+AddonsToolBarManager::~AddonsToolBarManager()
+{
+}
+
+static sal_Bool IsCorrectContext( const ::rtl::OUString& rModuleIdentifier, const ::rtl::OUString& aContextList )
+{
+ if ( aContextList.getLength() == 0 )
+ return sal_True;
+
+ if ( rModuleIdentifier.getLength() > 0 )
+ {
+ sal_Int32 nIndex = aContextList.indexOf( rModuleIdentifier );
+ return ( nIndex >= 0 );
+ }
+
+ return sal_False;
+}
+
+static Image RetrieveImage( Reference< com::sun::star::frame::XFrame >& rFrame,
+ const rtl::OUString& aImageId,
+ const rtl::OUString& aURL,
+ sal_Bool bBigImage
+)
+{
+ Image aImage;
+
+ if ( aImageId.getLength() > 0 )
+ {
+ aImage = framework::AddonsOptions().GetImageFromURL( aImageId, bBigImage );
+ if ( !!aImage )
+ return aImage;
+ else
+ aImage = GetImageFromURL( rFrame, aImageId, bBigImage );
+ if ( !!aImage )
+ return aImage;
+ }
+
+ aImage = framework::AddonsOptions().GetImageFromURL( aURL, bBigImage );
+ if ( !aImage )
+ aImage = GetImageFromURL( rFrame, aImageId, bBigImage );
+
+ return aImage;
+}
+
+// XComponent
+void SAL_CALL AddonsToolBarManager::dispose() throw( RuntimeException )
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ {
+ // Remove addon specific data from toolbar items.
+ ResetableGuard aGuard( m_aLock );
+ for ( sal_uInt16 n = 0; n < m_pToolBar->GetItemCount(); n++ )
+ {
+ sal_uInt16 nId( m_pToolBar->GetItemId( n ) );
+
+ if ( nId > 0 )
+ {
+ AddonsParams* pRuntimeItemData = (AddonsParams*)m_pToolBar->GetItemData( nId );
+ if ( pRuntimeItemData )
+ delete pRuntimeItemData;
+ m_pToolBar->SetItemData( nId, NULL );
+ }
+ }
+ }
+
+ // Base class will destroy our m_pToolBar member
+ ToolBarManager::dispose();
+}
+
+bool AddonsToolBarManager::MenuItemAllowed( sal_uInt16 nId ) const
+{
+ if (( nId == MENUITEM_TOOLBAR_VISIBLEBUTTON ) ||
+ ( nId == MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR ))
+ return false;
+ else
+ return true;
+}
+
+void AddonsToolBarManager::RefreshImages()
+{
+ sal_Bool bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() );
+ for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); nPos++ )
+ {
+ sal_uInt16 nId( m_pToolBar->GetItemId( nPos ) );
+
+ if ( nId > 0 )
+ {
+ ::rtl::OUString aCommandURL = m_pToolBar->GetItemCommand( nId );
+ ::rtl::OUString aImageId;
+ AddonsParams* pRuntimeItemData = (AddonsParams*)m_pToolBar->GetItemData( nId );
+ if ( pRuntimeItemData )
+ aImageId = pRuntimeItemData->aImageId;
+
+ m_pToolBar->SetItemImage(
+ nId,
+ RetrieveImage( m_xFrame, aImageId, aCommandURL, bBigImages )
+ );
+ }
+ }
+}
+
+void AddonsToolBarManager::FillToolbar( const Sequence< Sequence< PropertyValue > >& rAddonToolbar )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ sal_uInt16 nId( 1 );
+
+ RemoveControllers();
+
+ m_pToolBar->Clear();
+ m_aControllerMap.clear();
+
+ ::rtl::OUString aModuleIdentifier;
+ try
+ {
+ Reference< XModuleManager > xModuleManager(
+ m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
+ aModuleIdentifier = xModuleManager->identify( m_xFrame );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ Reference< XMultiComponentFactory > xToolbarControllerFactory( m_xToolbarControllerRegistration, UNO_QUERY );
+ Reference< XComponentContext > xComponentContext;
+ Reference< XPropertySet > xProps( m_xServiceManager, UNO_QUERY );
+
+ if ( xProps.is() )
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComponentContext;
+
+ sal_uInt32 nElements( 0 );
+ sal_Bool bAppendSeparator( sal_False );
+ Reference< XWindow > xToolbarWindow = VCLUnoHelper::GetInterface( m_pToolBar );
+ for ( sal_uInt32 n = 0; n < (sal_uInt32)rAddonToolbar.getLength(); n++ )
+ {
+ rtl::OUString aValueName;
+
+ rtl::OUString aURL;
+ rtl::OUString aTitle;
+ rtl::OUString aImageId;
+ rtl::OUString aContext;
+ rtl::OUString aTarget;
+ rtl::OUString aControlType;
+ sal_uInt16 nWidth( 0 );
+
+ const Sequence< PropertyValue >& rSeq = rAddonToolbar[n];
+
+ ToolBarMerger::ConvertSequenceToValues( rSeq, aURL, aTitle, aImageId, aTarget, aContext, aControlType, nWidth );
+
+ if ( IsCorrectContext( aModuleIdentifier, aContext ))
+ {
+ if ( aURL.equalsAsciiL( TOOLBOXITEM_SEPARATOR_STR, TOOLBOXITEM_SEPARATOR_STR_LEN ))
+ {
+ sal_uInt16 nCount = m_pToolBar->GetItemCount();
+ if ( nCount > 0 && ( m_pToolBar->GetItemType( nCount-1 ) != TOOLBOXITEM_SEPARATOR ) && nElements > 0 )
+ {
+ nElements = 0;
+ m_pToolBar->InsertSeparator();
+ }
+ }
+ else
+ {
+ sal_uInt16 nCount = m_pToolBar->GetItemCount();
+ if ( bAppendSeparator && nCount > 0 && ( m_pToolBar->GetItemType( nCount-1 ) != TOOLBOXITEM_SEPARATOR ))
+ {
+ // We have to append a separator first if the last item is not a separator
+ m_pToolBar->InsertSeparator();
+ }
+ bAppendSeparator = sal_False;
+
+ m_pToolBar->InsertItem( nId, aTitle );
+
+ Image aImage = RetrieveImage( m_xFrame, aImageId, aURL, !m_bSmallSymbols );
+ if ( !!aImage )
+ m_pToolBar->SetItemImage( nId, aImage );
+
+ // Create TbRuntimeItemData to hold additional information we will need in the future
+ AddonsParams* pRuntimeItemData = new AddonsParams;
+ pRuntimeItemData->aImageId = aImageId;
+ pRuntimeItemData->aTarget = aTarget;
+ m_pToolBar->SetItemData( nId, pRuntimeItemData );
+ m_pToolBar->SetItemCommand( nId, aURL );
+
+ Reference< XStatusListener > xController;
+
+ sal_Bool bMustBeInit( sal_True );
+
+ // Support external toolbar controller for add-ons!
+ if ( m_xToolbarControllerRegistration.is() &&
+ m_xToolbarControllerRegistration->hasController( aURL, m_aModuleIdentifier ))
+ {
+ if ( xToolbarControllerFactory.is() )
+ {
+ Sequence< Any > aArgs(5);
+ PropertyValue aPropValue;
+
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
+ aPropValue.Value <<= m_aModuleIdentifier;
+ aArgs[0] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropValue.Value <<= m_xFrame;
+ aArgs[1] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
+ aPropValue.Value <<= m_xServiceManager;
+ aArgs[2] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
+ aPropValue.Value <<= xToolbarWindow;
+ aArgs[3] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ItemId" ));
+ aPropValue.Value = makeAny( sal_Int32( nId ));
+ aArgs[4] <<= aPropValue;
+
+ try
+ {
+ xController = Reference< XStatusListener >( xToolbarControllerFactory->createInstanceWithArgumentsAndContext(
+ aURL, aArgs, xComponentContext ),
+ UNO_QUERY );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ bMustBeInit = sal_False; // factory called init already!
+ }
+ }
+ else
+ {
+ ::cppu::OWeakObject* pController = 0;
+
+ pController = ToolBarMerger::CreateController( m_xServiceManager, m_xFrame, m_pToolBar, aURL, nId, nWidth, aControlType );
+ xController = Reference< XStatusListener >( pController, UNO_QUERY );
+ }
+
+ // insert controller to the map
+ m_aControllerMap[nId] = xController;
+
+ Reference< XInitialization > xInit( xController, UNO_QUERY );
+ if ( xInit.is() && bMustBeInit )
+ {
+ PropertyValue aPropValue;
+ Sequence< Any > aArgs( 3 );
+ aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropValue.Value <<= m_xFrame;
+ aArgs[0] <<= aPropValue;
+ aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
+ aPropValue.Value <<= aURL;
+ aArgs[1] <<= aPropValue;
+ aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
+ aPropValue.Value <<= m_xServiceManager;
+ aArgs[2] <<= aPropValue;
+ try
+ {
+ xInit->initialize( aArgs );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+
+ // Request a item window from the toolbar controller and set it at the VCL toolbar
+ Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
+ if ( xTbxController.is() && xToolbarWindow.is() )
+ {
+ Reference< XWindow > xWindow = xTbxController->createItemWindow( xToolbarWindow );
+ if ( xWindow.is() )
+ {
+ Window* pItemWin = VCLUnoHelper::GetWindow( xWindow );
+ if ( pItemWin )
+ {
+ WindowType nType = pItemWin->GetType();
+ if ( nType == WINDOW_LISTBOX || nType == WINDOW_MULTILISTBOX || nType == WINDOW_COMBOBOX )
+ pItemWin->SetAccessibleName( m_pToolBar->GetItemText( nId ) );
+ m_pToolBar->SetItemWindow( nId, pItemWin );
+ }
+ }
+ }
+
+ // Notify controller implementation to its listeners. Controller is now useable from outside.
+ Reference< XUpdatable > xUpdatable( xController, UNO_QUERY );
+ if ( xUpdatable.is() )
+ {
+ try
+ {
+ xUpdatable->update();
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+
+ ++nId;
+ ++nElements;
+ }
+ }
+ }
+
+ AddFrameActionListener();
+}
+
+IMPL_LINK( AddonsToolBarManager, Click, ToolBox*, EMPTYARG )
+{
+ if ( m_bDisposed )
+ return 1;
+
+ sal_uInt16 nId( m_pToolBar->GetCurItemId() );
+ ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
+ if ( pIter != m_aControllerMap.end() )
+ {
+ Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
+
+ if ( xController.is() )
+ xController->click();
+ }
+
+ return 1;
+}
+
+IMPL_LINK( AddonsToolBarManager, DoubleClick, ToolBox*, EMPTYARG )
+{
+ if ( m_bDisposed )
+ return 1;
+
+ sal_uInt16 nId( m_pToolBar->GetCurItemId() );
+ ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
+ if ( pIter != m_aControllerMap.end() )
+ {
+ Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
+
+ if ( xController.is() )
+ xController->doubleClick();
+ }
+
+ return 1;
+}
+
+IMPL_LINK( AddonsToolBarManager, Command, CommandEvent*, EMPTYARG )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return 1;
+
+ return 0;
+}
+
+IMPL_LINK( AddonsToolBarManager, Select, ToolBox*, EMPTYARG )
+{
+ if ( m_bDisposed )
+ return 1;
+
+ sal_Int16 nKeyModifier( (sal_Int16)m_pToolBar->GetModifier() );
+ sal_uInt16 nId( m_pToolBar->GetCurItemId() );
+ ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
+ if ( pIter != m_aControllerMap.end() )
+ {
+ Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
+
+ if ( xController.is() )
+ xController->execute( nKeyModifier );
+ }
+
+ return 1;
+}
+
+IMPL_LINK( AddonsToolBarManager, Highlight, ToolBox*, EMPTYARG )
+{
+ return 1;
+}
+
+IMPL_LINK( AddonsToolBarManager, Activate, ToolBox*, EMPTYARG )
+{
+ return 1;
+}
+
+IMPL_LINK( AddonsToolBarManager, Deactivate, ToolBox*, EMPTYARG )
+{
+ return 1;
+}
+
+IMPL_LINK( AddonsToolBarManager, StateChanged, StateChangedType*, pStateChangedType )
+{
+ if ( *pStateChangedType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ CheckAndUpdateImages();
+ }
+ return 1;
+}
+
+IMPL_LINK( AddonsToolBarManager, DataChanged, DataChangedEvent*, pDataChangedEvent )
+{
+ if ((( pDataChangedEvent->GetType() == DATACHANGED_SETTINGS ) ||
+ ( pDataChangedEvent->GetType() == DATACHANGED_DISPLAY )) &&
+ ( pDataChangedEvent->GetFlags() & SETTINGS_STYLE ))
+ {
+ CheckAndUpdateImages();
+ }
+
+ for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos )
+ {
+ const sal_uInt16 nId = m_pToolBar->GetItemId(nPos);
+ Window* pWindow = m_pToolBar->GetItemWindow( nId );
+ if ( pWindow )
+ {
+ const DataChangedEvent& rDCEvt( *pDataChangedEvent );
+ pWindow->DataChanged( rDCEvt );
+ }
+ }
+
+ return 1;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/addonstoolbarwrapper.cxx b/framework/source/uielement/addonstoolbarwrapper.cxx
new file mode 100644
index 000000000000..49e74d12ca1a
--- /dev/null
+++ b/framework/source/uielement/addonstoolbarwrapper.cxx
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+
+#include <uielement/addonstoolbarwrapper.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <framework/actiontriggerhelper.hxx>
+#include <uielement/constitemcontainer.hxx>
+#include <uielement/rootitemcontainer.hxx>
+#include <uielement/addonstoolbarmanager.hxx>
+
+#include <uielement/toolbar.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
+#include <com/sun/star/awt/XMenuBar.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <toolkit/unohlp.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <svtools/miscopt.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::awt;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+AddonsToolBarWrapper::AddonsToolBarWrapper( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ UIElementWrapperBase( UIElementType::TOOLBAR ),
+ m_xServiceManager( xServiceManager )
+{
+}
+
+AddonsToolBarWrapper::~AddonsToolBarWrapper()
+{
+}
+
+// XComponent
+void SAL_CALL AddonsToolBarWrapper::dispose() throw ( RuntimeException )
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ com::sun::star::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_xToolBarManager.is() )
+ m_xToolBarManager->dispose();
+ m_xToolBarManager.clear();
+ m_xToolBarWindow.clear();
+
+ m_bDisposed = sal_True;
+}
+
+// XInitialization
+void SAL_CALL AddonsToolBarWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( !m_bInitialized )
+ {
+ UIElementWrapperBase::initialize( aArguments );
+
+ for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
+ {
+ PropertyValue aPropValue;
+ if ( aArguments[n] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ConfigurationData" ) ))
+ aPropValue.Value >>= m_aConfigData;
+ }
+ }
+
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ if ( xFrame.is() && m_aConfigData.getLength() > 0 )
+ {
+ // Create VCL based toolbar which will be filled with settings data
+ ToolBar* pToolBar = 0;
+ AddonsToolBarManager* pToolBarManager = 0;
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ if ( pWindow )
+ {
+ sal_uLong nStyles = WB_LINESPACING | WB_BORDER | WB_SCROLL | WB_MOVEABLE | WB_3DLOOK | WB_DOCKABLE | WB_SIZEABLE | WB_CLOSEABLE;
+
+ pToolBar = new ToolBar( pWindow, nStyles );
+ m_xToolBarWindow = VCLUnoHelper::GetInterface( pToolBar );
+ pToolBarManager = new AddonsToolBarManager( m_xServiceManager, xFrame, m_aResourceURL, pToolBar );
+ pToolBar->SetToolBarManager( pToolBarManager );
+ m_xToolBarManager = Reference< XComponent >( static_cast< OWeakObject *>( pToolBarManager ), UNO_QUERY );
+ }
+ }
+
+ try
+ {
+ if (( m_aConfigData.getLength() > 0 ) && pToolBar && pToolBarManager )
+ {
+ // Fill toolbar with container contents
+ pToolBarManager->FillToolbar( m_aConfigData );
+ pToolBar->SetOutStyle( SvtMiscOptions().GetToolboxStyle() );
+ pToolBar->EnableCustomize( sal_True );
+ ::Size aActSize( pToolBar->GetSizePixel() );
+ ::Size aSize( pToolBar->CalcWindowSizePixel() );
+ aSize.Width() = aActSize.Width();
+ pToolBar->SetSizePixel( aSize );
+ }
+ }
+ catch ( NoSuchElementException& )
+ {
+ }
+ }
+ }
+}
+
+// XUIElement interface
+Reference< XInterface > SAL_CALL AddonsToolBarWrapper::getRealInterface() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_xToolBarManager.is() )
+ {
+ AddonsToolBarManager* pToolBarManager = static_cast< AddonsToolBarManager *>( m_xToolBarManager.get() );
+ if ( pToolBarManager )
+ {
+ Window* pWindow = (Window *)pToolBarManager->GetToolBar();
+ return Reference< XInterface >( VCLUnoHelper::GetInterface( pWindow ), UNO_QUERY );
+ }
+ }
+
+ return Reference< XInterface >();
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/buttontoolbarcontroller.cxx b/framework/source/uielement/buttontoolbarcontroller.cxx
new file mode 100644
index 000000000000..c4d4f7b6c8fc
--- /dev/null
+++ b/framework/source/uielement/buttontoolbarcontroller.cxx
@@ -0,0 +1,335 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "uielement/buttontoolbarcontroller.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "uielement/toolbar.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <rtl/uri.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vcl/window.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/bitmap.hxx>
+#include <svtools/filter.hxx>
+#include <svtools/miscopt.hxx>
+#include <dispatch/uieventloghelper.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::util;
+
+namespace framework
+{
+
+ButtonToolbarController::ButtonToolbarController(
+ const uno::Reference< lang::XMultiServiceFactory >& rServiceManager,
+ ToolBox* pToolBar,
+ const rtl::OUString& aCommand ) :
+ cppu::OWeakObject(),
+ m_bInitialized( sal_False ),
+ m_bDisposed( sal_False ),
+ m_aCommandURL( aCommand ),
+ m_xServiceManager( rServiceManager ),
+ m_pToolbar( pToolBar )
+{
+}
+
+ButtonToolbarController::~ButtonToolbarController()
+{
+}
+
+ // XInterface
+uno::Any SAL_CALL ButtonToolbarController::queryInterface( const uno::Type& rType )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ Any a = ::cppu::queryInterface(
+ rType ,
+ static_cast< frame::XStatusListener* >( this ),
+ static_cast< frame::XToolbarController* >( this ),
+ static_cast< lang::XInitialization* >( this ),
+ static_cast< lang::XComponent* >( this ),
+ static_cast< util::XUpdatable* >( this ));
+
+ if ( a.hasValue() )
+ return a;
+
+ return cppu::OWeakObject::queryInterface( rType );
+}
+
+void SAL_CALL ButtonToolbarController::acquire() throw ()
+{
+ cppu::OWeakObject::acquire();
+}
+
+void SAL_CALL ButtonToolbarController::release() throw ()
+{
+ cppu::OWeakObject::release();
+}
+
+// XInitialization
+void SAL_CALL ButtonToolbarController::initialize(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ const rtl::OUString aFrameName( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ const rtl::OUString aCommandURLName( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
+ const rtl::OUString aServiceManagerName( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
+
+ bool bInitialized( true );
+
+ {
+ SolarMutexGuard aSolarMutexGuard;
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ bInitialized = m_bInitialized;
+ }
+
+ if ( !bInitialized )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ m_bInitialized = sal_True;
+
+ PropertyValue aPropValue;
+ for ( int i = 0; i < aArguments.getLength(); i++ )
+ {
+ if ( aArguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Frame" ) ))
+ m_xFrame.set(aPropValue.Value,UNO_QUERY);
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CommandURL" ) ))
+ aPropValue.Value >>= m_aCommandURL;
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ServiceManager" ) ))
+ m_xServiceManager.set(aPropValue.Value,UNO_QUERY);
+ }
+ }
+ }
+}
+
+// XComponent
+void SAL_CALL ButtonToolbarController::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ m_xServiceManager.clear();
+ m_xURLTransformer.clear();
+ m_xFrame.clear();
+ m_pToolbar = 0;
+ m_bDisposed = sal_True;
+ }
+}
+
+void SAL_CALL ButtonToolbarController::addEventListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ // do nothing
+}
+
+void SAL_CALL ButtonToolbarController::removeEventListener(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ // do nothing
+}
+
+// XUpdatable
+void SAL_CALL ButtonToolbarController::update()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aSolarMutexGuard;
+ if ( m_bDisposed )
+ throw DisposedException();
+}
+
+// XEventListener
+void SAL_CALL ButtonToolbarController::disposing(
+ const com::sun::star::lang::EventObject& Source )
+throw ( ::com::sun::star::uno::RuntimeException )
+{
+ uno::Reference< uno::XInterface > xSource( Source.Source );
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ if ( m_bDisposed )
+ return;
+
+ uno::Reference< uno::XInterface > xIfac( m_xFrame, uno::UNO_QUERY );
+ if ( xIfac == xSource )
+ m_xFrame.clear();
+}
+
+void SAL_CALL ButtonToolbarController::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& )
+throw ( ::com::sun::star::uno::RuntimeException )
+{
+ // do nothing
+ if ( m_bDisposed )
+ throw DisposedException();
+}
+
+// XToolbarController
+void SAL_CALL ButtonToolbarController::execute( sal_Int16 KeyModifier )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ uno::Reference< frame::XDispatch > xDispatch;
+ uno::Reference< frame::XFrame > xFrame;
+ uno::Reference< util::XURLTransformer > xURLTransformer;
+ rtl::OUString aCommandURL;
+ ::com::sun::star::util::URL aTargetURL;
+
+ {
+ SolarMutexGuard aSolarMutexGuard;
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_bInitialized &&
+ m_xFrame.is() &&
+ m_xServiceManager.is() &&
+ m_aCommandURL.getLength() )
+ {
+ if ( !m_xURLTransformer.is() )
+ {
+ m_xURLTransformer = uno::Reference< util::XURLTransformer >(
+ m_xServiceManager->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ uno::UNO_QUERY_THROW );
+ }
+
+ xFrame = m_xFrame;
+ aCommandURL = m_aCommandURL;
+ xURLTransformer = m_xURLTransformer;
+ }
+ }
+
+ uno::Reference< frame::XDispatchProvider > xDispatchProvider( xFrame, uno::UNO_QUERY );
+ if ( xDispatchProvider.is() )
+ {
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+ }
+
+ if ( xDispatch.is() )
+ {
+ try
+ {
+ Sequence<PropertyValue> aArgs( 1 );
+
+ // Provide key modifier information to dispatch function
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
+ aArgs[0].Value <<= KeyModifier;
+
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ButtonToolbarController"))).log(m_xServiceManager, m_xFrame, aTargetURL, aArgs);
+ xDispatch->dispatch( aTargetURL, aArgs );
+ }
+ catch ( DisposedException& )
+ {
+ }
+ }
+}
+
+void SAL_CALL ButtonToolbarController::click()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ sal_Int16 nKeyModifier( (sal_Int16)m_pToolbar->GetModifier() );
+ execute( nKeyModifier );
+}
+
+void SAL_CALL ButtonToolbarController::doubleClick()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ // do nothing
+ if ( m_bDisposed )
+ throw DisposedException();
+}
+
+uno::Reference< awt::XWindow > SAL_CALL ButtonToolbarController::createPopupWindow()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ return uno::Reference< awt::XWindow >();
+}
+
+uno::Reference< awt::XWindow > SAL_CALL ButtonToolbarController::createItemWindow(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ return uno::Reference< awt::XWindow >();
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/comboboxtoolbarcontroller.cxx b/framework/source/uielement/comboboxtoolbarcontroller.cxx
new file mode 100644
index 000000000000..45520e63b000
--- /dev/null
+++ b/framework/source/uielement/comboboxtoolbarcontroller.cxx
@@ -0,0 +1,445 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "uielement/comboboxtoolbarcontroller.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "uielement/toolbar.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/status/ItemStatus.hpp>
+#include <com/sun/star/frame/status/ItemState.hpp>
+#include <com/sun/star/frame/status/Visibility.hpp>
+#include <com/sun/star/frame/XControlNotificationListener.hpp>
+#include <com/sun/star/util/Color.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <svtools/toolboxcontroller.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/combobox.hxx>
+#include <tools/urlobj.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::frame::status;
+using namespace ::com::sun::star::util;
+
+namespace framework
+{
+
+// ------------------------------------------------------------------
+
+// Wrapper class to notify controller about events from combobox.
+// Unfortunaltly the events are notifed through virtual methods instead
+// of Listeners.
+
+class ComboBoxControl : public ComboBox
+{
+ public:
+ ComboBoxControl( Window* pParent, WinBits nStyle, IComboBoxListener* pComboBoxListener );
+ virtual ~ComboBoxControl();
+
+ virtual void Select();
+ virtual void DoubleClick();
+ virtual void Modify();
+ virtual void KeyInput( const ::KeyEvent& rKEvt );
+ virtual void GetFocus();
+ virtual void LoseFocus();
+ virtual long PreNotify( NotifyEvent& rNEvt );
+
+ private:
+ IComboBoxListener* m_pComboBoxListener;
+};
+
+ComboBoxControl::ComboBoxControl( Window* pParent, WinBits nStyle, IComboBoxListener* pComboBoxListener ) :
+ ComboBox( pParent, nStyle )
+ , m_pComboBoxListener( pComboBoxListener )
+{
+}
+
+ComboBoxControl::~ComboBoxControl()
+{
+ m_pComboBoxListener = 0;
+}
+
+void ComboBoxControl::Select()
+{
+ ComboBox::Select();
+ if ( m_pComboBoxListener )
+ m_pComboBoxListener->Select();
+}
+
+void ComboBoxControl::DoubleClick()
+{
+ ComboBox::DoubleClick();
+ if ( m_pComboBoxListener )
+ m_pComboBoxListener->DoubleClick();
+}
+
+void ComboBoxControl::Modify()
+{
+ ComboBox::Modify();
+ if ( m_pComboBoxListener )
+ m_pComboBoxListener->Modify();
+}
+
+void ComboBoxControl::KeyInput( const ::KeyEvent& rKEvt )
+{
+ ComboBox::KeyInput( rKEvt );
+ if ( m_pComboBoxListener )
+ m_pComboBoxListener->KeyInput( rKEvt );
+}
+
+void ComboBoxControl::GetFocus()
+{
+ ComboBox::GetFocus();
+ if ( m_pComboBoxListener )
+ m_pComboBoxListener->GetFocus();
+}
+
+void ComboBoxControl::LoseFocus()
+{
+ ComboBox::LoseFocus();
+ if ( m_pComboBoxListener )
+ m_pComboBoxListener->LoseFocus();
+}
+
+long ComboBoxControl::PreNotify( NotifyEvent& rNEvt )
+{
+ long nRet( 0 );
+ if ( m_pComboBoxListener )
+ nRet = m_pComboBoxListener->PreNotify( rNEvt );
+ if ( nRet == 0 )
+ nRet = ComboBox::PreNotify( rNEvt );
+
+ return nRet;
+}
+
+// ------------------------------------------------------------------
+
+ComboboxToolbarController::ComboboxToolbarController(
+ const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nID,
+ sal_Int32 nWidth,
+ const ::rtl::OUString& aCommand ) :
+ ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand )
+ , m_pComboBox( 0 )
+{
+ m_pComboBox = new ComboBoxControl( m_pToolbar, WB_DROPDOWN, this );
+ if ( nWidth == 0 )
+ nWidth = 100;
+
+ // default dropdown size
+ ::Size aLogicalSize( 8, 160 );
+ ::Size aPixelSize = m_pComboBox->LogicToPixel( aLogicalSize, MAP_APPFONT );
+
+ m_pComboBox->SetSizePixel( ::Size( nWidth, aPixelSize.Height() ));
+ m_pToolbar->SetItemWindow( m_nID, m_pComboBox );
+}
+
+// ------------------------------------------------------------------
+
+ComboboxToolbarController::~ComboboxToolbarController()
+{
+}
+
+// ------------------------------------------------------------------
+
+void SAL_CALL ComboboxToolbarController::dispose()
+throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ m_pToolbar->SetItemWindow( m_nID, 0 );
+ delete m_pComboBox;
+
+ ComplexToolbarController::dispose();
+
+ m_pComboBox = 0;
+}
+
+// ------------------------------------------------------------------
+Sequence<PropertyValue> ComboboxToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
+{
+ Sequence<PropertyValue> aArgs( 2 );
+ ::rtl::OUString aSelectedText = m_pComboBox->GetText();
+
+ // Add key modifier to argument list
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
+ aArgs[0].Value <<= KeyModifier;
+ aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
+ aArgs[1].Value <<= aSelectedText;
+ return aArgs;
+}
+
+// ------------------------------------------------------------------
+
+void ComboboxToolbarController::Select()
+{
+ if ( m_pComboBox->GetEntryCount() > 0 )
+ {
+ Window::PointerState aState = m_pComboBox->GetPointerState();
+
+ sal_uInt16 nKeyModifier = sal_uInt16( aState.mnState & KEY_MODTYPE );
+ execute( nKeyModifier );
+ }
+}
+
+void ComboboxToolbarController::DoubleClick()
+{
+}
+
+void ComboboxToolbarController::Modify()
+{
+ notifyTextChanged( m_pComboBox->GetText() );
+}
+
+void ComboboxToolbarController::KeyInput( const ::KeyEvent& )
+{
+}
+
+void ComboboxToolbarController::GetFocus()
+{
+ notifyFocusGet();
+}
+
+void ComboboxToolbarController::LoseFocus()
+{
+ notifyFocusLost();
+}
+
+long ComboboxToolbarController::PreNotify( NotifyEvent& rNEvt )
+{
+ switch ( rNEvt.GetType() )
+ {
+ case EVENT_KEYINPUT :
+ {
+ const ::KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ const KeyCode& rKeyCode = pKeyEvent->GetKeyCode();
+ if(( rKeyCode.GetModifier() | rKeyCode.GetCode()) == KEY_RETURN )
+ {
+ // Call execute only with non-empty text
+ if ( m_pComboBox->GetText().Len() > 0 )
+ execute( rKeyCode.GetModifier() );
+ return 1;
+ }
+ }
+ break;
+ case EVENT_GETFOCUS :
+ notifyFocusGet();
+ break;
+ case EVENT_LOSEFOCUS :
+ notifyFocusLost();
+ break;
+ default :
+ break;
+ }
+ return 0;
+}
+
+// --------------------------------------------------------
+
+void ComboboxToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
+{
+ if ( rControlCommand.Command.equalsAsciiL( "SetText", 7 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ {
+ rtl::OUString aText;
+ rControlCommand.Arguments[i].Value >>= aText;
+ m_pComboBox->SetText( aText );
+
+ // send notification
+ notifyTextChanged( aText );
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "SetList", 7 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "List", 4 ))
+ {
+ Sequence< ::rtl::OUString > aList;
+ m_pComboBox->Clear();
+
+ rControlCommand.Arguments[i].Value >>= aList;
+ for ( sal_Int32 j = 0; j < aList.getLength(); j++ )
+ m_pComboBox->InsertEntry( aList[j] );
+
+ // send notification
+ uno::Sequence< beans::NamedValue > aInfo( 1 );
+ aInfo[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ));
+ aInfo[0].Value <<= aList;
+ addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListChanged" )),
+ getDispatchFromCommand( m_aCommandURL ),
+ aInfo );
+
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "AddEntry", 8 ))
+ {
+ sal_uInt16 nPos( COMBOBOX_APPEND );
+ rtl::OUString aText;
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ {
+ if ( rControlCommand.Arguments[i].Value >>= aText )
+ m_pComboBox->InsertEntry( aText, nPos );
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "InsertEntry", 11 ))
+ {
+ sal_uInt16 nPos( COMBOBOX_APPEND );
+ rtl::OUString aText;
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
+ {
+ sal_Int32 nTmpPos = 0;
+ if ( rControlCommand.Arguments[i].Value >>= nTmpPos )
+ {
+ if (( nTmpPos >= 0 ) &&
+ ( nTmpPos < sal_Int32( m_pComboBox->GetEntryCount() )))
+ nPos = sal_uInt16( nTmpPos );
+ }
+ }
+ else if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ rControlCommand.Arguments[i].Value >>= aText;
+ }
+
+ m_pComboBox->InsertEntry( aText, nPos );
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryPos", 14 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
+ {
+ sal_Int32 nPos( -1 );
+ if ( rControlCommand.Arguments[i].Value >>= nPos )
+ {
+ if ( nPos < sal_Int32( m_pComboBox->GetEntryCount() ))
+ m_pComboBox->RemoveEntry( sal_uInt16( nPos ));
+ }
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryText", 15 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ {
+ rtl::OUString aText;
+ if ( rControlCommand.Arguments[i].Value >>= aText )
+ m_pComboBox->RemoveEntry( aText );
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "SetDropDownLines", 16 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Lines", 5 ))
+ {
+ sal_Int32 nValue( 5 );
+ rControlCommand.Arguments[i].Value >>= nValue;
+ m_pComboBox->SetDropDownLineCount( sal_uInt16( nValue ));
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "SetBackgroundColor", 18 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Color", 5 ))
+ {
+ com::sun::star::util::Color aColor(0);
+ if ( rControlCommand.Arguments[i].Value >>= aColor )
+ {
+ ::Color aBackColor( static_cast< sal_uInt32 >( aColor ));
+ m_pComboBox->SetControlBackground( aBackColor );
+ }
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "SetTextColor", 12 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Color", 5 ))
+ {
+ com::sun::star::util::Color aColor(0);
+ if ( rControlCommand.Arguments[i].Value >>= aColor )
+ {
+ ::Color aForeColor( static_cast< sal_uInt32 >( aColor ));
+ m_pComboBox->SetControlForeground( aForeColor );
+ }
+ break;
+ }
+ }
+ }
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/complextoolbarcontroller.cxx b/framework/source/uielement/complextoolbarcontroller.cxx
new file mode 100644
index 000000000000..b52e4cd66f1c
--- /dev/null
+++ b/framework/source/uielement/complextoolbarcontroller.cxx
@@ -0,0 +1,386 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "uielement/complextoolbarcontroller.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "uielement/toolbar.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/frame/status/ItemStatus.hpp>
+#include <com/sun/star/frame/status/ItemState.hpp>
+#include <com/sun/star/frame/status/Visibility.hpp>
+#include <com/sun/star/frame/XControlNotificationListener.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <svtools/toolboxcontroller.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <tools/urlobj.hxx>
+#include <dispatch/uieventloghelper.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::frame::status;
+using namespace ::com::sun::star::util;
+
+namespace framework
+{
+
+// ------------------------------------------------------------------
+
+ComplexToolbarController::ComplexToolbarController(
+ const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nID,
+ const ::rtl::OUString& aCommand ) :
+ svt::ToolboxController( rServiceManager, rFrame, aCommand )
+ , m_pToolbar( pToolbar )
+ , m_nID( nID )
+ , m_bMadeInvisible( sal_False )
+{
+ m_xURLTransformer.set( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY_THROW );
+}
+
+// ------------------------------------------------------------------
+
+ComplexToolbarController::~ComplexToolbarController()
+{
+}
+
+// ------------------------------------------------------------------
+
+void SAL_CALL ComplexToolbarController::dispose()
+throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ m_pToolbar->SetItemWindow( m_nID, 0 );
+ svt::ToolboxController::dispose();
+
+ m_xURLTransformer.clear();
+ m_pToolbar = 0;
+ m_nID = 0;
+}
+
+// ------------------------------------------------------------------
+Sequence<PropertyValue> ComplexToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
+{
+ Sequence<PropertyValue> aArgs( 1 );
+
+ // Add key modifier to argument list
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
+ aArgs[0].Value <<= KeyModifier;
+ return aArgs;
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL ComplexToolbarController::execute( sal_Int16 KeyModifier )
+throw ( RuntimeException )
+{
+ Reference< XDispatch > xDispatch;
+ Reference< XURLTransformer > xURLTransformer;
+ ::rtl::OUString aCommandURL;
+ ::com::sun::star::util::URL aTargetURL;
+ Sequence<PropertyValue> aArgs;
+
+ {
+ SolarMutexGuard aSolarMutexGuard;
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_bInitialized &&
+ m_xFrame.is() &&
+ m_xServiceManager.is() &&
+ m_aCommandURL.getLength() )
+ {
+ xURLTransformer = m_xURLTransformer;
+ xDispatch = getDispatchFromCommand( m_aCommandURL );
+ aCommandURL = m_aCommandURL;
+ aTargetURL = getInitializedURL();
+ aArgs = getExecuteArgs(KeyModifier);
+ }
+ }
+
+ if ( xDispatch.is() && aTargetURL.Complete.getLength() > 0 )
+ {
+ // Execute dispatch asynchronously
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+ pExecuteInfo->xDispatch = xDispatch;
+ pExecuteInfo->aTargetURL = aTargetURL;
+ pExecuteInfo->aArgs = aArgs;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ComplexToolbarController"))).log(
+ m_xServiceManager,
+ m_xFrame,
+ aTargetURL,
+ aArgs);
+ Application::PostUserEvent( STATIC_LINK(0, ComplexToolbarController , ExecuteHdl_Impl), pExecuteInfo );
+ }
+}
+
+// ------------------------------------------------------------------
+
+void ComplexToolbarController::statusChanged( const FeatureStateEvent& Event )
+throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ if ( m_bDisposed )
+ return;
+
+ if ( m_pToolbar )
+ {
+ m_pToolbar->EnableItem( m_nID, Event.IsEnabled );
+
+ sal_uInt16 nItemBits = m_pToolbar->GetItemBits( m_nID );
+ nItemBits &= ~TIB_CHECKABLE;
+ TriState eTri = STATE_NOCHECK;
+
+ sal_Bool bValue = sal_Bool();
+ rtl::OUString aStrValue;
+ ItemStatus aItemState;
+ Visibility aItemVisibility;
+ ControlCommand aControlCommand;
+
+ if ( Event.State >>= bValue )
+ {
+ // Boolean, treat it as checked/unchecked
+ if ( m_bMadeInvisible )
+ m_pToolbar->ShowItem( m_nID, sal_True );
+ m_pToolbar->CheckItem( m_nID, bValue );
+ if ( bValue )
+ eTri = STATE_CHECK;
+ nItemBits |= TIB_CHECKABLE;
+ }
+ else if ( Event.State >>= aStrValue )
+ {
+ ::rtl::OUString aText( MnemonicGenerator::EraseAllMnemonicChars( aStrValue ) );
+ m_pToolbar->SetItemText( m_nID, aText );
+ m_pToolbar->SetQuickHelpText( m_nID, aText );
+
+ if ( m_bMadeInvisible )
+ m_pToolbar->ShowItem( m_nID, sal_True );
+ }
+ else if ( Event.State >>= aItemState )
+ {
+ eTri = STATE_DONTKNOW;
+ nItemBits |= TIB_CHECKABLE;
+ if ( m_bMadeInvisible )
+ m_pToolbar->ShowItem( m_nID, sal_True );
+ }
+ else if ( Event.State >>= aItemVisibility )
+ {
+ m_pToolbar->ShowItem( m_nID, aItemVisibility.bVisible );
+ m_bMadeInvisible = !aItemVisibility.bVisible;
+ }
+ else if ( Event.State >>= aControlCommand )
+ {
+ executeControlCommand( aControlCommand );
+ if ( m_bMadeInvisible )
+ m_pToolbar->ShowItem( m_nID, sal_True );
+ }
+
+ else if ( m_bMadeInvisible )
+ m_pToolbar->ShowItem( m_nID, sal_True );
+
+ m_pToolbar->SetItemState( m_nID, eTri );
+ m_pToolbar->SetItemBits( m_nID, nItemBits );
+ }
+}
+
+// ------------------------------------------------------------------
+
+IMPL_STATIC_LINK_NOINSTANCE( ComplexToolbarController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
+{
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+ try
+ {
+ // Asynchronous execution as this can lead to our own destruction!
+ // Framework can recycle our current frame and the layout manager disposes all user interface
+ // elements if a component gets detached from its frame!
+ pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ Application::AcquireSolarMutex( nRef );
+ delete pExecuteInfo;
+ return 0;
+}
+
+// ------------------------------------------------------------------
+
+IMPL_STATIC_LINK_NOINSTANCE( ComplexToolbarController, Notify_Impl, NotifyInfo*, pNotifyInfo )
+{
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+ try
+ {
+ // Asynchronous execution: As this can lead to our own destruction!
+ // Framework can recycle our current frame and the layout manager disposes all user interface
+ // elements if a component gets detached from its frame!
+ frame::ControlEvent aEvent;
+ aEvent.aURL = pNotifyInfo->aSourceURL;
+ aEvent.Event = pNotifyInfo->aEventName;
+ aEvent.aInformation = pNotifyInfo->aInfoSeq;
+ pNotifyInfo->xNotifyListener->controlEvent( aEvent );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ Application::AcquireSolarMutex( nRef );
+ delete pNotifyInfo;
+ return 0;
+}
+
+// ------------------------------------------------------------------
+
+void ComplexToolbarController::addNotifyInfo(
+ const rtl::OUString& aEventName,
+ const uno::Reference< frame::XDispatch >& xDispatch,
+ const uno::Sequence< beans::NamedValue >& rInfo )
+{
+ uno::Reference< frame::XControlNotificationListener > xControlNotify( xDispatch, uno::UNO_QUERY );
+
+ if ( xControlNotify.is() )
+ {
+ // Execute notification asynchronously
+ NotifyInfo* pNotifyInfo = new NotifyInfo;
+
+ pNotifyInfo->aEventName = aEventName;
+ pNotifyInfo->xNotifyListener = xControlNotify;
+ pNotifyInfo->aSourceURL = getInitializedURL();
+
+ // Add frame as source to the information sequence
+ sal_Int32 nCount = rInfo.getLength();
+ uno::Sequence< beans::NamedValue > aInfoSeq( rInfo );
+ aInfoSeq.realloc( nCount+1 );
+ aInfoSeq[nCount].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Source" ));
+ aInfoSeq[nCount].Value = uno::makeAny( getFrameInterface() );
+ pNotifyInfo->aInfoSeq = aInfoSeq;
+
+ Application::PostUserEvent( STATIC_LINK(0, ComplexToolbarController, Notify_Impl), pNotifyInfo );
+ }
+}
+
+// --------------------------------------------------------
+sal_Int32 ComplexToolbarController::getFontSizePixel( const Window* pWindow )
+{
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ const Font& rFont = rSettings.GetAppFont();
+
+ // Calculate height of the application font used by window
+ sal_Int32 nHeight = sal_Int32( rFont.GetHeight() );
+ ::Size aPixelSize = pWindow->LogicToPixel( ::Size( 0, nHeight ), MAP_APPFONT );
+ return aPixelSize.Height();
+}
+
+// --------------------------------------------------------
+
+uno::Reference< frame::XDispatch > ComplexToolbarController::getDispatchFromCommand( const rtl::OUString& aCommand ) const
+{
+ uno::Reference< frame::XDispatch > xDispatch;
+
+ if ( m_bInitialized && m_xFrame.is() && m_xServiceManager.is() && aCommand.getLength() )
+ {
+ URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( aCommand );
+ if ( pIter != m_aListenerMap.end() )
+ xDispatch = pIter->second;
+ }
+
+ return xDispatch;
+}
+
+// --------------------------------------------------------
+
+const ::com::sun::star::util::URL& ComplexToolbarController::getInitializedURL()
+{
+ if ( m_aURL.Complete.getLength() == 0 )
+ {
+ m_aURL.Complete = m_aCommandURL;
+ m_xURLTransformer->parseStrict( m_aURL );
+ }
+ return m_aURL;
+}
+
+void ComplexToolbarController::notifyFocusGet()
+{
+ // send focus get notification
+ uno::Sequence< beans::NamedValue > aInfo;
+ addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FocusSet" )),
+ getDispatchFromCommand( m_aCommandURL ),
+ aInfo );
+}
+
+void ComplexToolbarController::notifyFocusLost()
+{
+ // send focus lost notification
+ uno::Sequence< beans::NamedValue > aInfo;
+ addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FocusLost" )),
+ getDispatchFromCommand( m_aCommandURL ),
+ aInfo );
+}
+
+void ComplexToolbarController::notifyTextChanged( const ::rtl::OUString& aText )
+{
+ // send text changed notification
+ uno::Sequence< beans::NamedValue > aInfo( 1 );
+ aInfo[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
+ aInfo[0].Value <<= aText;
+ addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TextChanged" )),
+ getDispatchFromCommand( m_aCommandURL ),
+ aInfo );
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/controlmenucontroller.cxx b/framework/source/uielement/controlmenucontroller.cxx
new file mode 100644
index 000000000000..e0ec7dd7d703
--- /dev/null
+++ b/framework/source/uielement/controlmenucontroller.cxx
@@ -0,0 +1,436 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <sal/macros.h>
+#include <uielement/controlmenucontroller.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <svl/solar.hrc>
+#include <tools/rcid.h>
+#include <vcl/image.hxx>
+#include <svtools/menuoptions.hxx>
+#include <dispatch/uieventloghelper.hxx>
+#include <osl/mutex.hxx>
+
+// Copied from svx
+// Function-Id's
+#define RID_FMSHELL_CONVERSIONMENU (RID_FORMS_START + 4)
+#define RID_SVXIMGLIST_FMEXPL (RID_FORMS_START + 0)
+
+// Forms - Ids, used to address images from image list
+#define SID_FMSLOTS_START (SID_SVX_START + 592)
+#define SID_MORE_FMSLOTS_START (SID_SVX_START + 702)
+
+#define SID_FM_CONVERTTO_EDIT (SID_MORE_FMSLOTS_START + 32)
+#define SID_FM_CONVERTTO_BUTTON (SID_MORE_FMSLOTS_START + 33)
+#define SID_FM_CONVERTTO_FIXEDTEXT (SID_MORE_FMSLOTS_START + 34)
+#define SID_FM_CONVERTTO_LISTBOX (SID_MORE_FMSLOTS_START + 35)
+#define SID_FM_CONVERTTO_CHECKBOX (SID_MORE_FMSLOTS_START + 36)
+#define SID_FM_CONVERTTO_RADIOBUTTON (SID_MORE_FMSLOTS_START + 37)
+#define SID_FM_CONVERTTO_GROUPBOX (SID_MORE_FMSLOTS_START + 38)
+#define SID_FM_CONVERTTO_COMBOBOX (SID_MORE_FMSLOTS_START + 39)
+#define SID_FM_CONVERTTO_GRID (SID_MORE_FMSLOTS_START + 40)
+#define SID_FM_CONVERTTO_IMAGEBUTTON (SID_MORE_FMSLOTS_START + 41)
+#define SID_FM_CONVERTTO_FILECONTROL (SID_MORE_FMSLOTS_START + 42)
+#define SID_FM_CONVERTTO_DATE (SID_MORE_FMSLOTS_START + 43)
+#define SID_FM_CONVERTTO_TIME (SID_MORE_FMSLOTS_START + 44)
+#define SID_FM_CONVERTTO_NUMERIC (SID_MORE_FMSLOTS_START + 45)
+#define SID_FM_CONVERTTO_CURRENCY (SID_MORE_FMSLOTS_START + 46)
+#define SID_FM_CONVERTTO_PATTERN (SID_MORE_FMSLOTS_START + 47)
+#define SID_FM_CONVERTTO_IMAGECONTROL (SID_MORE_FMSLOTS_START + 48)
+#define SID_FM_CONVERTTO_FORMATTED (SID_MORE_FMSLOTS_START + 49)
+#define SID_FM_CONVERTTO_SCROLLBAR (SID_MORE_FMSLOTS_START + 68)
+#define SID_FM_CONVERTTO_SPINBUTTON (SID_MORE_FMSLOTS_START + 69)
+
+#define SID_FM_DATEFIELD (SID_MORE_FMSLOTS_START + 2)
+#define SID_FM_TIMEFIELD (SID_MORE_FMSLOTS_START + 3)
+#define SID_FM_NUMERICFIELD (SID_MORE_FMSLOTS_START + 4)
+#define SID_FM_CURRENCYFIELD (SID_MORE_FMSLOTS_START + 5)
+#define SID_FM_PATTERNFIELD (SID_MORE_FMSLOTS_START + 6)
+#define SID_FM_IMAGECONTROL (SID_MORE_FMSLOTS_START + 8)
+#define SID_FM_FORMATTEDFIELD (SID_MORE_FMSLOTS_START + 26)
+#define SID_FM_SCROLLBAR (SID_MORE_FMSLOTS_START + 66)
+#define SID_FM_SPINBUTTON (SID_MORE_FMSLOTS_START + 67)
+#define SID_FM_CONFIG (SID_FMSLOTS_START + 1)
+#define SID_FM_PUSHBUTTON (SID_FMSLOTS_START + 2)
+#define SID_FM_RADIOBUTTON (SID_FMSLOTS_START + 3)
+#define SID_FM_CHECKBOX (SID_FMSLOTS_START + 4)
+#define SID_FM_FIXEDTEXT (SID_FMSLOTS_START + 5)
+#define SID_FM_GROUPBOX (SID_FMSLOTS_START + 6)
+#define SID_FM_EDIT (SID_FMSLOTS_START + 7)
+#define SID_FM_LISTBOX (SID_FMSLOTS_START + 8)
+#define SID_FM_COMBOBOX (SID_FMSLOTS_START + 9)
+#define SID_FM_URLBUTTON (SID_FMSLOTS_START + 10)
+#define SID_FM_DBGRID (SID_FMSLOTS_START + 11)
+#define SID_FM_IMAGEBUTTON (SID_FMSLOTS_START + 12)
+#define SID_FM_FILECONTROL (SID_FMSLOTS_START + 13)
+
+sal_Int16 nConvertSlots[] =
+{
+ SID_FM_CONVERTTO_EDIT,
+ SID_FM_CONVERTTO_BUTTON,
+ SID_FM_CONVERTTO_FIXEDTEXT,
+ SID_FM_CONVERTTO_LISTBOX,
+ SID_FM_CONVERTTO_CHECKBOX,
+ SID_FM_CONVERTTO_RADIOBUTTON,
+ SID_FM_CONVERTTO_GROUPBOX,
+ SID_FM_CONVERTTO_COMBOBOX,
+// SID_FM_CONVERTTO_GRID,
+ SID_FM_CONVERTTO_IMAGEBUTTON,
+ SID_FM_CONVERTTO_FILECONTROL,
+ SID_FM_CONVERTTO_DATE,
+ SID_FM_CONVERTTO_TIME,
+ SID_FM_CONVERTTO_NUMERIC,
+ SID_FM_CONVERTTO_CURRENCY,
+ SID_FM_CONVERTTO_PATTERN,
+ SID_FM_CONVERTTO_IMAGECONTROL,
+ SID_FM_CONVERTTO_FORMATTED,
+ SID_FM_CONVERTTO_SCROLLBAR,
+ SID_FM_CONVERTTO_SPINBUTTON
+};
+
+sal_Int16 nCreateSlots[] =
+{
+ SID_FM_EDIT,
+ SID_FM_PUSHBUTTON,
+ SID_FM_FIXEDTEXT,
+ SID_FM_LISTBOX,
+ SID_FM_CHECKBOX,
+ SID_FM_RADIOBUTTON,
+ SID_FM_GROUPBOX,
+ SID_FM_COMBOBOX,
+// SID_FM_DBGRID,
+ SID_FM_IMAGEBUTTON,
+ SID_FM_FILECONTROL,
+ SID_FM_DATEFIELD,
+ SID_FM_TIMEFIELD,
+ SID_FM_NUMERICFIELD,
+ SID_FM_CURRENCYFIELD,
+ SID_FM_PATTERNFIELD,
+ SID_FM_IMAGECONTROL,
+ SID_FM_FORMATTEDFIELD,
+ SID_FM_SCROLLBAR,
+ SID_FM_SPINBUTTON
+};
+
+const char* aCommands[] =
+{
+ ".uno:ConvertToEdit",
+ ".uno:ConvertToButton",
+ ".uno:ConvertToFixed",
+ ".uno:ConvertToList",
+ ".uno:ConvertToCheckBox",
+ ".uno:ConvertToRadio",
+ ".uno:ConvertToGroup",
+ ".uno:ConvertToCombo",
+// ".uno:ConvertToGrid",
+ ".uno:ConvertToImageBtn",
+ ".uno:ConvertToFileControl",
+ ".uno:ConvertToDate",
+ ".uno:ConvertToTime",
+ ".uno:ConvertToNumeric",
+ ".uno:ConvertToCurrency",
+ ".uno:ConvertToPattern",
+ ".uno:ConvertToImageControl",
+ ".uno:ConvertToFormatted",
+ ".uno:ConvertToScrollBar",
+ ".uno:ConvertToSpinButton"
+};
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::style;
+using namespace com::sun::star::container;
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( ControlMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_CONTROLMENUCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( ControlMenuController, {} )
+
+ControlMenuController::ControlMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::PopupMenuControllerBase( xServiceManager ),
+ m_pResPopupMenu( 0 )
+{
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ m_bShowMenuImages = rSettings.GetUseImagesInMenus();
+
+}
+
+ControlMenuController::~ControlMenuController()
+{
+}
+
+// private function
+void ControlMenuController::updateImagesPopupMenu( PopupMenu* pPopupMenu )
+{
+ ResMgr* pResMgr = ResMgr::CreateResMgr("svx");
+ ResId aResId( RID_SVXIMGLIST_FMEXPL, *pResMgr );
+ aResId.SetRT( RSC_IMAGELIST );
+
+ if ( pResMgr->IsAvailable( aResId ))
+ {
+ ImageList aImageList( aResId );
+ for ( sal_uInt32 i=0; i < SAL_N_ELEMENTS(nConvertSlots); ++i )
+ {
+ // das entsprechende Image dran
+ if ( m_bShowMenuImages )
+ pPopupMenu->SetItemImage( nConvertSlots[i], aImageList.GetImage(nCreateSlots[i]));
+ else
+ pPopupMenu->SetItemImage( nConvertSlots[i], Image() );
+ }
+ }
+
+ delete pResMgr;
+}
+
+// private function
+void ControlMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
+{
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ PopupMenu* pVCLPopupMenu = 0;
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ resetPopupMenu( rPopupMenu );
+ if ( pPopupMenu )
+ pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+
+ if ( pVCLPopupMenu && m_pResPopupMenu )
+ *pVCLPopupMenu = *m_pResPopupMenu;
+}
+
+// XEventListener
+void SAL_CALL ControlMenuController::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
+
+ osl::ResettableMutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xServiceManager.clear();
+
+ if ( m_xPopupMenu.is() )
+ m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
+ m_xPopupMenu.clear();
+ delete m_pResPopupMenu;
+}
+
+// XStatusListener
+void SAL_CALL ControlMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
+{
+ osl::ResettableMutexGuard aLock( m_aMutex );
+
+ sal_uInt16 nMenuId = 0;
+ for (sal_uInt32 i=0; i < SAL_N_ELEMENTS(aCommands); ++i)
+ {
+ if ( Event.FeatureURL.Complete.equalsAscii( aCommands[i] ))
+ {
+ nMenuId = nConvertSlots[i];
+ break;
+ }
+ }
+
+ if ( nMenuId )
+ {
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( m_xPopupMenu );
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+
+ if ( !Event.IsEnabled && pVCLPopupMenu->GetItemPos( nMenuId ) != MENU_ITEM_NOTFOUND )
+ pVCLPopupMenu->RemoveItem( pVCLPopupMenu->GetItemPos( nMenuId ));
+ else if ( Event.IsEnabled && pVCLPopupMenu->GetItemPos( nMenuId ) == MENU_ITEM_NOTFOUND )
+ {
+ sal_Int16 nSourcePos = m_pResPopupMenu->GetItemPos(nMenuId);
+ sal_Int16 nPrevInSource = nSourcePos;
+ sal_uInt16 nPrevInConversion = MENU_ITEM_NOTFOUND;
+ while (nPrevInSource>0)
+ {
+ sal_Int16 nPrevId = m_pResPopupMenu->GetItemId(--nPrevInSource);
+
+ // do we have the source's predecessor in our conversion menu, too ?
+ nPrevInConversion = pVCLPopupMenu->GetItemPos( nPrevId );
+ if ( nPrevInConversion != MENU_ITEM_NOTFOUND )
+ break;
+ }
+
+ if ( MENU_ITEM_NOTFOUND == nPrevInConversion )
+ // none of the items which precede the nSID-slot in the source menu are present in our conversion menu
+ nPrevInConversion = sal::static_int_cast< sal_uInt16 >(-1); // put the item at the first position
+
+ pVCLPopupMenu->InsertItem( nMenuId, m_pResPopupMenu->GetItemText( nMenuId ), m_pResPopupMenu->GetItemBits( nMenuId ), ++nPrevInConversion );
+ pVCLPopupMenu->SetItemImage( nMenuId, m_pResPopupMenu->GetItemImage( nMenuId ));
+ pVCLPopupMenu->SetHelpId( nMenuId, m_pResPopupMenu->GetHelpId( nMenuId ));
+ }
+ }
+}
+
+// XMenuListener
+void ControlMenuController::impl_select(const Reference< XDispatch >& /*_xDispatch*/,const ::com::sun::star::util::URL& aURL)
+{
+ UrlToDispatchMap::iterator pIter = m_aURLToDispatchMap.find( aURL.Complete );
+ if ( pIter != m_aURLToDispatchMap.end() )
+ {
+ Sequence<PropertyValue> aArgs;
+ Reference< XDispatch > xDispatch = pIter->second;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ControlMenuController"))).log(m_xServiceManager, m_xFrame, aURL, aArgs);
+ if ( xDispatch.is() )
+ xDispatch->dispatch( aURL, aArgs );
+ }
+}
+
+void SAL_CALL ControlMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException)
+{
+ osl::ResettableMutexGuard aLock( m_aMutex );
+
+ if ( m_xPopupMenu.is() )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+
+ // Check if some modes have changed so we have to update our menu images
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus();
+ sal_Bool bUpdateImages = (bShowMenuImages != m_bShowMenuImages);
+
+ if ( bUpdateImages )
+ {
+ m_bShowMenuImages = bShowMenuImages;
+
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( m_xPopupMenu );
+ if ( pPopupMenu )
+ {
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+ if ( pVCLPopupMenu && bUpdateImages )
+ updateImagesPopupMenu( pVCLPopupMenu );
+ }
+ }
+ }
+}
+
+// XPopupMenuController
+void ControlMenuController::impl_setPopupMenu()
+{
+ if ( m_pResPopupMenu == 0 )
+ {
+ ResMgr* pResMgr = ResMgr::CreateResMgr("svx");
+ if ( pResMgr )
+ {
+ ResId aResId( RID_FMSHELL_CONVERSIONMENU, *pResMgr );
+ aResId.SetRT( RSC_MENU );
+ if ( pResMgr->IsAvailable( aResId ))
+ m_pResPopupMenu = new PopupMenu( aResId );
+
+ updateImagesPopupMenu( m_pResPopupMenu );
+ delete pResMgr;
+ }
+ } // if ( m_pResPopupMenu == 0 )
+}
+
+void SAL_CALL ControlMenuController::updatePopupMenu() throw (::com::sun::star::uno::RuntimeException)
+{
+ osl::ResettableMutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ if ( m_xFrame.is() && m_xPopupMenu.is() )
+ {
+ URL aTargetURL;
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ fillPopupMenu( m_xPopupMenu );
+ m_aURLToDispatchMap.free();
+
+ for (sal_uInt32 i=0; i < SAL_N_ELEMENTS(aCommands); ++i)
+ {
+ aTargetURL.Complete = rtl::OUString::createFromAscii( aCommands[i] );
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+ if ( xDispatch.is() )
+ {
+ xDispatch->addStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
+ xDispatch->removeStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
+ m_aURLToDispatchMap.insert( UrlToDispatchMap::value_type( aTargetURL.Complete, xDispatch ));
+ }
+ }
+ }
+}
+
+// XInitialization
+void SAL_CALL ControlMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ osl::ResettableMutexGuard aLock( m_aMutex );
+ svt::PopupMenuControllerBase::initialize(aArguments);
+ m_aBaseURL = ::rtl::OUString();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/dropdownboxtoolbarcontroller.cxx b/framework/source/uielement/dropdownboxtoolbarcontroller.cxx
new file mode 100644
index 000000000000..30b5f4c3489c
--- /dev/null
+++ b/framework/source/uielement/dropdownboxtoolbarcontroller.cxx
@@ -0,0 +1,349 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "uielement/dropdownboxtoolbarcontroller.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "uielement/toolbar.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/status/ItemStatus.hpp>
+#include <com/sun/star/frame/status/ItemState.hpp>
+#include <com/sun/star/frame/status/Visibility.hpp>
+#include <com/sun/star/frame/XControlNotificationListener.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <svtools/toolboxcontroller.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <tools/urlobj.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::frame::status;
+using namespace ::com::sun::star::util;
+
+namespace framework
+{
+
+// ------------------------------------------------------------------
+
+// Wrapper class to notify controller about events from ListBox.
+// Unfortunaltly the events are notifed through virtual methods instead
+// of Listeners.
+
+class ListBoxControl : public ListBox
+{
+ public:
+ ListBoxControl( Window* pParent, WinBits nStyle, IListBoxListener* pListBoxListener );
+ virtual ~ListBoxControl();
+
+ virtual void Select();
+ virtual void DoubleClick();
+ virtual void GetFocus();
+ virtual void LoseFocus();
+ virtual long PreNotify( NotifyEvent& rNEvt );
+
+ private:
+ IListBoxListener* m_pListBoxListener;
+};
+
+ListBoxControl::ListBoxControl( Window* pParent, WinBits nStyle, IListBoxListener* pListBoxListener ) :
+ ListBox( pParent, nStyle )
+ , m_pListBoxListener( pListBoxListener )
+{
+}
+
+ListBoxControl::~ListBoxControl()
+{
+ m_pListBoxListener = 0;
+}
+
+void ListBoxControl::Select()
+{
+ ListBox::Select();
+ if ( m_pListBoxListener )
+ m_pListBoxListener->Select();
+}
+
+void ListBoxControl::DoubleClick()
+{
+ ListBox::DoubleClick();
+ if ( m_pListBoxListener )
+ m_pListBoxListener->DoubleClick();
+}
+
+void ListBoxControl::GetFocus()
+{
+ ListBox::GetFocus();
+ if ( m_pListBoxListener )
+ m_pListBoxListener->GetFocus();
+}
+
+void ListBoxControl::LoseFocus()
+{
+ ListBox::LoseFocus();
+ if ( m_pListBoxListener )
+ m_pListBoxListener->LoseFocus();
+}
+
+long ListBoxControl::PreNotify( NotifyEvent& rNEvt )
+{
+ long nRet( 0 );
+ if ( m_pListBoxListener )
+ nRet = m_pListBoxListener->PreNotify( rNEvt );
+ if ( nRet == 0 )
+ nRet = ListBox::PreNotify( rNEvt );
+
+ return nRet;
+}
+
+// ------------------------------------------------------------------
+
+DropdownToolbarController::DropdownToolbarController(
+ const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nID,
+ sal_Int32 nWidth,
+ const ::rtl::OUString& aCommand ) :
+ ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand )
+ , m_pListBoxControl( 0 )
+{
+ m_pListBoxControl = new ListBoxControl( m_pToolbar, WB_DROPDOWN|WB_AUTOHSCROLL|WB_BORDER, this );
+ if ( nWidth == 0 )
+ nWidth = 100;
+
+ // default dropdown size
+ ::Size aLogicalSize( 0, 160 );
+ ::Size aPixelSize = m_pListBoxControl->LogicToPixel( aLogicalSize, MAP_APPFONT );
+
+ m_pListBoxControl->SetSizePixel( ::Size( nWidth, aPixelSize.Height() ));
+ m_pToolbar->SetItemWindow( m_nID, m_pListBoxControl );
+ m_pListBoxControl->SetDropDownLineCount( 5 );
+}
+
+// ------------------------------------------------------------------
+
+DropdownToolbarController::~DropdownToolbarController()
+{
+}
+
+// ------------------------------------------------------------------
+
+void SAL_CALL DropdownToolbarController::dispose()
+throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ m_pToolbar->SetItemWindow( m_nID, 0 );
+ delete m_pListBoxControl;
+
+ ComplexToolbarController::dispose();
+
+ m_pListBoxControl = 0;
+}
+
+// ------------------------------------------------------------------
+Sequence<PropertyValue> DropdownToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
+{
+ Sequence<PropertyValue> aArgs( 2 );
+ ::rtl::OUString aSelectedText = m_pListBoxControl->GetSelectEntry();
+
+ // Add key modifier to argument list
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
+ aArgs[0].Value <<= KeyModifier;
+ aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
+ aArgs[1].Value <<= aSelectedText;
+ return aArgs;
+}
+
+// ------------------------------------------------------------------
+
+void DropdownToolbarController::Select()
+{
+ if ( m_pListBoxControl->GetEntryCount() > 0 )
+ {
+ Window::PointerState aState = m_pListBoxControl->GetPointerState();
+
+ sal_uInt16 nKeyModifier = sal_uInt16( aState.mnState & KEY_MODTYPE );
+ execute( nKeyModifier );
+ }
+}
+
+void DropdownToolbarController::DoubleClick()
+{
+}
+
+void DropdownToolbarController::GetFocus()
+{
+ notifyFocusGet();
+}
+
+void DropdownToolbarController::LoseFocus()
+{
+ notifyFocusLost();
+}
+
+long DropdownToolbarController::PreNotify( NotifyEvent& /*rNEvt*/ )
+{
+ return 0;
+}
+
+// --------------------------------------------------------
+
+void DropdownToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
+{
+ if ( rControlCommand.Command.equalsAsciiL( "SetList", 7 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "List", 4 ))
+ {
+ Sequence< ::rtl::OUString > aList;
+ m_pListBoxControl->Clear();
+
+ rControlCommand.Arguments[i].Value >>= aList;
+ for ( sal_Int32 j = 0; j < aList.getLength(); j++ )
+ m_pListBoxControl->InsertEntry( aList[j] );
+
+ m_pListBoxControl->SelectEntryPos( 0 );
+
+ // send notification
+ uno::Sequence< beans::NamedValue > aInfo( 1 );
+ aInfo[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ));
+ aInfo[0].Value <<= aList;
+ addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListChanged" )),
+ getDispatchFromCommand( m_aCommandURL ),
+ aInfo );
+
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "AddEntry", 8 ))
+ {
+ sal_uInt16 nPos( LISTBOX_APPEND );
+ rtl::OUString aText;
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ {
+ if ( rControlCommand.Arguments[i].Value >>= aText )
+ m_pListBoxControl->InsertEntry( aText, nPos );
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "InsertEntry", 11 ))
+ {
+ sal_uInt16 nPos( LISTBOX_APPEND );
+ rtl::OUString aText;
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
+ {
+ sal_Int32 nTmpPos = 0;
+ if ( rControlCommand.Arguments[i].Value >>= nTmpPos )
+ {
+ if (( nTmpPos >= 0 ) &&
+ ( nTmpPos < sal_Int32( m_pListBoxControl->GetEntryCount() )))
+ nPos = sal_uInt16( nTmpPos );
+ }
+ }
+ else if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ rControlCommand.Arguments[i].Value >>= aText;
+ }
+
+ m_pListBoxControl->InsertEntry( aText, nPos );
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryPos", 14 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
+ {
+ sal_Int32 nPos( -1 );
+ if ( rControlCommand.Arguments[i].Value >>= nPos )
+ {
+ if ( nPos < sal_Int32( m_pListBoxControl->GetEntryCount() ))
+ m_pListBoxControl->RemoveEntry( sal_uInt16( nPos ));
+ }
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryText", 15 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ {
+ rtl::OUString aText;
+ if ( rControlCommand.Arguments[i].Value >>= aText )
+ m_pListBoxControl->RemoveEntry( aText );
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "SetDropDownLines", 16 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Lines", 5 ))
+ {
+ sal_Int32 nValue( 5 );
+ rControlCommand.Arguments[i].Value >>= nValue;
+ m_pListBoxControl->SetDropDownLineCount( sal_uInt16( nValue ));
+ break;
+ }
+ }
+ }
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/edittoolbarcontroller.cxx b/framework/source/uielement/edittoolbarcontroller.cxx
new file mode 100644
index 000000000000..79039f8a3ce6
--- /dev/null
+++ b/framework/source/uielement/edittoolbarcontroller.cxx
@@ -0,0 +1,264 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "uielement/edittoolbarcontroller.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "uielement/toolbar.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/status/ItemStatus.hpp>
+#include <com/sun/star/frame/status/ItemState.hpp>
+#include <com/sun/star/frame/status/Visibility.hpp>
+#include <com/sun/star/frame/XControlNotificationListener.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <svtools/toolboxcontroller.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <tools/urlobj.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::frame::status;
+using namespace ::com::sun::star::util;
+
+namespace framework
+{
+
+// ------------------------------------------------------------------
+
+// Wrapper class to notify controller about events from edit.
+// Unfortunaltly the events are notifed through virtual methods instead
+// of Listeners.
+
+class EditControl : public Edit
+{
+ public:
+ EditControl( Window* pParent, WinBits nStyle, IEditListener* pEditListener );
+ virtual ~EditControl();
+
+ virtual void Modify();
+ virtual void KeyInput( const ::KeyEvent& rKEvt );
+ virtual void GetFocus();
+ virtual void LoseFocus();
+ virtual long PreNotify( NotifyEvent& rNEvt );
+
+ private:
+ IEditListener* m_pEditListener;
+};
+
+EditControl::EditControl( Window* pParent, WinBits nStyle, IEditListener* pEditListener ) :
+ Edit( pParent, nStyle )
+ , m_pEditListener( pEditListener )
+{
+}
+
+EditControl::~EditControl()
+{
+ m_pEditListener = 0;
+}
+
+void EditControl::Modify()
+{
+ Edit::Modify();
+ if ( m_pEditListener )
+ m_pEditListener->Modify();
+}
+
+void EditControl::KeyInput( const ::KeyEvent& rKEvt )
+{
+ Edit::KeyInput( rKEvt );
+ if ( m_pEditListener )
+ m_pEditListener->KeyInput( rKEvt );
+}
+
+void EditControl::GetFocus()
+{
+ Edit::GetFocus();
+ if ( m_pEditListener )
+ m_pEditListener->GetFocus();
+}
+
+void EditControl::LoseFocus()
+{
+ Edit::LoseFocus();
+ if ( m_pEditListener )
+ m_pEditListener->LoseFocus();
+}
+
+long EditControl::PreNotify( NotifyEvent& rNEvt )
+{
+ long nRet( 0 );
+ if ( m_pEditListener )
+ nRet = m_pEditListener->PreNotify( rNEvt );
+ if ( nRet == 0 )
+ nRet = Edit::PreNotify( rNEvt );
+
+ return nRet;
+}
+
+// ------------------------------------------------------------------
+
+EditToolbarController::EditToolbarController(
+ const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nID,
+ sal_Int32 nWidth,
+ const ::rtl::OUString& aCommand ) :
+ ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand )
+ , m_pEditControl( 0 )
+{
+ m_pEditControl = new EditControl( m_pToolbar, WB_BORDER, this );
+ if ( nWidth == 0 )
+ nWidth = 100;
+
+ // Calculate height of the edit field according to the application font height
+ sal_Int32 nHeight = getFontSizePixel( m_pEditControl ) + 6 + 1;
+
+ m_pEditControl->SetSizePixel( ::Size( nWidth, nHeight ));
+ m_pToolbar->SetItemWindow( m_nID, m_pEditControl );
+}
+
+// ------------------------------------------------------------------
+
+EditToolbarController::~EditToolbarController()
+{
+}
+
+// ------------------------------------------------------------------
+
+void SAL_CALL EditToolbarController::dispose()
+throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ m_pToolbar->SetItemWindow( m_nID, 0 );
+ delete m_pEditControl;
+
+ ComplexToolbarController::dispose();
+
+ m_pEditControl = 0;
+}
+
+// ------------------------------------------------------------------
+Sequence<PropertyValue> EditToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
+{
+ Sequence<PropertyValue> aArgs( 2 );
+ ::rtl::OUString aSelectedText = m_pEditControl->GetText();
+
+ // Add key modifier to argument list
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
+ aArgs[0].Value <<= KeyModifier;
+ aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
+ aArgs[1].Value <<= aSelectedText;
+ return aArgs;
+}
+
+// ------------------------------------------------------------------
+
+void EditToolbarController::Modify()
+{
+ notifyTextChanged( m_pEditControl->GetText() );
+}
+
+void EditToolbarController::KeyInput( const ::KeyEvent& /*rKEvt*/ )
+{
+}
+
+void EditToolbarController::GetFocus()
+{
+ notifyFocusGet();
+}
+
+void EditToolbarController::LoseFocus()
+{
+ notifyFocusLost();
+}
+
+long EditToolbarController::PreNotify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const ::KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ const KeyCode& rKeyCode = pKeyEvent->GetKeyCode();
+ if(( rKeyCode.GetModifier() | rKeyCode.GetCode()) == KEY_RETURN )
+ {
+ // Call execute only with non-empty text
+ if ( m_pEditControl->GetText().Len() > 0 )
+ execute( rKeyCode.GetModifier() );
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------
+
+void EditToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
+{
+ if ( rControlCommand.Command.equalsAsciiL( "SetText", 7 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ {
+ rtl::OUString aText;
+ rControlCommand.Arguments[i].Value >>= aText;
+ m_pEditControl->SetText( aText );
+
+ // send notification
+ notifyTextChanged( aText );
+ break;
+ }
+ }
+ }
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/fontmenucontroller.cxx b/framework/source/uielement/fontmenucontroller.cxx
new file mode 100644
index 000000000000..8360f60381de
--- /dev/null
+++ b/framework/source/uielement/fontmenucontroller.cxx
@@ -0,0 +1,259 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/fontmenucontroller.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/mnemonic.hxx>
+#include <dispatch/uieventloghelper.hxx>
+#include <osl/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+using namespace std;
+
+bool lcl_I18nCompareString(const rtl::OUString& rStr1, const rtl::OUString& rStr2)
+{
+ const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
+ return rI18nHelper.CompareString( rStr1, rStr2 ) < 0 ? true : false;
+}
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( FontMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_FONTMENUCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( FontMenuController, {} )
+
+FontMenuController::FontMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::PopupMenuControllerBase( xServiceManager )
+{
+}
+
+FontMenuController::~FontMenuController()
+{
+}
+
+// private function
+void FontMenuController::fillPopupMenu( const Sequence< ::rtl::OUString >& rFontNameSeq, Reference< css::awt::XPopupMenu >& rPopupMenu )
+{
+ const rtl::OUString* pFontNameArray = rFontNameSeq.getConstArray();
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ PopupMenu* pVCLPopupMenu = 0;
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ resetPopupMenu( rPopupMenu );
+ if ( pPopupMenu )
+ pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+
+ if ( pVCLPopupMenu )
+ {
+ vector<rtl::OUString> aVector;
+ aVector.reserve(rFontNameSeq.getLength());
+ for ( sal_uInt16 i = 0; i < rFontNameSeq.getLength(); i++ )
+ {
+ aVector.push_back(MnemonicGenerator::EraseAllMnemonicChars(pFontNameArray[i]));
+ }
+ sort(aVector.begin(), aVector.end(), lcl_I18nCompareString );
+
+ const rtl::OUString aFontNameCommandPrefix( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharFontName?CharFontName.FamilyName:string=" ));
+ const sal_Int16 nCount = (sal_Int16)aVector.size();
+ for ( sal_Int16 i = 0; i < nCount; i++ )
+ {
+ const rtl::OUString& rName = aVector[i];
+ m_xPopupMenu->insertItem( i+1, rName, css::awt::MenuItemStyle::RADIOCHECK | css::awt::MenuItemStyle::AUTOCHECK, i );
+ if ( rName == m_aFontFamilyName )
+ m_xPopupMenu->checkItem( i+1, sal_True );
+ // use VCL popup menu pointer to set vital information that are not part of the awt implementation
+ rtl::OUStringBuffer aCommandBuffer( aFontNameCommandPrefix );
+ aCommandBuffer.append( INetURLObject::encode( rName, INetURLObject::PART_HTTP_QUERY, '%', INetURLObject::ENCODE_ALL ));
+ rtl::OUString aFontNameCommand = aCommandBuffer.makeStringAndClear();
+ pVCLPopupMenu->SetItemCommand( i+1, aFontNameCommand ); // Store font name into item command.
+ }
+
+ }
+}
+
+// XEventListener
+void SAL_CALL FontMenuController::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
+
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xFontListDispatch.clear();
+ m_xServiceManager.clear();
+
+ if ( m_xPopupMenu.is() )
+ m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
+ m_xPopupMenu.clear();
+}
+
+// XStatusListener
+void SAL_CALL FontMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
+{
+ com::sun::star::awt::FontDescriptor aFontDescriptor;
+ Sequence< rtl::OUString > aFontNameSeq;
+
+ if ( Event.State >>= aFontDescriptor )
+ {
+ osl::MutexGuard aLock( m_aMutex );
+ m_aFontFamilyName = aFontDescriptor.Name;
+ }
+ else if ( Event.State >>= aFontNameSeq )
+ {
+ osl::MutexGuard aLock( m_aMutex );
+ if ( m_xPopupMenu.is() )
+ fillPopupMenu( aFontNameSeq, m_xPopupMenu );
+ }
+}
+
+// XMenuListener
+void FontMenuController::impl_select(const Reference< XDispatch >& _xDispatch,const ::com::sun::star::util::URL& aTargetURL)
+{
+ Sequence<PropertyValue> aArgs;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FontMenuController"))).log(
+ m_xServiceManager,
+ m_xFrame,
+ aTargetURL,
+ Sequence<PropertyValue>());
+ OSL_ENSURE(_xDispatch.is(),"FontMenuController::impl_select: No dispatch");
+ if ( _xDispatch.is() )
+ _xDispatch->dispatch( aTargetURL, aArgs );
+}
+
+void SAL_CALL FontMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException)
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ if ( m_xPopupMenu.is() )
+ {
+ // find new font name and set check mark!
+ sal_uInt16 nChecked = 0;
+ sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
+ rtl::OUString aEmpty;
+ for( sal_uInt16 i = 0; i < nItemCount; i++ )
+ {
+ sal_uInt16 nItemId = m_xPopupMenu->getItemId( i );
+
+ if ( m_xPopupMenu->isItemChecked( nItemId ) )
+ nChecked = nItemId;
+
+ rtl::OUString aText = m_xPopupMenu->getItemText( nItemId );
+
+ // TODO: must be replaced by implementation of VCL, when available
+ sal_Int32 nIndex = aText.indexOf( (sal_Unicode)'~' );
+ if ( nIndex >= 0 )
+ aText = aText.replaceAt( nIndex, 1, aEmpty );
+ // TODO: must be replaced by implementation of VCL, when available
+
+ if ( aText == m_aFontFamilyName )
+ {
+ m_xPopupMenu->checkItem( nItemId, sal_True );
+ return;
+ }
+ }
+
+ if ( nChecked )
+ m_xPopupMenu->checkItem( nChecked, sal_False );
+ }
+}
+
+// XPopupMenuController
+void FontMenuController::impl_setPopupMenu()
+{
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+
+ com::sun::star::util::URL aTargetURL;
+ // Register for font list updates to get the current font list from the controller
+ aTargetURL.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontNameList" ));
+ m_xURLTransformer->parseStrict( aTargetURL );
+ m_xFontListDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+}
+
+void SAL_CALL FontMenuController::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException )
+{
+ svt::PopupMenuControllerBase::updatePopupMenu();
+
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ Reference< XDispatch > xDispatch( m_xFontListDispatch );
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontNameList" ));
+ m_xURLTransformer->parseStrict( aTargetURL );
+ aLock.clear();
+
+ if ( xDispatch.is() )
+ {
+ xDispatch->addStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
+ xDispatch->removeStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/fontsizemenucontroller.cxx b/framework/source/uielement/fontsizemenucontroller.cxx
new file mode 100644
index 000000000000..d8b0b14eeb89
--- /dev/null
+++ b/framework/source/uielement/fontsizemenucontroller.cxx
@@ -0,0 +1,357 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/fontsizemenucontroller.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/view/XPrintable.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/menu.hxx>
+#include <tools/mapunit.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/print.hxx>
+#include <svtools/ctrltool.hxx>
+#include <dispatch/uieventloghelper.hxx>
+#include <osl/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::view;
+using namespace com::sun::star::beans;
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( FontSizeMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_FONTSIZEMENUCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( FontSizeMenuController, {} )
+
+FontSizeMenuController::FontSizeMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::PopupMenuControllerBase( xServiceManager ),
+ m_pHeightArray( 0 ),
+ m_bRebuildMenu( sal_True )
+{
+}
+
+FontSizeMenuController::~FontSizeMenuController()
+{
+ delete []m_pHeightArray;
+}
+
+// private function
+rtl::OUString FontSizeMenuController::retrievePrinterName( com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& rFrame )
+{
+ rtl::OUString aPrinterName;
+
+ if ( rFrame.is() )
+ {
+ Reference< XController > xController = m_xFrame->getController();
+ if ( xController.is() )
+ {
+ Reference< XPrintable > xPrintable( xController->getModel(), UNO_QUERY );
+ if ( xPrintable.is() )
+ {
+ Sequence< PropertyValue > aPrinterSeq = xPrintable->getPrinter();
+ for ( int i = 0; i < aPrinterSeq.getLength(); i++ )
+ {
+ if ( aPrinterSeq[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Name" ) ))
+ {
+ aPrinterSeq[i].Value >>= aPrinterName;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return aPrinterName;
+}
+
+// private function
+void FontSizeMenuController::setCurHeight( long nHeight, Reference< css::awt::XPopupMenu >& rPopupMenu )
+{
+ // check menu item
+ rtl::OUString aHeight = Application::GetSettings().GetUILocaleI18nHelper().GetNum( nHeight, 1, sal_True, sal_False );
+ sal_uInt16 nChecked = 0;
+ sal_uInt16 nItemCount = rPopupMenu->getItemCount();
+ for( sal_uInt16 i = 0; i < nItemCount; i++ )
+ {
+ sal_uInt16 nItemId = rPopupMenu->getItemId( i );
+
+ if ( m_pHeightArray[i] == nHeight )
+ {
+ rPopupMenu->checkItem( nItemId, sal_True );
+ return;
+ }
+
+ if ( rPopupMenu->isItemChecked( nItemId ) )
+ nChecked = nItemId;
+ }
+
+ if ( nChecked )
+ rPopupMenu->checkItem( nChecked, sal_False );
+}
+
+// private function
+void FontSizeMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
+{
+ const rtl::OUString aFontNameCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontHeight?FontHeight=" ));
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ PopupMenu* pVCLPopupMenu = 0;
+
+ resetPopupMenu( rPopupMenu );
+ if ( pPopupMenu )
+ pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+
+ if ( pVCLPopupMenu )
+ {
+ FontList* pFontList = 0;
+ Printer* pInfoPrinter = 0;
+ rtl::OUString aPrinterName;
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ // try to retrieve printer name of document
+ aPrinterName = retrievePrinterName( m_xFrame );
+ if ( aPrinterName.getLength() > 0 )
+ {
+ pInfoPrinter = new Printer( aPrinterName );
+ if ( pInfoPrinter && pInfoPrinter->GetDevFontCount() > 0 )
+ pFontList = new FontList( pInfoPrinter );
+ }
+
+ if ( pFontList == 0 )
+ pFontList = new FontList( Application::GetDefaultDevice() );
+
+ FontInfo aFntInfo = pFontList->Get( m_aFontDescriptor.Name, m_aFontDescriptor.StyleName );
+
+ // setup font size array
+ if ( m_pHeightArray )
+ delete m_pHeightArray;
+
+ const long* pTempAry;
+ const long* pAry = pFontList->GetSizeAry( aFntInfo );
+ sal_uInt16 nSizeCount = 0;
+ while ( pAry[nSizeCount] )
+ nSizeCount++;
+
+ sal_uInt16 nPos = 0;
+ const rtl::OUString aFontHeightCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontHeight?FontHeight.Height:float=" ));
+
+ // first insert font size names (for simplified/traditional chinese)
+ float fPoint;
+ rtl::OUString aHeightString;
+ FontSizeNames aFontSizeNames( Application::GetSettings().GetUILanguage() );
+ m_pHeightArray = new long[nSizeCount+aFontSizeNames.Count()];
+ rtl::OUString aCommand;
+
+ if ( !aFontSizeNames.IsEmpty() )
+ {
+ if ( pAry == pFontList->GetStdSizeAry() )
+ {
+ // for scalable fonts all font size names
+ sal_uLong nCount = aFontSizeNames.Count();
+ for( sal_uLong i = 0; i < nCount; i++ )
+ {
+ String aSizeName = aFontSizeNames.GetIndexName( i );
+ long nSize = aFontSizeNames.GetIndexSize( i );
+ m_pHeightArray[nPos] = nSize;
+ nPos++; // Id is nPos+1
+ pVCLPopupMenu->InsertItem( nPos, aSizeName, MIB_RADIOCHECK | MIB_AUTOCHECK );
+ fPoint = float( m_pHeightArray[nPos-1] ) / 10;
+
+ // Create dispatchable .uno command and set it
+ aCommand = aFontHeightCommand + rtl::OUString::valueOf( fPoint );
+ pVCLPopupMenu->SetItemCommand( nPos, aCommand );
+ }
+ }
+ else
+ {
+ // for fixed size fonts only selectable font size names
+ pTempAry = pAry;
+ while ( *pTempAry )
+ {
+ String aSizeName = aFontSizeNames.Size2Name( *pTempAry );
+ if ( aSizeName.Len() )
+ {
+ m_pHeightArray[nPos] = *pTempAry;
+ nPos++; // Id is nPos+1
+ pVCLPopupMenu->InsertItem( nPos, aSizeName, MIB_RADIOCHECK | MIB_AUTOCHECK );
+ fPoint = float( m_pHeightArray[nPos-1] ) / 10;
+
+ // Create dispatchable .uno command and set it
+ aCommand = aFontHeightCommand + rtl::OUString::valueOf( fPoint );
+ pVCLPopupMenu->SetItemCommand( nPos, aCommand );
+ }
+ pTempAry++;
+ }
+ }
+ }
+
+ // then insert numerical font size values
+ const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
+ pTempAry = pAry;
+ while ( *pTempAry )
+ {
+ m_pHeightArray[nPos] = *pTempAry;
+ nPos++; // Id is nPos+1
+ pVCLPopupMenu->InsertItem( nPos, rI18nHelper.GetNum( *pTempAry, 1, sal_True, sal_False ), MIB_RADIOCHECK | MIB_AUTOCHECK );
+ fPoint = float( m_pHeightArray[nPos-1] ) / 10;
+
+ // Create dispatchable .uno command and set it
+ aCommand = aFontHeightCommand + rtl::OUString::valueOf( fPoint );
+ pVCLPopupMenu->SetItemCommand( nPos, aCommand );
+
+ pTempAry++;
+ }
+
+ setCurHeight( long( m_aFontHeight.Height * 10), rPopupMenu );
+
+ delete pFontList;
+ delete pInfoPrinter;
+ }
+}
+
+// XEventListener
+void SAL_CALL FontSizeMenuController::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
+
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xCurrentFontDispatch.clear();
+ if ( m_xPopupMenu.is() )
+ m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
+ m_xPopupMenu.clear();
+}
+
+// XStatusListener
+void SAL_CALL FontSizeMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
+{
+ com::sun::star::awt::FontDescriptor aFontDescriptor;
+ ::com::sun::star::frame::status::FontHeight aFontHeight;
+
+ if ( Event.State >>= aFontDescriptor )
+ {
+ osl::MutexGuard aLock( m_aMutex );
+ m_aFontDescriptor = aFontDescriptor;
+
+ if ( m_xPopupMenu.is() )
+ fillPopupMenu( m_xPopupMenu );
+
+ }
+ else if ( Event.State >>= aFontHeight )
+ {
+ osl::MutexGuard aLock( m_aMutex );
+ m_aFontHeight = aFontHeight;
+
+ if ( m_xPopupMenu.is() )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ setCurHeight( long( m_aFontHeight.Height * 10), m_xPopupMenu );
+ }
+ }
+}
+
+// XMenuListener
+void FontSizeMenuController::impl_select(const Reference< XDispatch >& _xDispatch,const ::com::sun::star::util::URL& aTargetURL)
+{
+ Sequence<PropertyValue> aArgs;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FontSizeMenuController"))).log(m_xServiceManager, m_xFrame, aTargetURL, aArgs);
+ OSL_ENSURE(_xDispatch.is(),"FontSizeMenuController::impl_select: No dispatch");
+ if ( _xDispatch.is() )
+ _xDispatch->dispatch( aTargetURL, aArgs );
+}
+
+// XPopupMenuController
+void FontSizeMenuController::impl_setPopupMenu()
+{
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ com::sun::star::util::URL aTargetURL;
+ // Register for font name updates which gives us info about the current font!
+ aTargetURL.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharFontName" ));
+ m_xURLTransformer->parseStrict( aTargetURL );
+ m_xCurrentFontDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+}
+
+void SAL_CALL FontSizeMenuController::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException )
+{
+ osl::ClearableMutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ Reference< XDispatch > xDispatch( m_xCurrentFontDispatch );
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharFontName" ));
+ m_xURLTransformer->parseStrict( aTargetURL );
+ aLock.clear();
+
+ if ( xDispatch.is() )
+ {
+ xDispatch->addStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
+ xDispatch->removeStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
+ }
+
+ svt::PopupMenuControllerBase::updatePopupMenu();
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/footermenucontroller.cxx b/framework/source/uielement/footermenucontroller.cxx
new file mode 100644
index 000000000000..98deb29cbc11
--- /dev/null
+++ b/framework/source/uielement/footermenucontroller.cxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/footermenucontroller.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+#include <classes/resource.hrc>
+#include <classes/fwlresid.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <dispatch/uieventloghelper.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::style;
+using namespace com::sun::star::container;
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( FooterMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_FOOTERMENUCONTROLLER
+ )
+
+FooterMenuController::FooterMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ HeaderMenuController( xServiceManager,true )
+{
+}
+
+FooterMenuController::~FooterMenuController()
+{
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/generictoolbarcontroller.cxx b/framework/source/uielement/generictoolbarcontroller.cxx
new file mode 100644
index 000000000000..6270dd0c82c5
--- /dev/null
+++ b/framework/source/uielement/generictoolbarcontroller.cxx
@@ -0,0 +1,389 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "uielement/generictoolbarcontroller.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "uielement/toolbar.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/frame/status/ItemStatus.hpp>
+#include <com/sun/star/frame/status/ItemState.hpp>
+#include <com/sun/star/frame/status/Visibility.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <svtools/toolboxcontroller.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <tools/urlobj.hxx>
+#include <classes/resource.hrc>
+#include <classes/fwkresid.hxx>
+#include <dispatch/uieventloghelper.hxx>
+
+#include <framework/menuconfiguration.hxx>
+#include <uielement/menubarmanager.hxx>
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::frame::status;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::container;
+
+namespace framework
+{
+
+static sal_Bool isEnumCommand( const rtl::OUString& rCommand )
+{
+ INetURLObject aURL( rCommand );
+
+ if (( aURL.GetProtocol() == INET_PROT_UNO ) &&
+ ( aURL.GetURLPath().indexOf( '.' ) != -1))
+ return sal_True;
+
+ return sal_False;
+}
+
+static rtl::OUString getEnumCommand( const rtl::OUString& rCommand )
+{
+ INetURLObject aURL( rCommand );
+
+ rtl::OUString aEnumCommand;
+ String aURLPath = aURL.GetURLPath();
+ xub_StrLen nIndex = aURLPath.Search( '.' );
+ if (( nIndex > 0 ) && ( nIndex < aURLPath.Len() ))
+ aEnumCommand = aURLPath.Copy( nIndex+1 );
+
+ return aEnumCommand;
+}
+
+static rtl::OUString getMasterCommand( const rtl::OUString& rCommand )
+{
+ rtl::OUString aMasterCommand( rCommand );
+ INetURLObject aURL( rCommand );
+ if ( aURL.GetProtocol() == INET_PROT_UNO )
+ {
+ sal_Int32 nIndex = aURL.GetURLPath().indexOf( '.' );
+ if ( nIndex )
+ {
+ aURL.SetURLPath( aURL.GetURLPath().copy( 0, nIndex ) );
+ aMasterCommand = aURL.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ }
+ return aMasterCommand;
+}
+
+struct ExecuteInfo
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDispatch;
+ ::com::sun::star::util::URL aTargetURL;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs;
+};
+
+GenericToolbarController::GenericToolbarController( const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nID,
+ const ::rtl::OUString& aCommand ) :
+ svt::ToolboxController( rServiceManager, rFrame, aCommand )
+ , m_pToolbar( pToolbar )
+ , m_nID( nID )
+ , m_bEnumCommand( isEnumCommand( aCommand ))
+ , m_bMadeInvisible( sal_False )
+ , m_aEnumCommand( getEnumCommand( aCommand ))
+{
+ if ( m_bEnumCommand )
+ addStatusListener( getMasterCommand( aCommand ) );
+}
+
+GenericToolbarController::~GenericToolbarController()
+{
+}
+
+void SAL_CALL GenericToolbarController::dispose()
+throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ svt::ToolboxController::dispose();
+
+ m_pToolbar = 0;
+ m_nID = 0;
+}
+
+void SAL_CALL GenericToolbarController::execute( sal_Int16 KeyModifier )
+throw ( RuntimeException )
+{
+ Reference< XDispatch > xDispatch;
+ Reference< XURLTransformer > xURLTransformer;
+ ::rtl::OUString aCommandURL;
+
+ {
+ SolarMutexGuard aSolarMutexGuard;
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_bInitialized &&
+ m_xFrame.is() &&
+ m_xServiceManager.is() &&
+ m_aCommandURL.getLength() )
+ {
+ xURLTransformer = Reference< XURLTransformer >( m_xServiceManager->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
+ UNO_QUERY );
+
+ aCommandURL = m_aCommandURL;
+ URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
+ if ( pIter != m_aListenerMap.end() )
+ xDispatch = pIter->second;
+ }
+ }
+
+ if ( xDispatch.is() && xURLTransformer.is() )
+ {
+ com::sun::star::util::URL aTargetURL;
+ Sequence<PropertyValue> aArgs( 1 );
+
+ // Add key modifier to argument list
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
+ aArgs[0].Value <<= KeyModifier;
+
+ aTargetURL.Complete = aCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+
+ // Execute dispatch asynchronously
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+ pExecuteInfo->xDispatch = xDispatch;
+ pExecuteInfo->aTargetURL = aTargetURL;
+ pExecuteInfo->aArgs = aArgs;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GenericToolbarController"))).log( m_xServiceManager, m_xFrame, aTargetURL, aArgs);
+ Application::PostUserEvent( STATIC_LINK(0, GenericToolbarController , ExecuteHdl_Impl), pExecuteInfo );
+ }
+}
+
+void GenericToolbarController::statusChanged( const FeatureStateEvent& Event )
+throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ if ( m_bDisposed )
+ return;
+
+ if ( m_pToolbar )
+ {
+ m_pToolbar->EnableItem( m_nID, Event.IsEnabled );
+
+ sal_uInt16 nItemBits = m_pToolbar->GetItemBits( m_nID );
+ nItemBits &= ~TIB_CHECKABLE;
+ TriState eTri = STATE_NOCHECK;
+
+ sal_Bool bValue = sal_Bool();
+ rtl::OUString aStrValue;
+ ItemStatus aItemState;
+ Visibility aItemVisibility;
+
+ if (( Event.State >>= bValue ) && !m_bEnumCommand )
+ {
+ // Boolean, treat it as checked/unchecked
+ if ( m_bMadeInvisible )
+ m_pToolbar->ShowItem( m_nID, sal_True );
+ m_pToolbar->CheckItem( m_nID, bValue );
+ if ( bValue )
+ eTri = STATE_CHECK;
+ nItemBits |= TIB_CHECKABLE;
+ }
+ else if ( Event.State >>= aStrValue )
+ {
+ if ( m_bEnumCommand )
+ {
+ if ( aStrValue == m_aEnumCommand )
+ bValue = sal_True;
+ else
+ bValue = sal_False;
+
+ m_pToolbar->CheckItem( m_nID, bValue );
+ if ( bValue )
+ eTri = STATE_CHECK;
+ nItemBits |= TIB_CHECKABLE;
+ }
+ else
+ {
+ // Replacement for place holders
+ if ( aStrValue.matchAsciiL( "($1)", 4 ))
+ {
+ String aResStr = String( FwkResId( STR_UPDATEDOC ));
+ rtl::OUString aTmp( aResStr );
+ aTmp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
+ aTmp += aStrValue.copy( 4 );
+ aStrValue = aTmp;
+ }
+ else if ( aStrValue.matchAsciiL( "($2)", 4 ))
+ {
+ String aResStr = String( FwkResId( STR_CLOSEDOC_ANDRETURN ));
+ rtl::OUString aTmp( aResStr );
+ aTmp += aStrValue.copy( 4 );
+ aStrValue = aTmp;
+ }
+ else if ( aStrValue.matchAsciiL( "($3)", 4 ))
+ {
+ String aResStr = String( FwkResId( STR_SAVECOPYDOC ));
+ rtl::OUString aTmp( aResStr );
+ aTmp += aStrValue.copy( 4 );
+ aStrValue = aTmp;
+ }
+ ::rtl::OUString aText( MnemonicGenerator::EraseAllMnemonicChars( aStrValue ) );
+ m_pToolbar->SetItemText( m_nID, aText );
+ m_pToolbar->SetQuickHelpText( m_nID, aText );
+ }
+
+ if ( m_bMadeInvisible )
+ m_pToolbar->ShowItem( m_nID, sal_True );
+ }
+ else if (( Event.State >>= aItemState ) && !m_bEnumCommand )
+ {
+ eTri = STATE_DONTKNOW;
+ nItemBits |= TIB_CHECKABLE;
+ if ( m_bMadeInvisible )
+ m_pToolbar->ShowItem( m_nID, sal_True );
+ }
+ else if ( Event.State >>= aItemVisibility )
+ {
+ m_pToolbar->ShowItem( m_nID, aItemVisibility.bVisible );
+ m_bMadeInvisible = !aItemVisibility.bVisible;
+ }
+ else if ( m_bMadeInvisible )
+ m_pToolbar->ShowItem( m_nID, sal_True );
+
+ m_pToolbar->SetItemState( m_nID, eTri );
+ m_pToolbar->SetItemBits( m_nID, nItemBits );
+ }
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( GenericToolbarController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
+{
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+ try
+ {
+ // Asynchronous execution as this can lead to our own destruction!
+ // Framework can recycle our current frame and the layout manager disposes all user interface
+ // elements if a component gets detached from its frame!
+ pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ Application::AcquireSolarMutex( nRef );
+ delete pExecuteInfo;
+ return 0;
+}
+
+MenuToolbarController::MenuToolbarController( const Reference< XMultiServiceFactory >& rServiceManager, const Reference< XFrame >& rFrame, ToolBox* pToolBar, sal_uInt16 nID, const rtl::OUString& aCommand, const rtl::OUString& aModuleIdentifier, const Reference< XIndexAccess >& xMenuDesc ) : GenericToolbarController( rServiceManager, rFrame, pToolBar, nID, aCommand ), m_xMenuDesc( xMenuDesc ), pMenu( NULL ), m_aModuleIdentifier( aModuleIdentifier )
+{
+}
+
+MenuToolbarController::~MenuToolbarController()
+{
+ try
+ {
+ if ( m_xMenuManager.is() )
+ m_xMenuManager->dispose();
+ }
+ catch( Exception& ) {}
+ if ( pMenu )
+ {
+ delete pMenu;
+ pMenu = NULL;
+ }
+
+}
+
+class Toolbarmenu : public PopupMenu
+{
+ public:
+ Toolbarmenu();
+ ~Toolbarmenu();
+};
+
+Toolbarmenu::Toolbarmenu()
+{
+ OSL_TRACE("**** contstructing Toolbarmenu 0x%x", this );
+}
+
+Toolbarmenu::~Toolbarmenu()
+{
+ OSL_TRACE("**** destructing Toolbarmenu 0x%x", this );
+}
+
+void SAL_CALL MenuToolbarController::click() throw (RuntimeException)
+{
+ createPopupWindow();
+}
+
+Reference< XWindow > SAL_CALL
+MenuToolbarController::createPopupWindow() throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( !pMenu )
+ {
+ Reference< XDispatchProvider > xDispatch;
+ Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), UNO_QUERY );
+ pMenu = new Toolbarmenu();
+ m_xMenuManager.set( new MenuBarManager( m_xServiceManager, m_xFrame, xURLTransformer, xDispatch, m_aModuleIdentifier, pMenu, sal_True, sal_True ) );
+ if ( m_xMenuManager.is() )
+ {
+ MenuBarManager* pMgr = dynamic_cast< MenuBarManager* >( m_xMenuManager.get() );
+ pMgr->SetItemContainer( m_xMenuDesc );
+ }
+ }
+
+ ::Rectangle aRect( m_pToolbar->GetItemRect( m_nID ) );
+ pMenu->Execute( m_pToolbar, aRect, POPUPMENU_EXECUTE_DOWN );
+ return NULL;
+}
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/headermenucontroller.cxx b/framework/source/uielement/headermenucontroller.cxx
new file mode 100644
index 000000000000..2ab480d17247
--- /dev/null
+++ b/framework/source/uielement/headermenucontroller.cxx
@@ -0,0 +1,273 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/headermenucontroller.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+#include <classes/resource.hrc>
+#include <classes/fwlresid.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <dispatch/uieventloghelper.hxx>
+#include <osl/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::style;
+using namespace com::sun::star::container;
+
+// Copied from Writer module
+//#define RID_SW_SHELLRES (RID_SW_START + 1250 + 1)
+//#define STR_ALLPAGE_HEADFOOT 14
+
+const sal_uInt16 ALL_MENUITEM_ID = 1;
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( HeaderMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_HEADERMENUCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( HeaderMenuController, {} )
+
+HeaderMenuController::HeaderMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager,bool _bFooter ) :
+ svt::PopupMenuControllerBase( xServiceManager )
+ ,m_bFooter(_bFooter)
+{
+}
+
+HeaderMenuController::~HeaderMenuController()
+{
+}
+
+// private function
+void HeaderMenuController::fillPopupMenu( const Reference< ::com::sun::star::frame::XModel >& rModel, Reference< css::awt::XPopupMenu >& rPopupMenu )
+{
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ PopupMenu* pVCLPopupMenu = 0;
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ resetPopupMenu( rPopupMenu );
+ if ( pPopupMenu )
+ pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+
+ Reference< XStyleFamiliesSupplier > xStyleFamiliesSupplier( rModel, UNO_QUERY );
+ if ( pVCLPopupMenu && xStyleFamiliesSupplier.is())
+ {
+ Reference< XNameAccess > xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
+
+ rtl::OUString aCmd( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertPageHeader" ));
+ rtl::OUString aHeaderFooterIsOnStr(RTL_CONSTASCII_USTRINGPARAM( "HeaderIsOn" ));
+ if ( m_bFooter )
+ {
+ aCmd = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:InsertPageFooter" ));
+ aHeaderFooterIsOnStr = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "FooterIsOn" ));
+ }
+ const rtl::OUString aIsPhysicalStr( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ));
+ const rtl::OUString aDisplayNameStr( RTL_CONSTASCII_USTRINGPARAM( "DisplayName" ));
+
+ try
+ {
+ Reference< XNameContainer > xNameContainer;
+ if ( xStyleFamilies->getByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageStyles" ))) >>= xNameContainer )
+ {
+ Sequence< rtl::OUString > aSeqNames = xNameContainer->getElementNames();
+
+ sal_uInt16 nId = 2;
+ sal_uInt16 nCount = 0;
+ sal_Bool bAllOneState( sal_True );
+ sal_Bool bLastCheck( sal_True );
+ sal_Bool bFirstChecked( sal_False );
+ sal_Bool bFirstItemInserted( sal_False );
+ for ( sal_Int32 n = 0; n < aSeqNames.getLength(); n++ )
+ {
+ rtl::OUString aName = aSeqNames[n];
+ Reference< XPropertySet > xPropSet( xNameContainer->getByName( aName ), UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ sal_Bool bIsPhysical( sal_False );
+ if (( xPropSet->getPropertyValue( aIsPhysicalStr ) >>= bIsPhysical ) && bIsPhysical )
+ {
+ rtl::OUString aDisplayName;
+ sal_Bool bHeaderIsOn( sal_False );
+ xPropSet->getPropertyValue( aDisplayNameStr ) >>= aDisplayName;
+ xPropSet->getPropertyValue( aHeaderFooterIsOnStr ) >>= bHeaderIsOn;
+
+ rtl::OUStringBuffer aStrBuf( aCmd );
+ aStrBuf.appendAscii( "?PageStyle:string=");
+ aStrBuf.append( aDisplayName );
+ aStrBuf.appendAscii( "&On:bool=" );
+ if ( !bHeaderIsOn )
+ aStrBuf.appendAscii( "true" );
+ else
+ aStrBuf.appendAscii( "false" );
+ rtl::OUString aCommand( aStrBuf.makeStringAndClear() );
+ pVCLPopupMenu->InsertItem( nId, aDisplayName, MIB_CHECKABLE );
+ if ( !bFirstItemInserted )
+ {
+ bFirstItemInserted = sal_True;
+ bFirstChecked = bHeaderIsOn;
+ }
+
+ pVCLPopupMenu->SetItemCommand( nId, aCommand );
+
+ if ( bHeaderIsOn )
+ pVCLPopupMenu->CheckItem( nId, sal_True );
+ ++nId;
+
+ // Check if all entries have the same state
+ if( bAllOneState && n && bHeaderIsOn != bLastCheck )
+ bAllOneState = sal_False;
+ bLastCheck = bHeaderIsOn;
+ ++nCount;
+ }
+ }
+ }
+
+ if ( bAllOneState && ( nCount > 1 ))
+ {
+ // Insert special item for all command
+ pVCLPopupMenu->InsertItem( ALL_MENUITEM_ID, String( FwlResId( STR_MENU_HEADFOOTALL )), 0, 0 );
+
+ rtl::OUStringBuffer aStrBuf( aCmd );
+ aStrBuf.appendAscii( "?On:bool=" );
+
+ // Command depends on check state of first menu item entry
+ if ( !bFirstChecked )
+ aStrBuf.appendAscii( "true" );
+ else
+ aStrBuf.appendAscii( "false" );
+
+ pVCLPopupMenu->SetItemCommand( 1, aStrBuf.makeStringAndClear() );
+ pVCLPopupMenu->InsertSeparator( 1 );
+ }
+ }
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ }
+}
+
+// XEventListener
+void SAL_CALL HeaderMenuController::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
+
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xServiceManager.clear();
+
+ if ( m_xPopupMenu.is() )
+ m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
+ m_xPopupMenu.clear();
+}
+
+// XStatusListener
+void SAL_CALL HeaderMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
+{
+ Reference< com::sun::star::frame::XModel > xModel;
+
+ if ( Event.State >>= xModel )
+ {
+ osl::MutexGuard aLock( m_aMutex );
+ m_xModel = xModel;
+ if ( m_xPopupMenu.is() )
+ fillPopupMenu( xModel, m_xPopupMenu );
+ }
+}
+
+// XMenuListener
+void HeaderMenuController::impl_select(const Reference< XDispatch >& _xDispatch,const ::com::sun::star::util::URL& aTargetURL)
+{
+ Sequence<PropertyValue> aArgs;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(m_bFooter ? "FooterMenuController" : "HeaderMenuController"))).log(m_xServiceManager, m_xFrame, aTargetURL, aArgs);
+ OSL_ENSURE(_xDispatch.is(),"HeaderMenuController::impl_select: No dispatch");
+ if ( _xDispatch.is() )
+ _xDispatch->dispatch( aTargetURL, aArgs );
+}
+
+void SAL_CALL HeaderMenuController::updatePopupMenu() throw (::com::sun::star::uno::RuntimeException)
+{
+ osl::ResettableMutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ Reference< com::sun::star::frame::XModel > xModel( m_xModel );
+ aLock.clear();
+
+ if ( !xModel.is() )
+ svt::PopupMenuControllerBase::updatePopupMenu();
+
+ aLock.reset();
+ if ( m_xPopupMenu.is() && m_xModel.is() )
+ fillPopupMenu( m_xModel, m_xPopupMenu );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/imagebuttontoolbarcontroller.cxx b/framework/source/uielement/imagebuttontoolbarcontroller.cxx
new file mode 100644
index 000000000000..16d4317c2932
--- /dev/null
+++ b/framework/source/uielement/imagebuttontoolbarcontroller.cxx
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "uielement/imagebuttontoolbarcontroller.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <framework/addonsoptions.hxx>
+#include "uielement/toolbar.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/XControlNotificationListener.hpp>
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <rtl/uri.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vcl/window.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/bitmap.hxx>
+#include <svtools/filter.hxx>
+#include <svtools/miscopt.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::util;
+
+#define EXPAND_PROTOCOL "vnd.sun.star.expand:"
+
+const ::Size aImageSizeSmall( 16, 16 );
+const ::Size aImageSizeBig( 26, 26 );
+
+namespace framework
+{
+
+static uno::WeakReference< util::XMacroExpander > m_xMacroExpander;
+
+// ------------------------------------------------------------------
+
+uno::Reference< util::XMacroExpander > GetMacroExpander()
+{
+ uno::Reference< util::XMacroExpander > xMacroExpander( m_xMacroExpander );
+ if ( !xMacroExpander.is() )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+
+ if ( !xMacroExpander.is() )
+ {
+ uno::Reference< uno::XComponentContext > xContext;
+ uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
+ if ( xContext.is() )
+ {
+ m_xMacroExpander = Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))),
+ UNO_QUERY );
+ xMacroExpander = m_xMacroExpander;
+ }
+ }
+ }
+
+ return xMacroExpander;
+}
+
+static void SubstituteVariables( ::rtl::OUString& aURL )
+{
+ if ( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 )
+ {
+ uno::Reference< util::XMacroExpander > xMacroExpander = GetMacroExpander();
+
+ // cut protocol
+ rtl::OUString aMacro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
+ // decode uric class chars
+ aMacro = ::rtl::Uri::decode( aMacro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ // expand macro string
+ aURL = xMacroExpander->expandMacros( aMacro );
+ }
+}
+
+// ------------------------------------------------------------------
+
+ImageButtonToolbarController::ImageButtonToolbarController(
+ const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nID,
+ const ::rtl::OUString& aCommand ) :
+ ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand )
+{
+ sal_Bool bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() );
+
+ Image aImage = AddonsOptions().GetImageFromURL( aCommand, bBigImages, sal_True );
+
+ // Height will be controlled by scaling according to button height
+ m_pToolbar->SetItemImage( m_nID, aImage );
+}
+
+// ------------------------------------------------------------------
+
+ImageButtonToolbarController::~ImageButtonToolbarController()
+{
+}
+
+// ------------------------------------------------------------------
+
+void SAL_CALL ImageButtonToolbarController::dispose()
+throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+ ComplexToolbarController::dispose();
+}
+
+// ------------------------------------------------------------------
+
+void ImageButtonToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
+{
+ SolarMutexGuard aSolarMutexGuard;
+ // i73486 to be downward compatible use old and "wrong" also!
+ if (( rControlCommand.Command.equalsAsciiL( "SetImag", 7 )) ||
+ ( rControlCommand.Command.equalsAsciiL( "SetImage", 8 )) )
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "URL", 3 ))
+ {
+ rtl::OUString aURL;
+ rControlCommand.Arguments[i].Value >>= aURL;
+
+ SubstituteVariables( aURL );
+
+ Image aImage;
+ if ( ReadImageFromURL( SvtMiscOptions().AreCurrentSymbolsLarge(),
+ aURL,
+ aImage ))
+ {
+ m_pToolbar->SetItemImage( m_nID, aImage );
+
+ // send notification
+ uno::Sequence< beans::NamedValue > aInfo( 1 );
+ aInfo[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ));
+ aInfo[0].Value <<= aURL;
+ addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ImageChanged" )),
+ getDispatchFromCommand( m_aCommandURL ),
+ aInfo );
+ break;
+ }
+ }
+ }
+ }
+}
+
+sal_Bool ImageButtonToolbarController::ReadImageFromURL( sal_Bool bBigImage, const ::rtl::OUString& aImageURL, Image& aImage )
+{
+ SvStream* pStream = utl::UcbStreamHelper::CreateStream( aImageURL, STREAM_STD_READ );
+ if ( pStream && ( pStream->GetErrorCode() == 0 ))
+ {
+ // Use graphic class to also support more graphic formats (bmp,png,...)
+ Graphic aGraphic;
+
+ GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
+ pGF->ImportGraphic( aGraphic, String(), *pStream, GRFILTER_FORMAT_DONTKNOW );
+
+ BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
+
+ const ::Size aSize = bBigImage ? aImageSizeBig : aImageSizeSmall; // Sizes used for toolbar images
+
+ ::Size aBmpSize = aBitmapEx.GetSizePixel();
+ if ( aBmpSize.Width() > 0 && aBmpSize.Height() > 0 )
+ {
+ ::Size aNoScaleSize( aBmpSize.Width(), aSize.Height() );
+ if ( aBmpSize != aNoScaleSize )
+ aBitmapEx.Scale( aNoScaleSize, BMP_SCALE_INTERPOLATE );
+ aImage = Image( aBitmapEx );
+ return sal_True;
+ }
+ }
+
+ delete pStream;
+ return sal_False;
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/langselectionmenucontroller.cxx b/framework/source/uielement/langselectionmenucontroller.cxx
new file mode 100644
index 000000000000..d81aec95030e
--- /dev/null
+++ b/framework/source/uielement/langselectionmenucontroller.cxx
@@ -0,0 +1,371 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <uielement/langselectionmenucontroller.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/mnemonic.hxx>
+#include <com/sun/star/awt/XMenuExtended.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/document/XDocumentLanguages.hpp>
+#include <com/sun/star/frame/XPopupMenuController.hpp>
+#include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
+
+#include <i18npool/mslangid.hxx>
+#include <svl/languageoptions.hxx>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <svtools/langtab.hxx>
+#include <classes/fwlresid.hxx>
+
+#include <classes/resource.hrc>
+#include <dispatch/uieventloghelper.hxx>
+
+#include "helper/mischelper.hxx"
+#include <osl/mutex.hxx>
+
+#include <map>
+#include <set>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+using namespace ::com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+using ::rtl::OUString;
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( LanguageSelectionMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_LANGUAGESELECTIONMENUCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( LanguageSelectionMenuController, {} )
+
+LanguageSelectionMenuController::LanguageSelectionMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::PopupMenuControllerBase( xServiceManager ),
+ m_bShowMenu( sal_True ),
+ m_aLangGuessHelper( xServiceManager )
+{
+}
+
+LanguageSelectionMenuController::~LanguageSelectionMenuController()
+{
+}
+
+// XEventListener
+void SAL_CALL LanguageSelectionMenuController::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
+
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xLanguageDispatch.clear();
+ m_xServiceManager.clear();
+
+ if ( m_xPopupMenu.is() )
+ m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
+ m_xPopupMenu.clear();
+}
+
+// XStatusListener
+void SAL_CALL LanguageSelectionMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ return;
+
+ m_bShowMenu = sal_True;
+ m_nScriptType = LS_SCRIPT_LATIN | LS_SCRIPT_ASIAN | LS_SCRIPT_COMPLEX; //set the default value
+
+ OUString aStrValue;
+ Sequence< OUString > aSeq;
+
+ if ( Event.State >>= aSeq )
+ {
+ if ( aSeq.getLength() == 4 )
+ {
+ // Retrieve all other values from the sequence and
+ // store it members!
+ m_aCurLang = aSeq[0];
+ m_nScriptType = static_cast< sal_Int16 >(aSeq[1].toInt32());
+ m_aKeyboardLang = aSeq[2];
+ m_aGuessedTextLang = aSeq[3];
+ }
+ }
+ else if ( !Event.State.hasValue() )
+ {
+ m_bShowMenu = sal_False; // no language -> no sub-menu entries -> disable menu
+ }
+}
+
+// XMenuListener
+void LanguageSelectionMenuController::impl_select(const Reference< XDispatch >& _xDispatch,const ::com::sun::star::util::URL& aTargetURL)
+{
+ Reference< XDispatch > xDispatch = _xDispatch;
+
+ if ( aTargetURL.Complete == m_aMenuCommandURL_Font )
+ { //open format/character dialog for current selection
+ xDispatch = m_xMenuDispatch_Font;
+ }
+ else if ( aTargetURL.Complete == m_aMenuCommandURL_Lang )
+ { //open language tab-page in tools/options dialog
+ xDispatch = m_xMenuDispatch_Lang;
+ }
+ else if ( aTargetURL.Complete == m_aMenuCommandURL_CharDlgForParagraph )
+ { //open format/character dialog for current selection
+ xDispatch = m_xMenuDispatch_CharDlgForParagraph;
+ }
+
+ if ( !xDispatch.is() )
+ {
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( xDispatchProvider.is() )
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
+ }
+
+ if ( xDispatch.is() )
+ {
+ Sequence<PropertyValue> aArgs;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper( OUString(RTL_CONSTASCII_USTRINGPARAM("LanguageSelectionMenuController"))).log( m_xServiceManager, m_xFrame, aTargetURL, aArgs );
+ xDispatch->dispatch( aTargetURL, aArgs );
+ }
+}
+
+// XPopupMenuController
+void LanguageSelectionMenuController::impl_setPopupMenu()
+{
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+
+ com::sun::star::util::URL aTargetURL;
+
+ // Register for language updates
+ aTargetURL.Complete = m_aLangStatusCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ m_xLanguageDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
+
+ // Register for setting languages and opening language dialog
+ aTargetURL.Complete = m_aMenuCommandURL_Lang;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ m_xMenuDispatch_Lang = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
+
+ // Register for opening character dialog
+ aTargetURL.Complete = m_aMenuCommandURL_Font;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ m_xMenuDispatch_Font = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
+
+ // Register for opening character dialog with preselected paragraph
+ aTargetURL.Complete = m_aMenuCommandURL_CharDlgForParagraph;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ m_xMenuDispatch_CharDlgForParagraph = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
+}
+
+void LanguageSelectionMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu , const Mode eMode )
+{
+ VCLXPopupMenu* pVCLPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ PopupMenu* pPopupMenu = 0;
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ resetPopupMenu( rPopupMenu );
+ if (!m_bShowMenu)
+ return;
+
+ if ( pVCLPopupMenu )
+ pPopupMenu = (PopupMenu *)pVCLPopupMenu->GetMenu();
+
+ String aCmd;
+ String aCmd_Dialog;
+ String aCmd_Language;
+ if( eMode == MODE_SetLanguageSelectionMenu )
+ {
+ aCmd_Dialog.AppendAscii(".uno:FontDialog?Language:string=*");
+ aCmd_Language.AppendAscii(".uno:LanguageStatus?Language:string=Current_");
+ }
+ else if ( eMode == MODE_SetLanguageParagraphMenu )
+ {
+ aCmd_Dialog.AppendAscii(".uno:FontDialogForParagraph");
+ aCmd_Language.AppendAscii(".uno:LanguageStatus?Language:string=Paragraph_");
+ }
+ else if ( eMode == MODE_SetLanguageAllTextMenu )
+ {
+ aCmd_Dialog.AppendAscii(".uno:LanguageStatus?Language:string=*");
+ aCmd_Language.AppendAscii(".uno:LanguageStatus?Language:string=Default_");
+ }
+
+ SvtLanguageTable aLanguageTable;
+
+ // get languages to be displayed in the menu
+ std::set< OUString > aLangItems;
+ FillLangItems( aLangItems, aLanguageTable, m_xFrame, m_aLangGuessHelper,
+ m_nScriptType, m_aCurLang, m_aKeyboardLang, m_aGuessedTextLang );
+
+ // now add menu entries
+ // the different menues purpose will be handled by the different string
+ // for aCmd_Dialog and aCmd_Language
+
+ sal_Int16 nItemId = 1; // in this control the item id is not important for executing the command
+ const OUString sAsterix(RTL_CONSTASCII_USTRINGPARAM("*")); // multiple languages in current selection
+ const OUString sEmpty; // 'no language found' from language guessing
+ std::map< sal_Int16, OUString > aLangMap;
+ std::set< OUString >::const_iterator it;
+ for (it = aLangItems.begin(); it != aLangItems.end(); ++it)
+ {
+ const OUString & rStr( *it );
+ if (rStr != OUString( aLanguageTable.GetString( LANGUAGE_NONE ) )&&
+ rStr != sAsterix &&
+ rStr != sEmpty)
+ {
+ pPopupMenu->InsertItem( nItemId, rStr );
+ aCmd = aCmd_Language;
+ aCmd += String( rStr );
+ pPopupMenu->SetItemCommand( nItemId, aCmd );
+ if (rStr == m_aCurLang && eMode == MODE_SetLanguageSelectionMenu )
+ {
+ //make a sign for the current language
+ pPopupMenu->CheckItem( nItemId, sal_True );
+ }
+ aLangMap[ nItemId ] = rStr;
+ ++nItemId;
+ }
+ }
+
+ // entry for LANGUAGE_NONE
+ ++nItemId;
+ pPopupMenu->InsertItem( nItemId, String(FwlResId( STR_LANGSTATUS_NONE )) );
+ aCmd=aCmd_Language;
+ aCmd.AppendAscii("LANGUAGE_NONE");
+ pPopupMenu->SetItemCommand( nItemId, aCmd );
+
+ // entry for 'Reset to default language'
+ ++nItemId;
+ pPopupMenu->InsertItem( nItemId, String(FwlResId( STR_RESET_TO_DEFAULT_LANGUAGE )) );
+ aCmd=aCmd_Language;
+ aCmd.AppendAscii("RESET_LANGUAGES");
+ pPopupMenu->SetItemCommand( nItemId, aCmd );
+
+ // entry for opening the Format/Character dialog
+ ++nItemId;
+ pPopupMenu->InsertItem( nItemId, String(FwlResId( STR_LANGSTATUS_MORE )));
+ pPopupMenu->SetItemCommand( nItemId, aCmd_Dialog );
+}
+
+
+void SAL_CALL LanguageSelectionMenuController::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException )
+{
+ svt::PopupMenuControllerBase::updatePopupMenu();
+
+ // Force status update to get information about the current languages
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ Reference< XDispatch > xDispatch( m_xLanguageDispatch );
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = m_aLangStatusCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ aLock.clear();
+
+ if ( xDispatch.is() )
+ {
+ xDispatch->addStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
+ xDispatch->removeStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
+ }
+
+ // TODO: Fill menu with the information retrieved by the status update
+
+ if( m_aCommandURL.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ".uno:SetLanguageSelectionMenu" ) ))
+ {
+ fillPopupMenu(m_xPopupMenu, MODE_SetLanguageSelectionMenu );
+ }
+ else if( m_aCommandURL.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ".uno:SetLanguageParagraphMenu" ) ))
+ {
+ fillPopupMenu(m_xPopupMenu, MODE_SetLanguageParagraphMenu );
+ }
+ else if( m_aCommandURL.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ".uno:SetLanguageAllTextMenu" ) ))
+ {
+ fillPopupMenu(m_xPopupMenu, MODE_SetLanguageAllTextMenu );
+ }
+}
+
+// XInitialization
+void SAL_CALL LanguageSelectionMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ sal_Bool bInitalized( m_bInitialized );
+ if ( !bInitalized )
+ {
+ svt::PopupMenuControllerBase::initialize(aArguments);
+
+ if ( m_bInitialized )
+ {
+ m_aLangStatusCommandURL = OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:LanguageStatus" ));
+ m_aMenuCommandURL_Lang = m_aLangStatusCommandURL;
+ m_aMenuCommandURL_Font = OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontDialog" ));
+ m_aMenuCommandURL_CharDlgForParagraph = OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontDialogForParagraph" ));
+ }
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/langselectionstatusbarcontroller.cxx b/framework/source/uielement/langselectionstatusbarcontroller.cxx
new file mode 100644
index 000000000000..88096ca36ed8
--- /dev/null
+++ b/framework/source/uielement/langselectionstatusbarcontroller.cxx
@@ -0,0 +1,429 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <uielement/langselectionstatusbarcontroller.hxx>
+#include <classes/fwkresid.hxx>
+#include <services.h>
+#include <classes/resource.hrc>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/status.hxx>
+#include <toolkit/unohlp.hxx>
+#include <toolkit/helper/convert.hxx>
+
+#include <com/sun/star/frame/XPopupMenuController.hpp>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <com/sun/star/awt/PopupMenuDirection.hpp>
+#include <svtools/langtab.hxx>
+#include "sal/types.h"
+#include <vcl/svapp.hxx>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/document/XDocumentLanguages.hpp>
+#include <i18npool/mslangid.hxx>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/frame/XModule.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+#include <classes/fwkresid.hxx>
+#include <classes/resource.hrc>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include <toolkit/unohlp.hxx>
+#include <tools/gen.hxx>
+#include <com/sun/star/awt/Command.hpp>
+#include <svl/languageoptions.hxx>
+#include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
+#include <dispatch/uieventloghelper.hxx>
+
+#include "helper/mischelper.hxx"
+
+#include <map>
+#include <set>
+
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::i18n;
+using namespace ::com::sun::star::document;
+
+using ::rtl::OUString;
+
+
+namespace framework
+{
+
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( LangSelectionStatusbarController ,
+ OWeakObject ,
+ SERVICENAME_STATUSBARCONTROLLER ,
+ IMPLEMENTATIONNAME_LANGSELECTIONSTATUSBARCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( LangSelectionStatusbarController, {} )
+
+LangSelectionStatusbarController::LangSelectionStatusbarController( const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::StatusbarController( xServiceManager, uno::Reference< frame::XFrame >(), OUString(), 0 ),
+ m_bShowMenu( sal_True ),
+ m_nScriptType( LS_SCRIPT_LATIN | LS_SCRIPT_ASIAN | LS_SCRIPT_COMPLEX ),
+ m_aLangGuessHelper( xServiceManager )
+{
+}
+
+// XInterface
+Any SAL_CALL LangSelectionStatusbarController::queryInterface( const Type& rType )
+throw ( RuntimeException )
+{
+ return svt::StatusbarController::queryInterface( rType );
+}
+
+void SAL_CALL LangSelectionStatusbarController::acquire() throw ()
+{
+ svt::StatusbarController::acquire();
+}
+
+void SAL_CALL LangSelectionStatusbarController::release() throw ()
+{
+ svt::StatusbarController::release();
+}
+
+void SAL_CALL LangSelectionStatusbarController::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::initialize" );
+ SolarMutexGuard aSolarMutexGuard;
+
+ svt::StatusbarController::initialize( aArguments );
+
+ if ( m_xParentWindow.is() && m_nID > 0 )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( m_xParentWindow );
+ if ( pWindow && ( pWindow->GetType() == WINDOW_STATUSBAR ))
+ {
+ StatusBar* pStatusBar = (StatusBar *)pWindow;
+ pStatusBar->SetItemText( m_nID, FwkResId( STR_LANGSTATUS_MULTIPLE_LANGUAGES ) );
+ }
+ }
+}
+
+// XComponent
+void SAL_CALL LangSelectionStatusbarController::dispose()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::dispose" );
+ svt::StatusbarController::dispose();
+}
+
+// XEventListener
+void SAL_CALL LangSelectionStatusbarController::disposing( const com::sun::star::lang::EventObject& Source )
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::disposing" );
+ svt::StatusbarController::disposing( Source );
+}
+
+// XStatusbarController
+::sal_Bool SAL_CALL LangSelectionStatusbarController::mouseButtonDown(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::mouseButtonDown" );
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL LangSelectionStatusbarController::mouseMove(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::mouseMove" );
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL LangSelectionStatusbarController::mouseButtonUp(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::mouseButtonUp" );
+ return sal_False;
+}
+
+void LangSelectionStatusbarController::LangMenu()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::LangMenu" );
+ if (!m_bShowMenu)
+ return;
+
+ //add context menu
+ const static OUString s_sPopupMenu(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.PopupMenu"));
+ Reference< awt::XPopupMenu > xPopupMenu( m_xServiceManager->createInstance( s_sPopupMenu ), UNO_QUERY );
+ //sub menu that contains all items except the last two items: Separator + Set Language for Paragraph
+ Reference< awt::XPopupMenu > subPopupMenu(m_xServiceManager->createInstance( s_sPopupMenu ), UNO_QUERY );
+
+ SvtLanguageTable aLanguageTable;
+
+ // get languages to be displayed in the menu
+ std::set< OUString > aLangItems;
+ FillLangItems( aLangItems, aLanguageTable, m_xFrame, m_aLangGuessHelper,
+ m_nScriptType, m_aCurLang, m_aKeyboardLang, m_aGuessedTextLang );
+
+ // add first few entries to main menu
+ sal_Int16 nItemId = static_cast< sal_Int16 >(MID_LANG_SEL_1);
+ const OUString sAsterix(RTL_CONSTASCII_USTRINGPARAM("*")); // multiple languages in current selection
+ const OUString sEmpty; // 'no language found' from language guessing
+ std::map< sal_Int16, OUString > aLangMap;
+ std::set< OUString >::const_iterator it;
+ for (it = aLangItems.begin(); it != aLangItems.end(); ++it)
+ {
+ const OUString & rStr( *it );
+ if ( rStr != OUString( aLanguageTable.GetString( LANGUAGE_NONE ) ) &&
+ rStr != sAsterix &&
+ rStr != sEmpty)
+ {
+ DBG_ASSERT( MID_LANG_SEL_1 <= nItemId && nItemId <= MID_LANG_SEL_9,
+ "nItemId outside of expected range!" );
+ xPopupMenu->insertItem( nItemId, rStr, css::awt::MenuItemStyle::RADIOCHECK, nItemId );
+ if ( rStr == m_aCurLang )
+ {
+ //make a sign for the current language
+ xPopupMenu->checkItem( nItemId, sal_True );
+ }
+ aLangMap[ nItemId ] = rStr;
+ ++nItemId;
+ }
+ }
+ xPopupMenu->insertItem( MID_LANG_SEL_NONE, String( FwkResId( STR_LANGSTATUS_NONE )), css::awt::MenuItemStyle::RADIOCHECK, MID_LANG_SEL_NONE );
+ xPopupMenu->insertItem( MID_LANG_SEL_RESET, String( FwkResId( STR_RESET_TO_DEFAULT_LANGUAGE )), css::awt::MenuItemStyle::RADIOCHECK, MID_LANG_SEL_RESET );
+ xPopupMenu->insertItem( MID_LANG_SEL_MORE, String( FwkResId( STR_LANGSTATUS_MORE )), css::awt::MenuItemStyle::RADIOCHECK, MID_LANG_SEL_MORE );
+
+ // add entries to submenu ('set language for paragraph')
+ nItemId = static_cast< sal_Int16 >(MID_LANG_PARA_1);
+ for (it = aLangItems.begin(); it != aLangItems.end(); ++it)
+ {
+ const OUString & rStr( *it );
+ if( rStr != OUString( aLanguageTable.GetString( LANGUAGE_NONE ) )&&
+ rStr != sAsterix &&
+ rStr != sEmpty)
+ {
+ DBG_ASSERT( MID_LANG_PARA_1 <= nItemId && nItemId <= MID_LANG_PARA_9,
+ "nItemId outside of expected range!" );
+ subPopupMenu->insertItem( nItemId, rStr, css::awt::MenuItemStyle::RADIOCHECK, nItemId );
+ aLangMap[nItemId] = rStr;
+ ++nItemId;
+ }
+ }
+ subPopupMenu->insertItem( MID_LANG_PARA_NONE, String( FwkResId( STR_LANGSTATUS_NONE )), css::awt::MenuItemStyle::RADIOCHECK, MID_LANG_PARA_NONE );
+ subPopupMenu->insertItem( MID_LANG_PARA_RESET, String( FwkResId( STR_RESET_TO_DEFAULT_LANGUAGE )), css::awt::MenuItemStyle::RADIOCHECK, MID_LANG_PARA_RESET );
+ subPopupMenu->insertItem( MID_LANG_PARA_MORE, String( FwkResId( STR_LANGSTATUS_MORE )), css::awt::MenuItemStyle::RADIOCHECK, MID_LANG_PARA_MORE );
+
+ // add last two entries to main menu
+ xPopupMenu->insertSeparator( MID_LANG_PARA_SEPERATOR );
+ xPopupMenu->insertItem( MID_LANG_PARA_STRING, String( FwkResId( STR_SET_LANGUAGE_FOR_PARAGRAPH )), css::awt::MenuItemStyle::RADIOCHECK, MID_LANG_PARA_STRING );
+ xPopupMenu->setPopupMenu( MID_LANG_PARA_STRING, subPopupMenu );
+
+
+ // now display the popup menu and execute every command ...
+
+ Reference< awt::XWindowPeer > xParent( m_xParentWindow, UNO_QUERY );
+
+ com::sun::star::awt::Rectangle aRectangle;
+ Window* pWindow = VCLUnoHelper::GetWindow( m_xParentWindow );
+ const Point mMousePos = pWindow->GetPointerPosPixel();
+ aRectangle.X = mMousePos.X();
+ aRectangle.Y = mMousePos.Y();
+ sal_Int16 nId = xPopupMenu->execute( xParent, aRectangle, com::sun::star::awt::PopupMenuDirection::EXECUTE_UP+16 );
+ //click "More..."
+ if ( nId && m_xFrame.is() )
+ {
+ uno::Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ util::URL aURL;
+
+ if (MID_LANG_SEL_1 <= nId && nId <= MID_LANG_SEL_9)
+ {
+ //set selected language as current language for selection
+ String aSelectedLang = aLangMap[nId];
+ aURL.Complete += OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:LanguageStatus?Language:string=Current_"));
+ aURL.Complete += aSelectedLang;
+ }
+ else if (nId == MID_LANG_SEL_NONE)
+ {
+ //set None as current language for selection
+ aURL.Complete += OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:LanguageStatus?Language:string=Current_LANGUAGE_NONE"));
+ }
+ else if (nId == MID_LANG_SEL_RESET)
+ {
+ // reset language attributes for selection
+ aURL.Complete += OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:LanguageStatus?Language:string=Current_RESET_LANGUAGES"));
+ }
+ else if (nId == MID_LANG_SEL_MORE)
+ {
+ //open the dialog "format/character" for current selection
+ aURL.Complete += OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FontDialog?Language:string=*"));
+ }
+ else if (MID_LANG_PARA_1 <= nId && nId <= MID_LANG_PARA_9)
+ {
+ //set selected language for current paragraph
+ String aSelectedLang = aLangMap[nId];
+ aURL.Complete += OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:LanguageStatus?Language:string=Paragraph_"));
+ aURL.Complete += aSelectedLang;
+ }
+ else if (nId == MID_LANG_PARA_NONE)
+ {
+ //set None as language for current paragraph
+ aURL.Complete += OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:LanguageStatus?Language:string=Paragraph_LANGUAGE_NONE"));
+ }
+ else if (nId == MID_LANG_PARA_RESET)
+ {
+ // reset language attributes for paragraph
+ aURL.Complete += OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:LanguageStatus?Language:string=Paragraph_RESET_LANGUAGES"));
+ }
+ else if (nId == MID_LANG_PARA_MORE)
+ {
+ //open the dialog "format/character" for current paragraph
+ aURL.Complete += OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FontDialogForParagraph"));
+ }
+
+ uno::Reference< util::XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), uno::UNO_QUERY );
+ xURLTransformer->parseStrict( aURL );
+ uno::Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch(aURL, OUString(), 0);
+ if( xDispatch.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aPV;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper( OUString(RTL_CONSTASCII_USTRINGPARAM("ButtonToolbarController"))).log(m_xServiceManager, m_xFrame, aURL, aPV);
+ xDispatch->dispatch( aURL, aPV);
+ }
+ }
+}
+
+void SAL_CALL LangSelectionStatusbarController::command(
+ const ::com::sun::star::awt::Point& /*aPos*/,
+ ::sal_Int32 nCommand,
+ ::sal_Bool /*bMouseEvent*/,
+ const ::com::sun::star::uno::Any& /*aData*/ )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::command" );
+ if ( nCommand & ::awt::Command::CONTEXTMENU )
+ {
+ LangMenu();
+ }
+}
+
+void SAL_CALL LangSelectionStatusbarController::paint(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >& xGraphics,
+ const ::com::sun::star::awt::Rectangle& rOutputRectangle,
+ ::sal_Int32 nItemId,
+ ::sal_Int32 nStyle )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::paint" );
+ svt::StatusbarController::paint( xGraphics, rOutputRectangle, nItemId, nStyle );
+}
+
+void SAL_CALL LangSelectionStatusbarController::click()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::click" );
+ LangMenu();
+}
+
+void SAL_CALL LangSelectionStatusbarController::doubleClick()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::doubleClick" );
+ svt::StatusbarController::doubleClick();
+}
+
+// XStatusListener
+void SAL_CALL LangSelectionStatusbarController::statusChanged( const FeatureStateEvent& Event )
+throw ( RuntimeException )
+{
+ // This function will be called when observed data changes,
+ // for example the selection or keyboard language.
+ // - It displays the language in use in the status bar
+ // - and it stores the relevant data for creating the menu
+ // at some later point in the member variables
+ // m_nScriptType, m_aCurLang, m_aKeyboardLang, m_aGuessedText
+
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "LangSelectionStatusbarController::statusChanged" );
+ SolarMutexGuard aSolarMutexGuard;
+
+ if ( m_bDisposed )
+ return;
+
+ m_bShowMenu = sal_True;
+
+ m_nScriptType = LS_SCRIPT_LATIN | LS_SCRIPT_ASIAN | LS_SCRIPT_COMPLEX; //set the default value
+ Window* pWindow = VCLUnoHelper::GetWindow( m_xParentWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR && m_nID != 0 )
+ {
+ OUString aStrValue;
+ Sequence< OUString > aSeq;
+
+ StatusBar* pStatusBar = (StatusBar *)pWindow;
+ if ( Event.State >>= aStrValue )
+ pStatusBar->SetItemText( m_nID, aStrValue );
+ else if ( Event.State >>= aSeq )
+ {
+ if ( aSeq.getLength() == 4 )
+ {
+ const String aMultipleLangText( FwkResId( STR_LANGSTATUS_MULTIPLE_LANGUAGES ) );
+ OUString aStatusText = aSeq[0];
+ if ( 0 == aStatusText.compareToAscii( "*" ))
+ aStatusText = aMultipleLangText;
+ pStatusBar->SetItemText( m_nID, aStatusText );
+
+ // Retrieve all other values from the sequence and
+ // store it members!
+ m_aCurLang = aSeq[0];
+ m_nScriptType = static_cast< sal_Int16 >( aSeq[1].toInt32() );
+ m_aKeyboardLang = aSeq[2];
+ m_aGuessedTextLang = aSeq[3];
+ }
+ }
+ else if ( !Event.State.hasValue() )
+ {
+ pStatusBar->SetItemText( m_nID, String() );
+ m_bShowMenu = sal_False; // no language -> no menu
+ }
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/logoimagestatusbarcontroller.cxx b/framework/source/uielement/logoimagestatusbarcontroller.cxx
new file mode 100644
index 000000000000..6b20e717c457
--- /dev/null
+++ b/framework/source/uielement/logoimagestatusbarcontroller.cxx
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/logoimagestatusbarcontroller.hxx>
+#include <classes/fwlresid.hxx>
+#include <services.h>
+#include <classes/resource.hrc>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/status.hxx>
+#include <toolkit/unohlp.hxx>
+#include <toolkit/helper/convert.hxx>
+
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( LogoImageStatusbarController ,
+ OWeakObject ,
+ SERVICENAME_STATUSBARCONTROLLER ,
+ IMPLEMENTATIONNAME_LOGOIMAGESTATUSBARCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( LogoImageStatusbarController, {} )
+
+LogoImageStatusbarController::LogoImageStatusbarController( const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::StatusbarController( xServiceManager, uno::Reference< frame::XFrame >(), rtl::OUString(), 0 )
+{
+ Image aImage( FwlResId( RID_IMAGE_STATUSBAR_LOGO ));
+ m_aLogoImage = aImage;
+}
+
+LogoImageStatusbarController::~LogoImageStatusbarController()
+{
+}
+
+// XInterface
+Any SAL_CALL LogoImageStatusbarController::queryInterface( const Type& rType )
+throw ( RuntimeException )
+{
+ return svt::StatusbarController::queryInterface( rType );
+}
+
+void SAL_CALL LogoImageStatusbarController::acquire() throw ()
+{
+ svt::StatusbarController::acquire();
+}
+
+void SAL_CALL LogoImageStatusbarController::release() throw ()
+{
+ svt::StatusbarController::release();
+}
+
+void SAL_CALL LogoImageStatusbarController::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ svt::StatusbarController::initialize( aArguments );
+}
+
+// XComponent
+void SAL_CALL LogoImageStatusbarController::dispose()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::dispose();
+}
+
+// XEventListener
+void SAL_CALL LogoImageStatusbarController::disposing( const EventObject& Source )
+throw ( RuntimeException )
+{
+ svt::StatusbarController::disposing( Source );
+}
+
+// XStatusListener
+void SAL_CALL LogoImageStatusbarController::statusChanged( const FeatureStateEvent& )
+throw ( RuntimeException )
+{
+}
+
+// XStatusbarController
+::sal_Bool SAL_CALL LogoImageStatusbarController::mouseButtonDown(
+ const awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL LogoImageStatusbarController::mouseMove(
+ const awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL LogoImageStatusbarController::mouseButtonUp(
+ const awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+void SAL_CALL LogoImageStatusbarController::command(
+ const awt::Point& aPos,
+ ::sal_Int32 nCommand,
+ ::sal_Bool bMouseEvent,
+ const ::com::sun::star::uno::Any& aData )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::command( aPos, nCommand, bMouseEvent, aData );
+}
+
+void SAL_CALL LogoImageStatusbarController::paint(
+ const ::com::sun::star::uno::Reference< awt::XGraphics >& xGraphics,
+ const awt::Rectangle& rOutputRectangle,
+ ::sal_Int32 /*nItemId*/,
+ ::sal_Int32 /*nStyle*/ )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( xGraphics );;
+ if ( pOutDev )
+ {
+ ::Rectangle aRect = VCLRectangle( rOutputRectangle );
+ pOutDev->DrawImage( aRect.TopLeft(), aRect.GetSize(), m_aLogoImage );
+ }
+}
+
+void SAL_CALL LogoImageStatusbarController::click()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::click();
+}
+
+void SAL_CALL LogoImageStatusbarController::doubleClick() throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::doubleClick();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/logotextstatusbarcontroller.cxx b/framework/source/uielement/logotextstatusbarcontroller.cxx
new file mode 100644
index 000000000000..f332c458a6e7
--- /dev/null
+++ b/framework/source/uielement/logotextstatusbarcontroller.cxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/logotextstatusbarcontroller.hxx>
+#include <classes/fwlresid.hxx>
+#include <services.h>
+#include <classes/resource.hrc>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/status.hxx>
+#include <toolkit/unohlp.hxx>
+#include <toolkit/helper/convert.hxx>
+
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( LogoTextStatusbarController ,
+ OWeakObject ,
+ SERVICENAME_STATUSBARCONTROLLER ,
+ IMPLEMENTATIONNAME_LOGOTEXTSTATUSBARCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( LogoTextStatusbarController, {} )
+
+LogoTextStatusbarController::LogoTextStatusbarController( const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::StatusbarController( xServiceManager, uno::Reference< frame::XFrame >(), rtl::OUString(), 0 )
+{
+ m_aLogoText = String( FwlResId( STR_STATUSBAR_LOGOTEXT ));
+}
+
+LogoTextStatusbarController::~LogoTextStatusbarController()
+{
+}
+
+// XInterface
+Any SAL_CALL LogoTextStatusbarController::queryInterface( const Type& rType )
+throw ( RuntimeException )
+{
+ return svt::StatusbarController::queryInterface( rType );
+}
+
+void SAL_CALL LogoTextStatusbarController::acquire() throw ()
+{
+ svt::StatusbarController::acquire();
+}
+
+void SAL_CALL LogoTextStatusbarController::release() throw ()
+{
+ svt::StatusbarController::release();
+}
+
+void SAL_CALL LogoTextStatusbarController::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ svt::StatusbarController::initialize( aArguments );
+
+ if ( m_xParentWindow.is() && m_nID > 0 )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( m_xParentWindow );
+ if ( pWindow && ( pWindow->GetType() == WINDOW_STATUSBAR ))
+ {
+ StatusBar* pStatusBar = (StatusBar *)pWindow;
+ pStatusBar->SetItemText( m_nID, m_aLogoText );
+ }
+ }
+}
+
+// XComponent
+void SAL_CALL LogoTextStatusbarController::dispose()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::dispose();
+}
+
+// XEventListener
+void SAL_CALL LogoTextStatusbarController::disposing( const EventObject& Source )
+throw ( RuntimeException )
+{
+ svt::StatusbarController::disposing( Source );
+}
+
+// XStatusListener
+void SAL_CALL LogoTextStatusbarController::statusChanged( const FeatureStateEvent& )
+throw ( RuntimeException )
+{
+}
+
+// XStatusbarController
+::sal_Bool SAL_CALL LogoTextStatusbarController::mouseButtonDown(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL LogoTextStatusbarController::mouseMove(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL LogoTextStatusbarController::mouseButtonUp(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+void SAL_CALL LogoTextStatusbarController::command(
+ const ::com::sun::star::awt::Point& aPos,
+ ::sal_Int32 nCommand,
+ ::sal_Bool bMouseEvent,
+ const ::com::sun::star::uno::Any& aData )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::command( aPos, nCommand, bMouseEvent, aData );
+}
+
+void SAL_CALL LogoTextStatusbarController::paint(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >& xGraphics,
+ const ::com::sun::star::awt::Rectangle& rOutputRectangle,
+ ::sal_Int32 nItemId,
+ ::sal_Int32 nStyle )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::paint( xGraphics, rOutputRectangle, nItemId, nStyle );
+}
+
+void SAL_CALL LogoTextStatusbarController::click()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::click();
+}
+
+void SAL_CALL LogoTextStatusbarController::doubleClick() throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::doubleClick();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/macrosmenucontroller.cxx b/framework/source/uielement/macrosmenucontroller.cxx
new file mode 100644
index 000000000000..b51070830d12
--- /dev/null
+++ b/framework/source/uielement/macrosmenucontroller.cxx
@@ -0,0 +1,228 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <uielement/macrosmenucontroller.hxx>
+#include <uielement/menubarmanager.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+#include <classes/resource.hrc>
+#include <classes/fwkresid.hxx>
+#include <framework/imageproducer.hxx>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <comphelper/processfactory.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <dispatch/uieventloghelper.hxx>
+#include "helper/mischelper.hxx"
+#include "helpid.hrc"
+#include <osl/mutex.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::style;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::frame;
+
+namespace framework
+{
+class
+DEFINE_XSERVICEINFO_MULTISERVICE ( MacrosMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_MACROSMENUCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( MacrosMenuController, {} )
+
+MacrosMenuController::MacrosMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::PopupMenuControllerBase( xServiceManager ),
+ m_xServiceManager( xServiceManager)
+{
+}
+
+MacrosMenuController::~MacrosMenuController()
+{
+ OSL_TRACE("calling dtor");
+}
+
+// private function
+void MacrosMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
+{
+ VCLXPopupMenu* pVCLPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ PopupMenu* pPopupMenu = 0;
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ resetPopupMenu( rPopupMenu );
+ if ( pVCLPopupMenu )
+ pPopupMenu = (PopupMenu *)pVCLPopupMenu->GetMenu();
+
+ if (!pPopupMenu)
+ return;
+
+ // insert basic
+ String aCommand = String::CreateFromAscii( ".uno:MacroDialog" );
+ String aDisplayName = RetrieveLabelFromCommand( aCommand );
+ pPopupMenu->InsertItem( 2, aDisplayName );
+ pPopupMenu->SetItemCommand( 2, aCommand );
+
+ // insert providers but not basic or java
+ addScriptItems( pPopupMenu, 4);
+}
+
+// XEventListener
+void SAL_CALL MacrosMenuController::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
+
+ osl::MutexGuard aLock( m_aMutex );
+ OSL_TRACE("disposing");
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xServiceManager.clear();
+
+ if ( m_xPopupMenu.is() )
+ {
+ m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
+ OSL_TRACE("removed listener");
+ }
+ m_xPopupMenu.clear();
+}
+
+// XStatusListener
+void SAL_CALL MacrosMenuController::statusChanged( const FeatureStateEvent& ) throw ( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+ if ( m_xPopupMenu.is() )
+ {
+ fillPopupMenu( m_xPopupMenu );
+ }
+}
+
+// XMenuListener
+void MacrosMenuController::impl_select(const Reference< XDispatch >& /*_xDispatch*/,const ::com::sun::star::util::URL& aTargetURL)
+{
+ // need to requery, since we handle more than one type of Command
+ // if we don't do this only .uno:ScriptOrganizer commands are executed
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+ if( xDispatch.is() )
+ {
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+ pExecuteInfo->xDispatch = xDispatch;
+ pExecuteInfo->aTargetURL = aTargetURL;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MacrosMenuController"))).log(m_xServiceManager, m_xFrame, aTargetURL, pExecuteInfo->aArgs);
+ Application::PostUserEvent( STATIC_LINK(0, MacrosMenuController , ExecuteHdl_Impl), pExecuteInfo );
+ }
+}
+
+
+IMPL_STATIC_LINK_NOINSTANCE( MacrosMenuController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
+{
+ try
+ {
+ // Asynchronous execution as this can lead to our own destruction!
+ // Framework can recycle our current frame and the layout manager disposes all user interface
+ // elements if a component gets detached from its frame!
+ pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
+ }
+ catch ( Exception& )
+ {
+ }
+ delete pExecuteInfo;
+ return 0;
+}
+
+String MacrosMenuController::RetrieveLabelFromCommand( const String& aCmdURL )
+{
+ sal_Bool bModuleIdentified = m_aModuleIdentifier.getLength() != 0;
+ return framework::RetrieveLabelFromCommand(aCmdURL,m_xServiceManager,m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,bModuleIdentified,"Label");
+}
+
+void MacrosMenuController::addScriptItems( PopupMenu* pPopupMenu, sal_uInt16 startItemId )
+{
+ const String aCmdBase = String::CreateFromAscii( ".uno:ScriptOrganizer?ScriptOrganizer.Language:string=" );
+ const String ellipsis = String::CreateFromAscii( "..." );
+ const ::rtl::OUString providerKey(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.provider.ScriptProviderFor"));
+ const ::rtl::OUString languageProviderName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.provider.LanguageScriptProvider"));
+ sal_uInt16 itemId = startItemId;
+ Reference< XContentEnumerationAccess > xEnumAccess = Reference< XContentEnumerationAccess >( m_xServiceManager, UNO_QUERY_THROW );
+ Reference< XEnumeration > xEnum = xEnumAccess->createContentEnumeration ( languageProviderName );
+
+ while ( xEnum->hasMoreElements() )
+ {
+ Reference< XServiceInfo > xServiceInfo;
+ if ( sal_False == ( xEnum->nextElement() >>= xServiceInfo ) )
+ {
+ break;
+ }
+ Sequence< ::rtl::OUString > serviceNames = xServiceInfo->getSupportedServiceNames();
+
+ if ( serviceNames.getLength() > 0 )
+ {
+ for ( sal_Int32 index = 0; index < serviceNames.getLength(); index++ )
+ {
+ if ( serviceNames[ index ].indexOf( providerKey ) == 0 )
+ {
+ ::rtl::OUString serviceName = serviceNames[ index ];
+ String aCommand = aCmdBase;
+ String aDisplayName = String( serviceName.copy( providerKey.getLength() ) );
+ if( aDisplayName.Equals( String::CreateFromAscii( "Java" ) ) || aDisplayName.Equals( String::CreateFromAscii( "Basic" ) ) )
+ {
+ // no entries for Java & Basic added elsewhere
+ break;
+ }
+ aCommand.Append( aDisplayName );
+ aDisplayName.Append( ellipsis );
+ pPopupMenu->InsertItem( itemId, aDisplayName );
+ pPopupMenu->SetItemCommand( itemId, aCommand );
+ itemId++;
+ break;
+ }
+ }
+ }
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx
new file mode 100644
index 000000000000..4c9a190e3221
--- /dev/null
+++ b/framework/source/uielement/menubarmanager.cxx
@@ -0,0 +1,2118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uielement/menubarmanager.hxx>
+#include <framework/menuconfiguration.hxx>
+#include <framework/bmkmenu.hxx>
+#include <framework/addonmenu.hxx>
+#include <framework/imageproducer.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include "framework/addonsoptions.hxx"
+#include <classes/fwkresid.hxx>
+#include <classes/menumanager.hxx>
+#include <framework/acceleratorinfo.hxx>
+#include <helper/mischelper.hxx>
+#include <framework/menuextensionsupplier.hxx>
+#include <classes/resource.hrc>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/util/XStringWidth.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/frame/XPopupMenuController.hpp>
+#include <com/sun/star/frame/XUIControllerRegistration.hpp>
+#include <com/sun/star/lang/SystemDependent.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/ItemStyle.hpp>
+#include <com/sun/star/frame/status/Visibility.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <comphelper/processfactory.hxx>
+#include <comphelper/extract.hxx>
+#include <svtools/menuoptions.hxx>
+#include <unotools/historyoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/cmdoptions.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <toolkit/unohlp.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/file.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <svtools/acceleratorexecute.hxx>
+#include <rtl/logfile.hxx>
+#include "svtools/miscopt.hxx"
+#include <framework/addonmenu.hxx>
+#include <uielement/menubarmerger.hxx>
+#include <dispatch/uieventloghelper.hxx>
+
+// Be careful removing this "bad" construct. There are serious problems
+// with #define STRICT and including windows.h. Changing this needs some
+// redesign on other projects, too. Especially sal/main.h which defines
+// HINSTANCE depending on STRCIT!!!!!!!!!!!!!!!
+struct SystemMenuData
+{
+ unsigned long nSize;
+ long hMenu;
+};
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::ui;
+
+static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
+static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL";
+static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer";
+static const char ITEM_DESCRIPTOR_LABEL[] = "Label";
+static const char ITEM_DESCRIPTOR_TYPE[] = "Type";
+static const char ITEM_DESCRIPTOR_MODULEIDENTIFIER[] = "ModuleIdentifier";
+static const char ITEM_DESCRIPTOR_DISPATCHPROVIDER[] = "DispatchProvider";
+static const char ITEM_DESCRIPTOR_STYLE[] = "Style";
+
+const sal_Int32 LEN_DESCRIPTOR_COMMANDURL = 10;
+const sal_Int32 LEN_DESCRIPTOR_HELPURL = 7;
+const sal_Int32 LEN_DESCRIPTOR_CONTAINER = 23;
+const sal_Int32 LEN_DESCRIPTOR_LABEL = 5;
+const sal_Int32 LEN_DESCRIPTOR_TYPE = 4;
+const sal_Int32 LEN_DESCRIPTOR_MODULEIDENTIFIER = 16;
+const sal_Int32 LEN_DESCRIPTOR_DISPATCHPROVIDER = 16;
+static const sal_Int32 ITEM_DESCRIPTOR_STYLE_LEN = 5;
+
+const sal_uInt16 ADDONMENU_MERGE_ITEMID_START = 1500;
+
+class StringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
+{
+ public:
+ StringLength() {}
+ virtual ~StringLength() {}
+
+ // XStringWidth
+ sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
+ throw (RuntimeException)
+ {
+ return aString.getLength();
+ }
+};
+
+namespace framework
+{
+
+// special menu ids/command ids for dynamic popup menus
+#define SID_SFX_START 5000
+#define SID_NEWDOCDIRECT (SID_SFX_START + 537)
+#define SID_AUTOPILOTMENU (SID_SFX_START + 1381)
+#define SID_PICKLIST (SID_SFX_START + 510)
+#define SID_MDIWINDOWLIST (SID_SFX_START + 610)
+#define SID_ADDONLIST (SID_SFX_START + 1677)
+#define SID_HELPMENU (SID_SFX_START + 410)
+
+#define SFX_REFERER_USER "private:user"
+
+#define aCmdHelpIndex ".uno:HelpIndex"
+#define aCmdToolsMenu ".uno:ToolsMenu"
+#define aCmdHelpMenu ".uno:HelpMenu"
+#define aSlotHelpMenu "slot:5410"
+
+#define aSpecialWindowMenu "window"
+#define aSlotSpecialWindowMenu "slot:5610"
+#define aSlotSpecialToolsMenu "slot:6677"
+
+// special uno commands for window list
+#define aSpecialWindowCommand ".uno:WindowList"
+
+static sal_Int16 getImageTypeFromBools( sal_Bool bBig )
+{
+ sal_Int16 n( 0 );
+ if ( bBig )
+ n |= ::com::sun::star::ui::ImageType::SIZE_LARGE;
+ return n;
+}
+
+MenuBarManager::MenuBarManager(
+ const Reference< XMultiServiceFactory >& xServiceFactory,
+ const Reference< XFrame >& rFrame,
+ const Reference< XURLTransformer >& _xURLTransformer,
+ const Reference< XDispatchProvider >& rDispatchProvider,
+ const rtl::OUString& rModuleIdentifier,
+ Menu* pMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
+: ThreadHelpBase( &Application::GetSolarMutex() ), OWeakObject()
+ , m_bDisposed( sal_False )
+ , m_bRetrieveImages( sal_False )
+ , m_bAcceleratorCfg( sal_False )
+ , m_bModuleIdentified( sal_False )
+ , m_aListenerContainer( m_aLock.getShareableOslMutex() )
+ , mxServiceFactory(xServiceFactory)
+ , m_xURLTransformer(_xURLTransformer)
+ , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" );
+ m_xPopupMenuControllerRegistration = Reference< ::com::sun::star::frame::XUIControllerRegistration >(
+ getServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.PopupMenuControllerFactory" ))),
+ UNO_QUERY );
+ FillMenuManager( pMenu, rFrame, rDispatchProvider, rModuleIdentifier, bDelete, bDeleteChildren );
+}
+
+MenuBarManager::MenuBarManager(
+ const Reference< XMultiServiceFactory >& xServiceFactory,
+ const Reference< XFrame >& rFrame,
+ const Reference< XURLTransformer >& _xURLTransformer,
+ AddonMenu* pAddonMenu,
+ sal_Bool bDelete,
+ sal_Bool bDeleteChildren )
+: ThreadHelpBase( &Application::GetSolarMutex() )
+ , OWeakObject()
+ , m_bDisposed( sal_False )
+ , m_bRetrieveImages( sal_True )
+ , m_bAcceleratorCfg( sal_False )
+ , m_bModuleIdentified( sal_False )
+ , m_aListenerContainer( m_aLock.getShareableOslMutex() )
+ , mxServiceFactory(xServiceFactory)
+ , m_xURLTransformer(_xURLTransformer)
+ , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" );
+ Init(rFrame,pAddonMenu,bDelete,bDeleteChildren);
+}
+
+MenuBarManager::MenuBarManager(
+ const Reference< XMultiServiceFactory >& xServiceFactory,
+ const Reference< XFrame >& rFrame,
+ const Reference< XURLTransformer >& _xURLTransformer,
+ AddonPopupMenu* pAddonPopupMenu,
+ sal_Bool bDelete,
+ sal_Bool bDeleteChildren )
+: ThreadHelpBase( &Application::GetSolarMutex() )
+ , OWeakObject()
+ , m_bDisposed( sal_False )
+ , m_bRetrieveImages( sal_True )
+ , m_bAcceleratorCfg( sal_False )
+ , m_bModuleIdentified( sal_False )
+ , m_aListenerContainer( m_aLock.getShareableOslMutex() )
+ , mxServiceFactory(xServiceFactory)
+ , m_xURLTransformer(_xURLTransformer)
+ , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" );
+ Init(rFrame,pAddonPopupMenu,bDelete,bDeleteChildren,true);
+}
+
+Any SAL_CALL MenuBarManager::queryInterface( const Type & rType ) throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ rType ,
+ SAL_STATIC_CAST( ::com::sun::star::frame::XStatusListener*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::frame::XFrameActionListener*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::ui::XUIConfigurationListener*, this ),
+ SAL_STATIC_CAST( XEventListener*, (XStatusListener *)this ),
+ SAL_STATIC_CAST( XComponent*, this ),
+ SAL_STATIC_CAST( ::com::sun::star::awt::XSystemDependentMenuPeer*, this ));
+
+ if ( a.hasValue() )
+ return a;
+
+ return OWeakObject::queryInterface( rType );
+}
+
+
+void SAL_CALL MenuBarManager::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+
+void SAL_CALL MenuBarManager::release() throw()
+{
+ OWeakObject::release();
+}
+
+
+Any SAL_CALL MenuBarManager::getMenuHandle( const Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 SystemType ) throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::getMenuHandle" );
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw com::sun::star::lang::DisposedException();
+
+ Any a;
+
+ if ( m_pVCLMenu )
+ {
+ SolarMutexGuard aSolarGuard;
+
+ SystemMenuData aSystemMenuData;
+ aSystemMenuData.nSize = sizeof( SystemMenuData );
+
+ m_pVCLMenu->GetSystemMenuData( &aSystemMenuData );
+#ifdef QUARTZ
+ if( SystemType == SystemDependent::SYSTEM_MAC )
+ {
+ }
+#elif (defined WNT)
+ if( SystemType == SystemDependent::SYSTEM_WIN32 )
+ {
+ a <<= (long) aSystemMenuData.hMenu;
+ }
+#elif (defined UNX)
+ if( SystemType == SystemDependent::SYSTEM_XWINDOW )
+ {
+ }
+#endif
+ }
+
+ return a;
+}
+
+MenuBarManager::~MenuBarManager()
+{
+ // stop asynchronous settings timer
+ m_xDeferedItemContainer.clear();
+ m_aAsyncSettingsTimer.Stop();
+
+ DBG_ASSERT( OWeakObject::m_refCount == 0, "Who wants to delete an object with refcount > 0!" );
+}
+
+void MenuBarManager::Destroy()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Destroy" );
+ SolarMutexGuard aGuard;
+
+ if ( !m_bDisposed )
+ {
+ // stop asynchronous settings timer and
+ // release defered item container reference
+ m_aAsyncSettingsTimer.Stop();
+ m_xDeferedItemContainer.clear();
+ RemoveListener();
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ pItemHandler->xMenuItemDispatch.clear();
+ pItemHandler->xSubMenuManager.clear();
+ pItemHandler->xPopupMenu.clear();
+ delete pItemHandler;
+ }
+ m_aMenuItemHandlerVector.clear();
+
+ if ( m_bDeleteMenu )
+ {
+ delete m_pVCLMenu;
+ m_pVCLMenu = 0;
+ }
+ }
+}
+
+// XComponent
+void SAL_CALL MenuBarManager::dispose() throw( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::dispose" );
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ {
+ ResetableGuard aGuard( m_aLock );
+ Destroy();
+ m_bDisposed = sal_True;
+
+ if ( m_xDocImageManager.is() )
+ {
+ try
+ {
+ m_xDocImageManager->removeConfigurationListener(
+ Reference< XUIConfigurationListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ if ( m_xModuleImageManager.is() )
+ {
+ try
+ {
+ m_xModuleImageManager->removeConfigurationListener(
+ Reference< XUIConfigurationListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ m_xDocImageManager.clear();
+ m_xModuleImageManager.clear();
+ m_xGlobalAcceleratorManager.clear();
+ m_xModuleAcceleratorManager.clear();
+ m_xDocAcceleratorManager.clear();
+ m_xUICommandLabels.clear();
+ m_xPopupMenuControllerRegistration.clear();
+ mxServiceFactory.clear();
+ }
+}
+
+void SAL_CALL MenuBarManager::addEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::addEventListener" );
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL MenuBarManager::removeEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::removeEventListener" );
+ ResetableGuard aGuard( m_aLock );
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL MenuBarManager::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event )
+throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementInserted" );
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ return;
+
+ sal_Int16 nImageType = sal_Int16();
+ sal_Int16 nCurrentImageType = getImageTypeFromBools( sal_False );
+ if (( Event.aInfo >>= nImageType ) &&
+ ( nImageType == nCurrentImageType ))
+ RequestImages();
+}
+
+void SAL_CALL MenuBarManager::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event )
+throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementRemoved" );
+ elementInserted(Event);
+}
+
+void SAL_CALL MenuBarManager::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event )
+throw (RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementReplaced" );
+ elementInserted(Event);
+}
+
+// XFrameActionListener
+void SAL_CALL MenuBarManager::frameAction( const FrameActionEvent& Action )
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::frameAction" );
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ throw com::sun::star::lang::DisposedException();
+
+ if ( Action.Action == FrameAction_CONTEXT_CHANGED )
+ {
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ // Clear dispatch reference as we will requery it later o
+ MenuItemHandler* pItemHandler = *p;
+ pItemHandler->xMenuItemDispatch.clear();
+ }
+ }
+}
+
+// XStatusListener
+void SAL_CALL MenuBarManager::statusChanged( const FeatureStateEvent& Event )
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::statusChanged" );
+ ::rtl::OUString aFeatureURL = Event.FeatureURL.Complete;
+
+ SolarMutexGuard aSolarGuard;
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ // We have to check all menu entries as there can be identical entries in a popup menu.
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+ if ( pMenuItemHandler->aMenuItemURL == aFeatureURL )
+ {
+ sal_Bool bCheckmark( sal_False );
+ sal_Bool bMenuItemEnabled( m_pVCLMenu->IsItemEnabled( pMenuItemHandler->nItemId ));
+ sal_Bool bEnabledItem( Event.IsEnabled );
+ rtl::OUString aItemText;
+ status::Visibility aVisibilityStatus;
+
+ #ifdef UNIX
+ //enable some slots hardly, because UNIX clipboard does not notify all changes
+ // Can be removed if follow up task will be fixed directly within applications.
+ if (
+ ( pMenuItemHandler->aMenuItemURL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".uno:Paste"))) ||
+ ( pMenuItemHandler->aMenuItemURL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".uno:PasteSpecial"))) ||
+ ( pMenuItemHandler->aMenuItemURL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".uno:PasteClipboard"))) // special for draw/impress
+ )
+ bEnabledItem = sal_True;
+ #endif
+
+ // Enable/disable item
+ if ( bEnabledItem != bMenuItemEnabled )
+ m_pVCLMenu->EnableItem( pMenuItemHandler->nItemId, bEnabledItem );
+
+ if ( Event.State >>= bCheckmark )
+ {
+ // Checkmark or RadioButton
+ m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True );
+ m_pVCLMenu->CheckItem( pMenuItemHandler->nItemId, bCheckmark );
+
+ MenuItemBits nBits = m_pVCLMenu->GetItemBits( pMenuItemHandler->nItemId );
+ //If not already designated RadioButton set as CheckMark
+ if (!(nBits & MIB_RADIOCHECK))
+ m_pVCLMenu->SetItemBits( pMenuItemHandler->nItemId, nBits | MIB_CHECKABLE );
+ }
+ else if ( Event.State >>= aItemText )
+ {
+ // Replacement for place holders
+ if ( aItemText.matchAsciiL( "($1)", 4 ))
+ {
+ String aResStr = String( FwkResId( STR_UPDATEDOC ));
+ rtl::OUString aTmp( aResStr );
+ aTmp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
+ aTmp += aItemText.copy( 4 );
+ aItemText = aTmp;
+ }
+ else if ( aItemText.matchAsciiL( "($2)", 4 ))
+ {
+ String aResStr = String( FwkResId( STR_CLOSEDOC_ANDRETURN ));
+ rtl::OUString aTmp( aResStr );
+ aTmp += aItemText.copy( 4 );
+ aItemText = aTmp;
+ }
+ else if ( aItemText.matchAsciiL( "($3)", 4 ))
+ {
+ String aResStr = String( FwkResId( STR_SAVECOPYDOC ));
+ rtl::OUString aTmp( aResStr );
+ aTmp += aItemText.copy( 4 );
+ aItemText = aTmp;
+ }
+
+ m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True );
+ m_pVCLMenu->SetItemText( pMenuItemHandler->nItemId, aItemText );
+ }
+ else if ( Event.State >>= aVisibilityStatus )
+ {
+ // Visibility
+ m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, aVisibilityStatus.bVisible );
+ }
+ else
+ m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True );
+ }
+
+ if ( Event.Requery )
+ {
+ // Release dispatch object - will be requeried on the next activate!
+ pMenuItemHandler->xMenuItemDispatch.clear();
+ }
+ }
+ }
+}
+
+// Helper to retrieve own structure from item ID
+MenuBarManager::MenuItemHandler* MenuBarManager::GetMenuItemHandler( sal_uInt16 nItemId )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::GetMenuItemHandler" );
+ ResetableGuard aGuard( m_aLock );
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ if ( pItemHandler->nItemId == nItemId )
+ return pItemHandler;
+ }
+
+ return 0;
+}
+
+// Helper to set request images flag
+void MenuBarManager::RequestImages()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RequestImages" );
+
+ m_bRetrieveImages = sal_True;
+ const sal_uInt32 nCount = m_aMenuItemHandlerVector.size();
+ for ( sal_uInt32 i = 0; i < nCount; ++i )
+ {
+ MenuItemHandler* pItemHandler = m_aMenuItemHandlerVector[i];
+ if ( pItemHandler->xSubMenuManager.is() )
+ {
+ MenuBarManager* pMenuBarManager = (MenuBarManager*)(pItemHandler->xSubMenuManager.get());
+ pMenuBarManager->RequestImages();
+ }
+ }
+}
+
+// Helper to reset objects to prepare shutdown
+void MenuBarManager::RemoveListener()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RemoveListener" );
+ ResetableGuard aGuard( m_aLock );
+
+ // Check service manager reference. Remove listener can be called due
+ // to a disposing call from the frame and therefore we already removed
+ // our listeners and release the service manager reference!
+ Reference< XMultiServiceFactory > xServiceManager = getServiceFactory();
+ if ( xServiceManager.is() )
+ {
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ if ( pItemHandler->xMenuItemDispatch.is() )
+ {
+ URL aTargetURL;
+ aTargetURL.Complete = pItemHandler->aMenuItemURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ pItemHandler->xMenuItemDispatch->removeStatusListener(
+ static_cast< XStatusListener* >( this ), aTargetURL );
+ }
+
+ pItemHandler->xMenuItemDispatch.clear();
+ if ( pItemHandler->xPopupMenu.is() )
+ {
+ {
+ // Remove popup menu from menu structure
+ SolarMutexGuard aGuard2;
+ m_pVCLMenu->SetPopupMenu( pItemHandler->nItemId, 0 );
+ }
+
+ Reference< com::sun::star::lang::XEventListener > xEventListener( pItemHandler->xPopupMenuController, UNO_QUERY );
+ if ( xEventListener.is() )
+ {
+ EventObject aEventObject;
+ aEventObject.Source = (OWeakObject *)this;
+ xEventListener->disposing( aEventObject );
+ }
+
+ // We now provide a popup menu controller to external code.
+ // Therefore the life-time must be explicitly handled via
+ // dispose!!
+ try
+ {
+ Reference< XComponent > xComponent( pItemHandler->xPopupMenuController, UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ }
+
+ // Release references to controller and popup menu
+ pItemHandler->xPopupMenuController.clear();
+ pItemHandler->xPopupMenu.clear();
+ }
+
+ Reference< XComponent > xComponent( pItemHandler->xSubMenuManager, UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+ }
+ }
+
+ try
+ {
+ if ( m_xFrame.is() )
+ m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& )
+ {
+ }
+
+ m_xFrame = 0;
+}
+
+void SAL_CALL MenuBarManager::disposing( const EventObject& Source ) throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::disposing(evt)" );
+ MenuItemHandler* pMenuItemDisposing = NULL;
+
+ ResetableGuard aGuard( m_aLock );
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+ if ( pMenuItemHandler->xMenuItemDispatch.is() &&
+ pMenuItemHandler->xMenuItemDispatch == Source.Source )
+ {
+ // disposing called from menu item dispatcher, remove listener
+ pMenuItemDisposing = pMenuItemHandler;
+ break;
+ }
+ }
+
+ if ( pMenuItemDisposing )
+ {
+ // Release references to the dispatch object
+ URL aTargetURL;
+ aTargetURL.Complete = pMenuItemDisposing->aMenuItemURL;
+
+ // Check reference of service manager before we use it. Reference could
+ // be cleared due to RemoveListener call!
+ Reference< XMultiServiceFactory > xServiceManager( getServiceFactory() );
+ if ( xServiceManager.is() )
+ {
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ pMenuItemDisposing->xMenuItemDispatch->removeStatusListener(
+ static_cast< XStatusListener* >( this ), aTargetURL );
+ pMenuItemDisposing->xMenuItemDispatch = Reference< XDispatch >();
+ if ( pMenuItemDisposing->xPopupMenu.is() )
+ {
+ Reference< com::sun::star::lang::XEventListener > xEventListener( pMenuItemDisposing->xPopupMenuController, UNO_QUERY );
+ if ( xEventListener.is() )
+ xEventListener->disposing( Source );
+
+ {
+ // Remove popup menu from menu structure as we release our reference to
+ // the controller.
+ SolarMutexGuard aGuard2;
+ m_pVCLMenu->SetPopupMenu( pMenuItemDisposing->nItemId, 0 );
+ }
+
+ pMenuItemDisposing->xPopupMenuController.clear();
+ pMenuItemDisposing->xPopupMenu.clear();
+ }
+ }
+ return;
+ }
+ else if ( Source.Source == m_xFrame )
+ {
+ // Our frame gets disposed. We have to remove all our listeners
+ RemoveListener();
+ }
+ else if ( Source.Source == Reference< XInterface >( m_xDocImageManager, UNO_QUERY ))
+ m_xDocImageManager.clear();
+ else if ( Source.Source == Reference< XInterface >( m_xModuleImageManager, UNO_QUERY ))
+ m_xModuleImageManager.clear();
+}
+
+
+void MenuBarManager::CheckAndAddMenuExtension( Menu* pMenu )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::CheckAndAddMenuExtension" );
+ static const char REFERENCECOMMAND_AFTER[] = ".uno:OnlineRegistrationDlg";
+ static const char REFERENCECOMMAND_BEFORE[] = ".uno:About";
+
+ // retrieve menu extension item
+ MenuExtensionItem aMenuItem( GetMenuExtension() );
+ if (( aMenuItem.aURL.getLength() > 0 ) &&
+ ( aMenuItem.aLabel.getLength() > 0 ))
+ {
+ // remove all old window list entries from menu
+ sal_uInt16 nNewItemId( 0 );
+ sal_uInt16 nInsertPos( MENU_APPEND );
+ sal_uInt16 nAfterPos( MENU_APPEND );
+ sal_uInt16 nBeforePos( MENU_APPEND );
+ String aCommandAfter( String::CreateFromAscii ( REFERENCECOMMAND_AFTER ));
+ String aCommandBefore( String::CreateFromAscii ( REFERENCECOMMAND_BEFORE ));
+ for ( sal_uInt16 n = 0; n < pMenu->GetItemCount(); n++ )
+ {
+ sal_uInt16 nItemId = pMenu->GetItemId( n );
+ nNewItemId = std::max( nItemId, nNewItemId );
+ if ( pMenu->GetItemCommand( nItemId ) == aCommandAfter )
+ nAfterPos = n+1;
+ else if ( pMenu->GetItemCommand( nItemId ) == aCommandBefore )
+ nBeforePos = n;
+ }
+ ++nNewItemId;
+
+ if ( nAfterPos != MENU_APPEND )
+ nInsertPos = nAfterPos;
+ else if ( nBeforePos != MENU_APPEND )
+ nInsertPos = nBeforePos;
+
+ pMenu->InsertItem( nNewItemId, aMenuItem.aLabel, 0, nInsertPos );
+ pMenu->SetItemCommand( nNewItemId, aMenuItem.aURL );
+ }
+}
+
+static void lcl_CheckForChildren(Menu* pMenu, sal_uInt16 nItemId)
+{
+ if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( nItemId ))
+ pMenu->EnableItem( nItemId, pThisPopup->GetItemCount() ? true : false );
+}
+
+//_________________________________________________________________________________________________________________
+// vcl handler
+//_________________________________________________________________________________________________________________
+
+IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Activate" );
+ if ( pMenu == m_pVCLMenu )
+ {
+ // set/unset hiding disabled menu entries
+ sal_Bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled();
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus();
+ sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
+
+ ResetableGuard aGuard( m_aLock );
+
+ sal_uInt16 nFlag = pMenu->GetMenuFlags();
+ if ( bDontHide )
+ nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
+ else
+ nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES;
+ pMenu->SetMenuFlags( nFlag | MENU_FLAG_SHOWCHECKIMAGES );
+
+ if ( m_bActive )
+ return 0;
+
+ m_bActive = sal_True;
+
+ ::rtl::OUString aMenuCommand( m_aMenuItemCommand );
+ if ( m_aMenuItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSpecialWindowMenu)) ||
+ m_aMenuItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSlotSpecialWindowMenu)) ||
+ aMenuCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSpecialWindowCommand)) )
+ MenuManager::UpdateSpecialWindowMenu( pMenu,getServiceFactory(),m_aLock );
+
+ // Check if some modes have changed so we have to update our menu images
+ sal_Int16 nSymbolsStyle = SvtMiscOptions().GetCurrentSymbolsStyle();
+
+ if ( m_bRetrieveImages ||
+ bShowMenuImages != m_bShowMenuImages ||
+ nSymbolsStyle != m_nSymbolsStyle )
+ {
+ m_bShowMenuImages = bShowMenuImages;
+ m_bRetrieveImages = sal_False;
+ m_nSymbolsStyle = nSymbolsStyle;
+ MenuManager::FillMenuImages( m_xFrame, pMenu, bShowMenuImages );
+ }
+
+ // Try to map commands to labels
+ for ( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
+ {
+ sal_uInt16 nItemId = pMenu->GetItemId( nPos );
+ if (( pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR ) &&
+ ( pMenu->GetItemText( nItemId ).Len() == 0 ))
+ {
+ String aCommand = pMenu->GetItemCommand( nItemId );
+ if ( aCommand.Len() > 0 )
+ pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aCommand ));
+ }
+ }
+
+ // Try to set accelerator keys
+ {
+ RetrieveShortcuts( m_aMenuItemHandlerVector );
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+
+ // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex
+ // Only non-popup menu items can have a short-cut
+ if ( pMenuItemHandler->aMenuItemURL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aCmdHelpIndex)) )
+ {
+ KeyCode aKeyCode( KEY_F1 );
+ pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode );
+ }
+ else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 )
+ pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode );
+ }
+ }
+
+ URL aTargetURL;
+
+ // Use provided dispatch provider => fallback to frame as dispatch provider
+ Reference< XDispatchProvider > xDispatchProvider;
+ if ( m_xDispatchProvider.is() )
+ xDispatchProvider = m_xDispatchProvider;
+ else
+ xDispatchProvider = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY );
+
+ if ( xDispatchProvider.is() )
+ {
+ KeyCode aEmptyKeyCode;
+ SvtCommandOptions aCmdOptions;
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+ if ( pMenuItemHandler )
+ {
+ if ( !pMenuItemHandler->xMenuItemDispatch.is() &&
+ !pMenuItemHandler->xSubMenuManager.is() )
+ {
+ // There is no dispatch mechanism for the special window list menu items,
+ // because they are handled directly through XFrame->activate!!!
+ // Don't update dispatches for special file menu items.
+ if ( !(( pMenuItemHandler->nItemId >= START_ITEMID_WINDOWLIST &&
+ pMenuItemHandler->nItemId < END_ITEMID_WINDOWLIST )))
+ {
+ Reference< XDispatch > xMenuItemDispatch;
+
+ ::rtl::OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId );
+ if ( !aItemCommand.getLength() )
+ {
+ aItemCommand = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)pMenuItemHandler->nItemId );
+ pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand );
+ }
+
+ aTargetURL.Complete = aItemCommand;
+
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ if ( bHasDisabledEntries )
+ {
+ if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path ))
+ pMenu->HideItem( pMenuItemHandler->nItemId );
+ }
+
+ if ( m_bIsBookmarkMenu )
+ xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 );
+ else
+ xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+
+ sal_Bool bPopupMenu( sal_False );
+ if ( !pMenuItemHandler->xPopupMenuController.is() &&
+ m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() ))
+ {
+ bPopupMenu = CreatePopupMenuController( pMenuItemHandler );
+ }
+ else if ( pMenuItemHandler->xPopupMenuController.is() )
+ {
+ // Force update of popup menu
+ pMenuItemHandler->xPopupMenuController->updatePopupMenu();
+ bPopupMenu = sal_True;
+ if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( pMenuItemHandler->nItemId ))
+ pMenu->EnableItem( pMenuItemHandler->nItemId, pThisPopup->GetItemCount() ? true : false );
+ }
+
+ lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
+
+ if ( xMenuItemDispatch.is() )
+ {
+ pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
+ pMenuItemHandler->aMenuItemURL = aTargetURL.Complete;
+
+ if ( !bPopupMenu )
+ {
+ // We need only an update to reflect the current state
+ xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
+ xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
+ }
+ }
+ else if ( !bPopupMenu )
+ pMenu->EnableItem( pMenuItemHandler->nItemId, sal_False );
+ }
+ }
+ else if ( pMenuItemHandler->xPopupMenuController.is() )
+ {
+ // Force update of popup menu
+ pMenuItemHandler->xPopupMenuController->updatePopupMenu();
+ lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
+ }
+ else if ( pMenuItemHandler->xMenuItemDispatch.is() )
+ {
+ // We need an update to reflect the current state
+ try
+ {
+ aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ pMenuItemHandler->xMenuItemDispatch->addStatusListener(
+ static_cast< XStatusListener* >( this ), aTargetURL );
+ pMenuItemHandler->xMenuItemDispatch->removeStatusListener(
+ static_cast< XStatusListener* >( this ), aTargetURL );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ else if ( pMenuItemHandler->xSubMenuManager.is() )
+ lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+
+IMPL_LINK( MenuBarManager, Deactivate, Menu *, pMenu )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Deactivate" );
+ if ( pMenu == m_pVCLMenu )
+ {
+ m_bActive = sal_False;
+ if ( pMenu->IsMenuBar() && m_xDeferedItemContainer.is() )
+ {
+ // Start timer to handle settings asynchronous
+ // Changing the menu inside this handler leads to
+ // a crash under X!
+ m_aAsyncSettingsTimer.SetTimeoutHdl(LINK(this, MenuBarManager, AsyncSettingsHdl));
+ m_aAsyncSettingsTimer.SetTimeout(10);
+ m_aAsyncSettingsTimer.Start();
+ }
+ }
+
+ return 1;
+}
+
+IMPL_LINK( MenuBarManager, AsyncSettingsHdl, Timer*,)
+{
+ SolarMutexGuard aGuard;
+ Reference< XInterface > xSelfHold(
+ static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY_THROW );
+
+ m_aAsyncSettingsTimer.Stop();
+ if ( !m_bActive && m_xDeferedItemContainer.is() )
+ {
+ SetItemContainer( m_xDeferedItemContainer );
+ m_xDeferedItemContainer.clear();
+ }
+
+ return 0;
+}
+
+IMPL_LINK( MenuBarManager, Select, Menu *, pMenu )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Select" );
+ URL aTargetURL;
+ Sequence<PropertyValue> aArgs;
+ Reference< XDispatch > xDispatch;
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ sal_uInt16 nCurItemId = pMenu->GetCurItemId();
+ sal_uInt16 nCurPos = pMenu->GetItemPos( nCurItemId );
+ if ( pMenu == m_pVCLMenu &&
+ pMenu->GetItemType( nCurPos ) != MENUITEM_SEPARATOR )
+ {
+ if ( nCurItemId >= START_ITEMID_WINDOWLIST &&
+ nCurItemId <= END_ITEMID_WINDOWLIST )
+ {
+ // window list menu item selected
+
+ Reference< XFramesSupplier > xDesktop( getServiceFactory()->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
+
+ if ( xDesktop.is() )
+ {
+ sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
+ Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY );
+ sal_Int32 nCount = xList->getCount();
+ for ( sal_Int32 i=0; i<nCount; ++i )
+ {
+ Reference< XFrame > xFrame;
+ xList->getByIndex(i) >>= xFrame;
+ if ( xFrame.is() && nTaskId == nCurItemId )
+ {
+ Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ pWin->GrabFocus();
+ pWin->ToTop( TOTOP_RESTOREWHENMIN );
+ break;
+ }
+
+ nTaskId++;
+ }
+ }
+ }
+ else
+ {
+ MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId );
+ if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() )
+ {
+ aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ if ( m_bIsBookmarkMenu )
+ {
+ // bookmark menu item selected
+ aArgs.realloc( 1 );
+ aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
+ aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
+ }
+
+ xDispatch = pMenuItemHandler->xMenuItemDispatch;
+ }
+ }
+ }
+ }
+
+ if ( xDispatch.is() )
+ {
+ const sal_uInt32 nRef = Application::ReleaseSolarMutex();
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MenuBarManager"))).log(getServiceFactory(), m_xFrame, aTargetURL, aArgs);
+ xDispatch->dispatch( aTargetURL, aArgs );
+ Application::AcquireSolarMutex( nRef );
+ }
+
+ return 1;
+}
+
+
+IMPL_LINK( MenuBarManager, Highlight, Menu *, EMPTYARG )
+{
+ return 0;
+}
+
+sal_Bool MenuBarManager::MustBeHidden( PopupMenu* pPopupMenu, const Reference< XURLTransformer >& rTransformer )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MustBeHidden" );
+ if ( pPopupMenu )
+ {
+ URL aTargetURL;
+ SvtCommandOptions aCmdOptions;
+
+ sal_uInt16 nCount = pPopupMenu->GetItemCount();
+ sal_uInt16 nHideCount( 0 );
+
+ for ( sal_uInt16 i = 0; i < nCount; i++ )
+ {
+ sal_uInt16 nId = pPopupMenu->GetItemId( i );
+ if ( nId > 0 )
+ {
+ PopupMenu* pSubPopupMenu = pPopupMenu->GetPopupMenu( nId );
+ if ( pSubPopupMenu )
+ {
+ if ( MustBeHidden( pSubPopupMenu, rTransformer ))
+ {
+ pPopupMenu->HideItem( nId );
+ ++nHideCount;
+ }
+ }
+ else
+ {
+ aTargetURL.Complete = pPopupMenu->GetItemCommand( nId );
+ rTransformer->parseStrict( aTargetURL );
+
+ if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path ))
+ ++nHideCount;
+ }
+ }
+ else
+ ++nHideCount;
+ }
+
+ return ( nCount == nHideCount );
+ }
+
+ return sal_True;
+}
+String MenuBarManager::RetrieveLabelFromCommand( const String& aCmdURL )
+{
+ return framework::RetrieveLabelFromCommand(aCmdURL,mxServiceFactory,m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,m_bModuleIdentified,"Label");
+}
+
+
+
+sal_Bool MenuBarManager::CreatePopupMenuController( MenuItemHandler* pMenuItemHandler )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::CreatePopupMenuController" );
+ rtl::OUString aItemCommand( pMenuItemHandler->aMenuItemURL );
+
+ // Try instanciate a popup menu controller. It is stored in the menu item handler.
+ Reference< XMultiComponentFactory > xPopupMenuControllerFactory( m_xPopupMenuControllerRegistration, UNO_QUERY );
+ if ( xPopupMenuControllerFactory.is() )
+ {
+ Sequence< Any > aSeq( 2 );
+ PropertyValue aPropValue;
+
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
+ aPropValue.Value <<= m_aModuleIdentifier;
+ aSeq[0] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropValue.Value <<= m_xFrame;
+ aSeq[1] <<= aPropValue;
+
+ Reference< XComponentContext > xComponentContext;
+ Reference< XPropertySet > xProps( getServiceFactory(), UNO_QUERY );
+
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>=
+ xComponentContext;
+
+ Reference< XPopupMenuController > xPopupMenuController(
+ xPopupMenuControllerFactory->createInstanceWithArgumentsAndContext(
+ aItemCommand,
+ aSeq,
+ xComponentContext ),
+ UNO_QUERY );
+
+ if ( xPopupMenuController.is() )
+ {
+ // Provide our awt popup menu to the popup menu controller
+ pMenuItemHandler->xPopupMenuController = xPopupMenuController;
+ xPopupMenuController->setPopupMenu( pMenuItemHandler->xPopupMenu );
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+void MenuBarManager::FillMenuManager( Menu* pMenu, const Reference< XFrame >& rFrame, const Reference< XDispatchProvider >& rDispatchProvider, const rtl::OUString& rModuleIdentifier, sal_Bool bDelete, sal_Bool bDeleteChildren )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenuManager" );
+ m_xFrame = rFrame;
+ m_bActive = sal_False;
+ m_bDeleteMenu = bDelete;
+ m_bDeleteChildren = bDeleteChildren;
+ m_pVCLMenu = pMenu;
+ m_bInitialized = sal_False;
+ m_bIsBookmarkMenu = sal_False;
+ m_xDispatchProvider = rDispatchProvider;
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ m_bShowMenuImages = rSettings.GetUseImagesInMenus();
+ m_bRetrieveImages = sal_False;
+
+ sal_Int32 nAddonsURLPrefixLength = ADDONSPOPUPMENU_URL_PREFIX.getLength();
+
+ // Add root as ui configuration listener
+ RetrieveImageManagers();
+
+ if ( pMenu->IsMenuBar() && rFrame.is() )
+ {
+ // First merge all addon popup menus into our structure
+ sal_uInt16 nPos = 0;
+ for ( nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
+ {
+ sal_uInt16 nItemId = pMenu->GetItemId( nPos );
+ ::rtl::OUString aCommand = pMenu->GetItemCommand( nItemId );
+ if ( nItemId == SID_MDIWINDOWLIST ||
+ aCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSpecialWindowCommand)) )
+ {
+ // Retrieve addon popup menus and add them to our menu bar
+ Reference< com::sun::star::frame::XModel > xModel;
+ Reference< com::sun::star::frame::XController > xController( rFrame->getController(), UNO_QUERY );
+ if ( xController.is() )
+ xModel = Reference< com::sun::star::frame::XModel >( xController->getModel(), UNO_QUERY );
+ framework::AddonMenuManager::MergeAddonPopupMenus( rFrame, xModel, nPos, (MenuBar *)pMenu );
+ break;
+ }
+ }
+
+ // Merge the Add-Ons help menu items into the Office help menu
+ framework::AddonMenuManager::MergeAddonHelpMenu( rFrame, (MenuBar *)pMenu );
+ }
+
+ String aEmpty;
+ sal_Bool bAccessibilityEnabled( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() );
+ sal_uInt16 nItemCount = pMenu->GetItemCount();
+ ::rtl::OUString aItemCommand;
+ m_aMenuItemHandlerVector.reserve(nItemCount);
+ for ( sal_uInt16 i = 0; i < nItemCount; i++ )
+ {
+ sal_uInt16 nItemId = FillItemCommand(aItemCommand,pMenu, i );
+
+ // Set module identifier when provided from outside
+ if ( rModuleIdentifier.getLength() > 0 )
+ {
+ m_aModuleIdentifier = rModuleIdentifier;
+ m_bModuleIdentified = sal_True;
+ }
+
+ if (( pMenu->IsMenuBar() || bAccessibilityEnabled ) &&
+ ( pMenu->GetItemText( nItemId ).Len() == 0 ))
+ {
+ if ( aItemCommand.getLength() > 0 )
+ pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aItemCommand ));
+ }
+
+ Reference< XDispatch > xDispatch;
+ Reference< XStatusListener > xStatusListener;
+ PopupMenu* pPopup = pMenu->GetPopupMenu( nItemId );
+ bool bItemShowMenuImages = m_bShowMenuImages;
+ // overwrite the show icons on menu option?
+ if (!bItemShowMenuImages)
+ {
+ MenuItemBits nBits = pMenu->GetItemBits( nItemId );
+ bItemShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
+ }
+ if ( pPopup )
+ {
+ // Retrieve module identifier from Help Command entry
+ rtl::OUString aModuleIdentifier( rModuleIdentifier );
+ if ( pMenu->GetHelpCommand( nItemId ).Len() > 0 )
+ {
+ aModuleIdentifier = pMenu->GetHelpCommand( nItemId );
+ pMenu->SetHelpCommand( nItemId, aEmpty );
+ }
+
+ if ( m_xPopupMenuControllerRegistration.is() &&
+ pPopup->GetItemCount() == 0 &&
+ m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() )
+ )
+ {
+ // Check if we have to create a popup menu for a uno based popup menu controller.
+ // We have to set an empty popup menu into our menu structure so the controller also
+ // works with inplace OLE. Remove old dummy popup menu!
+ MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
+ VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
+ PopupMenu* pNewPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu();
+ pMenu->SetPopupMenu( nItemId, pNewPopupMenu );
+ pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
+ pItemHandler->aMenuItemURL = aItemCommand;
+ m_aMenuItemHandlerVector.push_back( pItemHandler );
+ delete pPopup;
+
+ if ( bAccessibilityEnabled )
+ {
+ if ( CreatePopupMenuController( pItemHandler ))
+ pItemHandler->xPopupMenuController->updatePopupMenu();
+ }
+ lcl_CheckForChildren(pMenu, nItemId);
+ }
+ else if (( aItemCommand.getLength() > nAddonsURLPrefixLength ) &&
+ ( aItemCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 ))
+ {
+ // A special addon popup menu, must be created with a different ctor
+ MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), m_xFrame, m_xURLTransformer,(AddonPopupMenu *)pPopup, bDeleteChildren, bDeleteChildren );
+ AddMenu(pSubMenuManager,aItemCommand,nItemId);
+ }
+ else
+ {
+ Reference< XDispatchProvider > xPopupMenuDispatchProvider( rDispatchProvider );
+
+ // Retrieve possible attributes struct
+ MenuConfiguration::Attributes* pAttributes = (MenuConfiguration::Attributes *)(pMenu->GetUserValue( nItemId ));
+ if ( pAttributes )
+ xPopupMenuDispatchProvider = pAttributes->xDispatchProvider;
+
+ // Check if this is the help menu. Add menu item if needed
+ if ( nItemId == SID_HELPMENU || aItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSlotHelpMenu)) || aItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aCmdHelpMenu)) )
+ {
+ // Check if this is the help menu. Add menu item if needed
+ CheckAndAddMenuExtension( pPopup );
+ }
+ else if (( nItemId == SID_ADDONLIST || aItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aSlotSpecialToolsMenu)) || aItemCommand.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aCmdToolsMenu)) ) &&
+ AddonMenuManager::HasAddonMenuElements() )
+ {
+ // Create addon popup menu if there exist elements and this is the tools popup menu
+ sal_uInt16 nCount = 0;
+ AddonMenu* pSubMenu = AddonMenuManager::CreateAddonMenu( rFrame );
+ if ( pSubMenu && ( pSubMenu->GetItemCount() > 0 ))
+ {
+ if ( pPopup->GetItemType( nCount-1 ) != MENUITEM_SEPARATOR )
+ pPopup->InsertSeparator();
+
+ // Use resource to load popup menu title
+ String aAddonsStrRes = String( FwkResId( STR_MENU_ADDONS ));
+ pPopup->InsertItem( ITEMID_ADDONLIST, aAddonsStrRes );
+ pPopup->SetPopupMenu( ITEMID_ADDONLIST, pSubMenu );
+
+ // Set item command for popup menu to enable it for GetImageFromURL
+ const ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ ::rtl::OUString aNewItemCommand( aSlotString );
+ aNewItemCommand += ::rtl::OUString::valueOf( (sal_Int32)ITEMID_ADDONLIST );
+ pPopup->SetItemCommand( ITEMID_ADDONLIST, aNewItemCommand );
+ }
+ else
+ delete pSubMenu;
+ }
+
+ if ( nItemId == ITEMID_ADDONLIST )
+ {
+ AddonMenu* pSubMenu = dynamic_cast< AddonMenu* >( pPopup );
+ if ( pSubMenu )
+ {
+ MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), m_xFrame, m_xURLTransformer,pSubMenu, sal_True, sal_False );
+ AddMenu(pSubMenuManager,aItemCommand,nItemId);
+ pSubMenuManager->m_aMenuItemCommand = ::rtl::OUString();
+
+ // Set image for the addon popup menu item
+ if ( bItemShowMenuImages && !pPopup->GetItemImage( ITEMID_ADDONLIST ))
+ {
+ Reference< XFrame > xTemp( rFrame );
+ Image aImage = GetImageFromURL( xTemp, aItemCommand, false );
+ if ( !!aImage )
+ pPopup->SetItemImage( ITEMID_ADDONLIST, aImage );
+ }
+ }
+ }
+ else
+ {
+ MenuBarManager* pSubMenuMgr = new MenuBarManager( getServiceFactory(), rFrame, m_xURLTransformer,rDispatchProvider, aModuleIdentifier, pPopup, bDeleteChildren, bDeleteChildren );
+ AddMenu(pSubMenuMgr,aItemCommand,nItemId);
+ }
+ }
+ }
+ else if ( pMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
+ {
+ if ( bItemShowMenuImages )
+ {
+ if ( AddonMenuManager::IsAddonMenuId( nItemId ))
+ {
+ // Add-Ons uses images from different places
+ Image aImage;
+ rtl::OUString aImageId;
+
+ MenuConfiguration::Attributes* pMenuAttributes =
+ (MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId );
+
+ if ( pMenuAttributes && pMenuAttributes->aImageId.getLength() > 0 )
+ {
+ // Retrieve image id from menu attributes
+ aImage = GetImageFromURL( m_xFrame, aImageId, false );
+ }
+
+ if ( !aImage )
+ {
+ aImage = GetImageFromURL( m_xFrame, aItemCommand, false );
+ if ( !aImage )
+ aImage = AddonsOptions().GetImageFromURL( aItemCommand, false );
+ }
+
+ if ( !!aImage )
+ pMenu->SetItemImage( nItemId, aImage );
+ else
+ m_bRetrieveImages = sal_True;
+ }
+ m_bRetrieveImages = sal_True;
+ }
+
+ MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
+ pItemHandler->aMenuItemURL = aItemCommand;
+
+ if ( m_xPopupMenuControllerRegistration.is() &&
+ m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() ))
+ {
+ // Check if we have to create a popup menu for a uno based popup menu controller.
+ // We have to set an empty popup menu into our menu structure so the controller also
+ // works with inplace OLE.
+ VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
+ PopupMenu* pPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu();
+ pMenu->SetPopupMenu( pItemHandler->nItemId, pPopupMenu );
+ pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
+
+ if ( bAccessibilityEnabled && CreatePopupMenuController( pItemHandler ) )
+ {
+ pItemHandler->xPopupMenuController->updatePopupMenu();
+ }
+
+ lcl_CheckForChildren(pMenu, pItemHandler->nItemId);
+ }
+
+ m_aMenuItemHandlerVector.push_back( pItemHandler );
+ }
+ }
+
+ if ( bAccessibilityEnabled )
+ {
+ RetrieveShortcuts( m_aMenuItemHandlerVector );
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+
+ // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex
+ // Only non-popup menu items can have a short-cut
+ if ( pMenuItemHandler->aMenuItemURL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(aCmdHelpIndex)) )
+ {
+ KeyCode aKeyCode( KEY_F1 );
+ pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode );
+ }
+ else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 )
+ pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode );
+ }
+ }
+
+ SetHdl();
+}
+
+void MenuBarManager::impl_RetrieveShortcutsFromConfiguration(
+ const Reference< XAcceleratorConfiguration >& rAccelCfg,
+ const Sequence< rtl::OUString >& rCommands,
+ std::vector< MenuItemHandler* >& aMenuShortCuts )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::impl_RetrieveShortcutsFromConfiguration" );
+ if ( rAccelCfg.is() )
+ {
+ try
+ {
+ com::sun::star::awt::KeyEvent aKeyEvent;
+ Sequence< Any > aSeqKeyCode = rAccelCfg->getPreferredKeyEventsForCommandList( rCommands );
+ for ( sal_Int32 i = 0; i < aSeqKeyCode.getLength(); i++ )
+ {
+ if ( aSeqKeyCode[i] >>= aKeyEvent )
+ aMenuShortCuts[i]->aKeyCode = svt::AcceleratorExecute::st_AWTKey2VCLKey( aKeyEvent );
+ }
+ }
+ catch ( IllegalArgumentException& )
+ {
+ }
+ }
+}
+
+void MenuBarManager::RetrieveShortcuts( std::vector< MenuItemHandler* >& aMenuShortCuts )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RetrieveShortcuts" );
+ if ( !m_bModuleIdentified )
+ {
+ m_bModuleIdentified = sal_True;
+ Reference< XModuleManager > xModuleManager;
+ xModuleManager = Reference< XModuleManager >( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
+
+ try
+ {
+ m_aModuleIdentifier = xModuleManager->identify( m_xFrame );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ if ( m_bModuleIdentified )
+ {
+ Reference< XAcceleratorConfiguration > xDocAccelCfg( m_xDocAcceleratorManager );
+ Reference< XAcceleratorConfiguration > xModuleAccelCfg( m_xModuleAcceleratorManager );
+ Reference< XAcceleratorConfiguration > xGlobalAccelCfg( m_xGlobalAcceleratorManager );
+
+ if ( !m_bAcceleratorCfg )
+ {
+ // Retrieve references on demand
+ m_bAcceleratorCfg = sal_True;
+ if ( !xDocAccelCfg.is() )
+ {
+ Reference< XController > xController = m_xFrame->getController();
+ Reference< XModel > xModel;
+ if ( xController.is() )
+ {
+ xModel = xController->getModel();
+ if ( xModel.is() )
+ {
+ Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
+ if ( xSupplier.is() )
+ {
+ Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY );
+ if ( xDocUICfgMgr.is() )
+ {
+ xDocAccelCfg = Reference< XAcceleratorConfiguration >( xDocUICfgMgr->getShortCutManager(), UNO_QUERY );
+ m_xDocAcceleratorManager = xDocAccelCfg;
+ }
+ }
+ }
+ }
+ }
+
+ if ( !xModuleAccelCfg.is() )
+ {
+ Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( getServiceFactory()->createInstance(
+ SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ),
+ UNO_QUERY );
+ try
+ {
+ Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
+ if ( xUICfgMgr.is() )
+ {
+ xModuleAccelCfg = Reference< XAcceleratorConfiguration >( xUICfgMgr->getShortCutManager(), UNO_QUERY );
+ m_xModuleAcceleratorManager = xModuleAccelCfg;
+ }
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ if ( !xGlobalAccelCfg.is() )
+ {
+ xGlobalAccelCfg = Reference< XAcceleratorConfiguration >( getServiceFactory()->createInstance(
+ SERVICENAME_GLOBALACCELERATORCONFIGURATION ),
+ UNO_QUERY );
+ m_xGlobalAcceleratorManager = xGlobalAccelCfg;
+ }
+ }
+
+ KeyCode aEmptyKeyCode;
+ Sequence< rtl::OUString > aSeq( aMenuShortCuts.size() );
+ const sal_uInt32 nCount = aMenuShortCuts.size();
+ for ( sal_uInt32 i = 0; i < nCount; ++i )
+ {
+ aSeq[i] = aMenuShortCuts[i]->aMenuItemURL;
+ aMenuShortCuts[i]->aKeyCode = aEmptyKeyCode;
+ }
+
+ if ( m_xGlobalAcceleratorManager.is() )
+ impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts );
+ if ( m_xModuleAcceleratorManager.is() )
+ impl_RetrieveShortcutsFromConfiguration( xModuleAccelCfg, aSeq, aMenuShortCuts );
+ if ( m_xDocAcceleratorManager.is() )
+ impl_RetrieveShortcutsFromConfiguration( xDocAccelCfg, aSeq, aMenuShortCuts );
+ }
+}
+
+void MenuBarManager::RetrieveImageManagers()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RetrieveImageManagers" );
+ if ( !m_xDocImageManager.is() )
+ {
+ Reference< XController > xController = m_xFrame->getController();
+ Reference< XModel > xModel;
+ if ( xController.is() )
+ {
+ xModel = xController->getModel();
+ if ( xModel.is() )
+ {
+ Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
+ if ( xSupplier.is() )
+ {
+ Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY );
+ m_xDocImageManager = Reference< XImageManager >( xDocUICfgMgr->getImageManager(), UNO_QUERY );
+ m_xDocImageManager->addConfigurationListener(
+ Reference< XUIConfigurationListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ }
+ }
+ }
+
+ Reference< XModuleManager > xModuleManager;
+ if ( m_aModuleIdentifier.getLength() == 0 )
+ xModuleManager.set( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
+
+ try
+ {
+ if ( xModuleManager.is() )
+ m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) );
+ }
+ catch( Exception& )
+ {
+ }
+
+ if ( !m_xModuleImageManager.is() )
+ {
+ Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( getServiceFactory()->createInstance(
+ SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ),
+ UNO_QUERY );
+ Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
+ m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY );
+ m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+}
+
+void MenuBarManager::FillMenuWithConfiguration(
+ sal_uInt16& nId,
+ Menu* pMenu,
+ const ::rtl::OUString& rModuleIdentifier,
+ const Reference< XIndexAccess >& rItemContainer,
+ const Reference< XURLTransformer >& rTransformer )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenuWithConfiguration" );
+ Reference< XDispatchProvider > xEmptyDispatchProvider;
+ MenuBarManager::FillMenu( nId, pMenu, rModuleIdentifier, rItemContainer, xEmptyDispatchProvider );
+
+ // Merge add-on menu entries into the menu bar
+ MenuBarManager::MergeAddonMenus( static_cast< Menu* >( pMenu ),
+ AddonsOptions().GetMergeMenuInstructions(),
+ rModuleIdentifier );
+
+ sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
+ if ( bHasDisabledEntries )
+ {
+ sal_uInt16 nCount = pMenu->GetItemCount();
+ for ( sal_uInt16 i = 0; i < nCount; i++ )
+ {
+ sal_uInt16 nID = pMenu->GetItemId( i );
+ if ( nID > 0 )
+ {
+ PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nID );
+ if ( pPopupMenu )
+ {
+ if ( MustBeHidden( pPopupMenu, rTransformer ))
+ pMenu->HideItem( nId );
+ }
+ }
+ }
+ }
+}
+
+void MenuBarManager::FillMenu(
+ sal_uInt16& nId,
+ Menu* pMenu,
+ const rtl::OUString& rModuleIdentifier,
+ const Reference< XIndexAccess >& rItemContainer,
+ const Reference< XDispatchProvider >& rDispatchProvider )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenu" );
+ // Fill menu bar with container contents
+ for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ )
+ {
+ Sequence< PropertyValue > aProp;
+ rtl::OUString aCommandURL;
+ rtl::OUString aLabel;
+ rtl::OUString aHelpURL;
+ rtl::OUString aModuleIdentifier( rModuleIdentifier );
+ sal_uInt16 nType = 0;
+ Reference< XIndexAccess > xIndexContainer;
+ Reference< XDispatchProvider > xDispatchProvider( rDispatchProvider );
+ sal_Int16 nStyle = 0;
+ try
+ {
+ if ( rItemContainer->getByIndex( n ) >>= aProp )
+ {
+ for ( int i = 0; i < aProp.getLength(); i++ )
+ {
+ rtl::OUString aPropName = aProp[i].Name;
+ if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_COMMANDURL,
+ LEN_DESCRIPTOR_COMMANDURL ))
+ aProp[i].Value >>= aCommandURL;
+ else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_HELPURL,
+ LEN_DESCRIPTOR_HELPURL ))
+ aProp[i].Value >>= aHelpURL;
+ else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_CONTAINER,
+ LEN_DESCRIPTOR_CONTAINER ))
+ aProp[i].Value >>= xIndexContainer;
+ else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_LABEL,
+ LEN_DESCRIPTOR_LABEL ))
+ aProp[i].Value >>= aLabel;
+ else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_TYPE,
+ LEN_DESCRIPTOR_TYPE ))
+ aProp[i].Value >>= nType;
+ else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_MODULEIDENTIFIER,
+ LEN_DESCRIPTOR_MODULEIDENTIFIER ))
+ aProp[i].Value >>= aModuleIdentifier;
+ else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_DISPATCHPROVIDER,
+ LEN_DESCRIPTOR_DISPATCHPROVIDER ))
+ aProp[i].Value >>= xDispatchProvider;
+ else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_STYLE, ITEM_DESCRIPTOR_STYLE_LEN ))
+ aProp[i].Value >>= nStyle;
+ }
+
+ if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
+ {
+ pMenu->InsertItem( nId, aLabel );
+ pMenu->SetItemCommand( nId, aCommandURL );
+
+ if ( nStyle )
+ {
+ MenuItemBits nBits = pMenu->GetItemBits( nId );
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::ICON )
+ nBits |= MIB_ICON;
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::TEXT )
+ nBits |= MIB_TEXT;
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::RADIO_CHECK )
+ nBits |= MIB_RADIOCHECK;
+ pMenu->SetItemBits( nId, nBits );
+ }
+ if ( xIndexContainer.is() )
+ {
+ PopupMenu* pNewPopupMenu = new PopupMenu;
+ pMenu->SetPopupMenu( nId, pNewPopupMenu );
+
+ if ( xDispatchProvider.is() )
+ {
+ // Use attributes struct to transport special dispatch provider
+ MenuConfiguration::Attributes* pAttributes = new MenuConfiguration::Attributes;
+ pAttributes->xDispatchProvider = xDispatchProvider;
+ pMenu->SetUserValue( nId, (sal_uIntPtr)( pAttributes ));
+ }
+
+ // Use help command to transport module identifier
+ if ( aModuleIdentifier.getLength() > 0 )
+ pMenu->SetHelpCommand( nId, aModuleIdentifier );
+
+ ++nId;
+ FillMenu( nId, pNewPopupMenu, aModuleIdentifier, xIndexContainer, xDispatchProvider );
+ }
+ else
+ ++nId;
+ }
+ else
+ {
+ pMenu->InsertSeparator();
+ ++nId;
+ }
+ }
+ }
+ catch ( IndexOutOfBoundsException& )
+ {
+ break;
+ }
+ }
+}
+
+void MenuBarManager::MergeAddonMenus(
+ Menu* pMenuBar,
+ const MergeMenuInstructionContainer& aMergeInstructionContainer,
+ const ::rtl::OUString& rModuleIdentifier )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MergeAddonMenus" );
+ // set start value for the item ID for the new addon menu items
+ sal_uInt16 nItemId = ADDONMENU_MERGE_ITEMID_START;
+
+ const sal_uInt32 nCount = aMergeInstructionContainer.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ const MergeMenuInstruction& rMergeInstruction = aMergeInstructionContainer[i];
+
+ if ( MenuBarMerger::IsCorrectContext( rMergeInstruction.aMergeContext, rModuleIdentifier ))
+ {
+ ::std::vector< ::rtl::OUString > aMergePath;
+
+ // retrieve the merge path from the merge point string
+ MenuBarMerger::RetrieveReferencePath( rMergeInstruction.aMergePoint, aMergePath );
+
+ // convert the sequence/sequence property value to a more convenient vector<>
+ AddonMenuContainer aMergeMenuItems;
+ MenuBarMerger::GetSubMenu( rMergeInstruction.aMergeMenu, aMergeMenuItems );
+
+ // try to find the reference point for our merge operation
+ Menu* pMenu = pMenuBar;
+ ReferencePathInfo aResult = MenuBarMerger::FindReferencePath( aMergePath, pMenu );
+
+ if ( aResult.eResult == RP_OK )
+ {
+ // normal merge operation
+ MenuBarMerger::ProcessMergeOperation( aResult.pPopupMenu,
+ aResult.nPos,
+ nItemId,
+ rMergeInstruction.aMergeCommand,
+ rMergeInstruction.aMergeCommandParameter,
+ rModuleIdentifier,
+ aMergeMenuItems );
+ }
+ else
+ {
+ // fallback
+ MenuBarMerger::ProcessFallbackOperation( aResult,
+ nItemId,
+ rMergeInstruction.aMergeCommand,
+ rMergeInstruction.aMergeFallback,
+ aMergePath,
+ rModuleIdentifier,
+ aMergeMenuItems );
+ }
+ }
+ }
+}
+
+void MenuBarManager::SetItemContainer( const Reference< XIndexAccess >& rItemContainer )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarManager::SetItemContainer" );
+
+ ResetableGuard aGuard( m_aLock );
+
+ Reference< XFrame > xFrame = m_xFrame;
+
+ if ( !m_bModuleIdentified )
+ {
+ m_bModuleIdentified = sal_True;
+ Reference< XModuleManager > xModuleManager;
+ xModuleManager = Reference< XModuleManager >( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
+
+ try
+ {
+ m_aModuleIdentifier = xModuleManager->identify( xFrame );
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ // Clear MenuBarManager structures
+ {
+ SolarMutexGuard aSolarMutexGuard;
+
+ // Check active state as we cannot change our VCL menu during activation by the user
+ if ( m_bActive )
+ {
+ m_xDeferedItemContainer = rItemContainer;
+ return;
+ }
+
+ RemoveListener();
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ pItemHandler->xMenuItemDispatch.clear();
+ pItemHandler->xSubMenuManager.clear();
+ delete pItemHandler;
+ }
+ m_aMenuItemHandlerVector.clear();
+
+ // Remove top-level parts
+ m_pVCLMenu->Clear();
+
+ sal_uInt16 nId = 1;
+
+ // Fill menu bar with container contents
+ FillMenuWithConfiguration( nId, (Menu *)m_pVCLMenu, m_aModuleIdentifier, rItemContainer, m_xURLTransformer );
+
+ // Refill menu manager again
+ Reference< XDispatchProvider > xDispatchProvider;
+ FillMenuManager( m_pVCLMenu, xFrame, xDispatchProvider, m_aModuleIdentifier, sal_False, sal_True );
+
+ // add itself as frame action listener
+ m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+}
+
+void MenuBarManager::GetPopupController( PopupControllerCache& rPopupController )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::GetPopupController" );
+ String aPopupScheme = String::CreateFromAscii( "vnd.sun.star.popup:" );
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ if ( pItemHandler->xPopupMenuController.is() )
+ {
+ Reference< XDispatchProvider > xDispatchProvider( pItemHandler->xPopupMenuController, UNO_QUERY );
+
+ PopupControllerEntry aPopupControllerEntry;
+ aPopupControllerEntry.m_xDispatchProvider = xDispatchProvider;
+
+ // Just use the main part of the URL for popup menu controllers
+ sal_Int32 nQueryPart( 0 );
+ sal_Int32 nSchemePart( 0 );
+ rtl::OUString aMainURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" ));
+ rtl::OUString aMenuURL( pItemHandler->aMenuItemURL );
+
+ nSchemePart = aMenuURL.indexOf( ':' );
+ if (( nSchemePart > 0 ) &&
+ ( aMenuURL.getLength() > ( nSchemePart+1 )))
+ {
+ nQueryPart = aMenuURL.indexOf( '?', nSchemePart );
+ if ( nQueryPart > 0 )
+ aMainURL += aMenuURL.copy( nSchemePart, nQueryPart-nSchemePart );
+ else if ( nQueryPart == -1 )
+ aMainURL += aMenuURL.copy( nSchemePart+1 );
+
+ rPopupController.insert( PopupControllerCache::value_type(
+ aMainURL, aPopupControllerEntry ));
+ }
+ }
+ if ( pItemHandler->xSubMenuManager.is() )
+ {
+ MenuBarManager* pMenuBarManager = (MenuBarManager*)(pItemHandler->xSubMenuManager.get());
+ if ( pMenuBarManager )
+ pMenuBarManager->GetPopupController( rPopupController );
+ }
+ }
+}
+
+const Reference< XMultiServiceFactory >& MenuBarManager::getServiceFactory()
+{
+ return mxServiceFactory;
+}
+
+void MenuBarManager::AddMenu(MenuBarManager* pSubMenuManager,const ::rtl::OUString& _sItemCommand,sal_uInt16 _nItemId)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::AddMenu" );
+ Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY );
+ m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( xSubMenuManager, UNO_QUERY ));
+
+ // store menu item command as we later have to know which menu is active (see Activate handler)
+ pSubMenuManager->m_aMenuItemCommand = _sItemCommand;
+ Reference< XDispatch > xDispatch;
+ MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
+ _nItemId,
+ xSubMenuManager,
+ xDispatch );
+ pMenuItemHandler->aMenuItemURL = _sItemCommand;
+ m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
+}
+
+sal_uInt16 MenuBarManager::FillItemCommand(::rtl::OUString& _rItemCommand,Menu* _pMenu,sal_uInt16 _nIndex) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillItemCommand" );
+ sal_uInt16 nItemId = _pMenu->GetItemId( _nIndex );
+
+ _rItemCommand = _pMenu->GetItemCommand( nItemId );
+ if ( !_rItemCommand.getLength() )
+ {
+ const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ _rItemCommand = aSlotString;
+ _rItemCommand += ::rtl::OUString::valueOf( (sal_Int32)nItemId );
+ _pMenu->SetItemCommand( nItemId, _rItemCommand );
+ }
+ return nItemId;
+}
+void MenuBarManager::Init(const Reference< XFrame >& rFrame,AddonMenu* pAddonMenu,sal_Bool bDelete,sal_Bool bDeleteChildren,bool _bHandlePopUp)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Init" );
+ m_bActive = sal_False;
+ m_bDeleteMenu = bDelete;
+ m_bDeleteChildren = bDeleteChildren;
+ m_pVCLMenu = pAddonMenu;
+ m_xFrame = rFrame;
+ m_bInitialized = sal_False;
+ m_bIsBookmarkMenu = sal_True;
+
+ rtl::OUString aModuleIdentifier;
+ m_xPopupMenuControllerRegistration = Reference< ::com::sun::star::frame::XUIControllerRegistration >(
+ getServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.PopupMenuControllerFactory" ))),
+ UNO_QUERY );
+
+ Reference< XStatusListener > xStatusListener;
+ Reference< XDispatch > xDispatch;
+ sal_uInt16 nItemCount = pAddonMenu->GetItemCount();
+ ::rtl::OUString aItemCommand;
+ m_aMenuItemHandlerVector.reserve(nItemCount);
+ for ( sal_uInt16 i = 0; i < nItemCount; i++ )
+ {
+ sal_uInt16 nItemId = FillItemCommand(aItemCommand,pAddonMenu, i );
+
+ PopupMenu* pPopupMenu = pAddonMenu->GetPopupMenu( nItemId );
+ if ( pPopupMenu )
+ {
+ Reference< XDispatchProvider > xDispatchProvider;
+ MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), rFrame, m_xURLTransformer,xDispatchProvider, aModuleIdentifier, pPopupMenu, _bHandlePopUp ? sal_False : bDeleteChildren, _bHandlePopUp ? sal_False : bDeleteChildren );
+
+ Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY );
+
+ // store menu item command as we later have to know which menu is active (see Acivate handler)
+ pSubMenuManager->m_aMenuItemCommand = aItemCommand;
+
+ MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
+ nItemId,
+ xSubMenuManager,
+ xDispatch );
+ m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
+ }
+ else
+ {
+ if ( pAddonMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
+ {
+ MenuConfiguration::Attributes* pAddonAttributes = (MenuConfiguration::Attributes *)(pAddonMenu->GetUserValue( nItemId ));
+ MenuItemHandler* pMenuItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
+
+ if ( pAddonAttributes )
+ {
+ // read additional attributes from attributes struct and AddonMenu implementation will delete all attributes itself!!
+ pMenuItemHandler->aTargetFrame = pAddonAttributes->aTargetFrame;
+ }
+
+ pMenuItemHandler->aMenuItemURL = aItemCommand;
+ if ( _bHandlePopUp )
+ {
+ // Check if we have to create a popup menu for a uno based popup menu controller.
+ // We have to set an empty popup menu into our menu structure so the controller also
+ // works with inplace OLE.
+ if ( m_xPopupMenuControllerRegistration.is() &&
+ m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() ))
+ {
+ VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
+ PopupMenu* pCtlPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu();
+ pAddonMenu->SetPopupMenu( pMenuItemHandler->nItemId, pCtlPopupMenu );
+ pMenuItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
+
+ }
+ }
+ m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
+ }
+ }
+ }
+
+ SetHdl();
+}
+
+void MenuBarManager::SetHdl()
+{
+ m_pVCLMenu->SetHighlightHdl( LINK( this, MenuBarManager, Highlight ));
+ m_pVCLMenu->SetActivateHdl( LINK( this, MenuBarManager, Activate ));
+ m_pVCLMenu->SetDeactivateHdl( LINK( this, MenuBarManager, Deactivate ));
+ m_pVCLMenu->SetSelectHdl( LINK( this, MenuBarManager, Select ));
+
+ if ( !m_xURLTransformer.is() && mxServiceFactory.is() )
+ m_xURLTransformer.set( mxServiceFactory->createInstance(
+ SERVICENAME_URLTRANSFORMER),
+ UNO_QUERY );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/menubarmerger.cxx b/framework/source/uielement/menubarmerger.cxx
new file mode 100644
index 000000000000..5aba33de6877
--- /dev/null
+++ b/framework/source/uielement/menubarmerger.cxx
@@ -0,0 +1,451 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <uielement/menubarmerger.hxx>
+#include <framework/addonsoptions.hxx>
+
+using namespace ::com::sun::star;
+
+static const char SEPARATOR_STRING[] = "private:separator";
+static const sal_uInt32 SEPARATOR_STRING_LEN = 17;
+
+static const char MERGECOMMAND_ADDAFTER[] = "AddAfter";
+static const sal_uInt32 MERGECOMMAND_ADDAFTER_LEN = 8;
+static const char MERGECOMMAND_ADDBEFORE[] = "AddBefore";
+static const sal_uInt32 MERGECOMMAND_ADDBEFORE_LEN = 9;
+static const char MERGECOMMAND_REPLACE[] = "Replace";
+static const sal_uInt32 MERGECOMMAND_REPLACE_LEN = 7;
+static const char MERGECOMMAND_REMOVE[] = "Remove";
+static const sal_uInt32 MERGECOMMAND_REMOVE_LEN = 6;
+
+static const char MERGEFALLBACK_ADDPATH[] = "AddPath";
+static const char MERGEFALLBACK_ADDPATH_LEN = 7;
+static const char MERGEFALLBACK_IGNORE[] = "Ignore";
+static const char MERGEFALLBACK_IGNORE_LEN = 6;
+
+
+namespace framework
+{
+
+/**
+ Check whether a module identifier is part of a context
+ defined by a colon separated list of module identifier.
+
+ @param
+ rContext
+
+ Describes a context string list where all contexts
+ are delimited by a colon. For more information about
+ the module identifier used as context strings see the
+ IDL description of com::sun::star::frame::XModuleManager
+
+ @param
+ rModuleIdentifier
+
+ A string describing a module identifier. See IDL
+ description of com::sun::star::frame::XModuleManager.
+
+*/
+bool MenuBarMerger::IsCorrectContext( const ::rtl::OUString& rContext, const ::rtl::OUString& rModuleIdentifier )
+{
+ return (( rContext.getLength() == 0 ) || ( rContext.indexOf( rModuleIdentifier ) >= 0 ));
+}
+
+void MenuBarMerger::RetrieveReferencePath(
+ const ::rtl::OUString& rReferencePathString,
+ ::std::vector< ::rtl::OUString >& rReferencePath )
+{
+ const sal_Char aDelimiter = '\\';
+
+ rReferencePath.clear();
+ sal_Int32 nIndex( 0 );
+ do
+ {
+ ::rtl::OUString aToken = rReferencePathString.getToken( 0, aDelimiter, nIndex );
+ if ( aToken.getLength() > 0 )
+ rReferencePath.push_back( aToken );
+ }
+ while ( nIndex >= 0 );
+}
+
+ReferencePathInfo MenuBarMerger::FindReferencePath(
+ const ::std::vector< ::rtl::OUString >& rReferencePath,
+ Menu* pMenu )
+{
+ sal_uInt32 i( 0 );
+ const sal_uInt32 nCount( rReferencePath.size() );
+
+ ReferencePathInfo aResult;
+ if ( !nCount )
+ {
+ aResult.eResult = RP_MENUITEM_NOT_FOUND;
+ return aResult;
+ }
+
+ Menu* pCurrMenu( pMenu );
+ RPResultInfo eResult( RP_OK );
+
+ sal_Int32 nLevel( - 1 );
+ sal_uInt16 nPos( MENU_ITEM_NOTFOUND );
+ do
+ {
+ ++nLevel;
+ ::rtl::OUString aCmd( rReferencePath[i] );
+
+ if ( i == nCount-1 )
+ {
+ // Check last reference path element. Must be a leave (menu item).
+ sal_uInt16 nTmpPos = FindMenuItem( aCmd, pCurrMenu );
+ if ( nTmpPos != MENU_ITEM_NOTFOUND )
+ nPos = nTmpPos;
+ eResult = ( nTmpPos != MENU_ITEM_NOTFOUND ) ? RP_OK : RP_MENUITEM_NOT_FOUND;
+ }
+ else
+ {
+ // Check reference path element. Must be a node (popup menu)!
+ sal_uInt16 nTmpPos = FindMenuItem( aCmd, pCurrMenu );
+ if ( nTmpPos != MENU_ITEM_NOTFOUND )
+ {
+ sal_uInt16 nItemId = pCurrMenu->GetItemId( nTmpPos );
+ Menu* pTmpMenu = pCurrMenu->GetPopupMenu( nItemId );
+ if ( pTmpMenu != 0 )
+ pCurrMenu = pTmpMenu;
+ else
+ {
+ nPos = nTmpPos;
+ eResult = RP_MENUITEM_INSTEAD_OF_POPUPMENU_FOUND;
+ }
+ }
+ else
+ eResult = RP_POPUPMENU_NOT_FOUND;
+ }
+ i++;
+ }
+ while (( pCurrMenu != 0 ) && ( i < nCount ) && ( eResult == RP_OK ));
+
+ aResult.pPopupMenu = pCurrMenu;
+ aResult.nPos = nPos;
+ aResult.nLevel = nLevel;
+ aResult.eResult = eResult;
+
+ return aResult;
+}
+
+sal_uInt16 MenuBarMerger::FindMenuItem( const ::rtl::OUString& rCmd, Menu* pCurrMenu )
+{
+ for ( sal_uInt16 i = 0; i < pCurrMenu->GetItemCount(); i++ )
+ {
+ const sal_uInt16 nItemId = pCurrMenu->GetItemId( i );
+ if ( nItemId > 0 )
+ {
+ if ( rCmd == ::rtl::OUString( pCurrMenu->GetItemCommand( nItemId )))
+ return i;
+ }
+ }
+
+ return MENU_ITEM_NOTFOUND;
+}
+
+bool MenuBarMerger::CreateSubMenu(
+ Menu* pSubMenu,
+ sal_uInt16& nItemId,
+ const ::rtl::OUString& rModuleIdentifier,
+ const AddonMenuContainer& rAddonSubMenu )
+{
+ const sal_uInt32 nSize = rAddonSubMenu.size();
+ for ( sal_uInt32 i = 0; i < nSize; i++ )
+ {
+ const AddonMenuItem& rMenuItem = rAddonSubMenu[i];
+
+ if ( IsCorrectContext( rMenuItem.aContext, rModuleIdentifier ))
+ {
+ if ( rMenuItem.aURL.equalsAsciiL( SEPARATOR_STRING, SEPARATOR_STRING_LEN ))
+ {
+ pSubMenu->InsertSeparator( MENU_APPEND );
+ }
+ else
+ {
+ pSubMenu->InsertItem( nItemId, rMenuItem.aTitle, 0, MENU_APPEND );
+ pSubMenu->SetItemCommand( nItemId, rMenuItem.aURL );
+ if ( !rMenuItem.aSubMenu.empty() )
+ {
+ PopupMenu* pPopupMenu = new PopupMenu();
+ pSubMenu->SetPopupMenu( nItemId, pPopupMenu );
+ ++nItemId;
+
+ CreateSubMenu( pPopupMenu, nItemId, rModuleIdentifier, rMenuItem.aSubMenu );
+ }
+ else
+ ++nItemId;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool MenuBarMerger::MergeMenuItems(
+ Menu* pMenu,
+ sal_uInt16 nPos,
+ sal_uInt16 nModIndex,
+ sal_uInt16& nItemId,
+ const ::rtl::OUString& rModuleIdentifier,
+ const AddonMenuContainer& rAddonMenuItems )
+{
+ sal_uInt16 nIndex( 0 );
+ const sal_uInt32 nSize = rAddonMenuItems.size();
+ for ( sal_uInt32 i = 0; i < nSize; i++ )
+ {
+ const AddonMenuItem& rMenuItem = rAddonMenuItems[i];
+
+ if ( IsCorrectContext( rMenuItem.aContext, rModuleIdentifier ))
+ {
+ if ( rMenuItem.aURL.equalsAsciiL( SEPARATOR_STRING, SEPARATOR_STRING_LEN ))
+ {
+ pMenu->InsertSeparator( nPos+nModIndex+nIndex );
+ }
+ else
+ {
+ pMenu->InsertItem( nItemId, rMenuItem.aTitle, 0, nPos+nModIndex+nIndex );
+ pMenu->SetItemCommand( nItemId, rMenuItem.aURL );
+ if ( !rMenuItem.aSubMenu.empty() )
+ {
+ PopupMenu* pSubMenu = new PopupMenu();
+ pMenu->SetPopupMenu( nItemId, pSubMenu );
+ ++nItemId;
+
+ CreateSubMenu( pSubMenu, nItemId, rModuleIdentifier, rMenuItem.aSubMenu );
+ }
+ else
+ ++nItemId;
+ }
+ ++nIndex;
+ }
+ }
+
+ return true;
+}
+
+bool MenuBarMerger::ReplaceMenuItem(
+ Menu* pMenu,
+ sal_uInt16 nPos,
+ sal_uInt16& rItemId,
+ const ::rtl::OUString& rModuleIdentifier,
+ const AddonMenuContainer& rAddonMenuItems )
+{
+ // There is no replace available. Therfore we first have to
+ // remove the old menu entry,
+ pMenu->RemoveItem( nPos );
+
+ return MergeMenuItems( pMenu, nPos, 0, rItemId, rModuleIdentifier, rAddonMenuItems );
+}
+
+bool MenuBarMerger::RemoveMenuItems(
+ Menu* pMenu,
+ sal_uInt16 nPos,
+ const ::rtl::OUString& rMergeCommandParameter )
+{
+ const sal_uInt16 nParam( sal_uInt16( rMergeCommandParameter.toInt32() ));
+ sal_uInt16 nCount( 1 );
+
+ nCount = std::max( nParam, nCount );
+
+ sal_uInt16 i = 0;
+ while (( nPos < pMenu->GetItemCount() ) && ( i < nCount ))
+ {
+ pMenu->RemoveItem( nPos );
+ ++i;
+ }
+
+ return true;
+}
+
+bool MenuBarMerger::ProcessMergeOperation(
+ Menu* pMenu,
+ sal_uInt16 nPos,
+ sal_uInt16& nItemId,
+ const ::rtl::OUString& rMergeCommand,
+ const ::rtl::OUString& rMergeCommandParameter,
+ const ::rtl::OUString& rModuleIdentifier,
+ const AddonMenuContainer& rAddonMenuItems )
+{
+ sal_uInt16 nModIndex( 0 );
+
+ if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDBEFORE, MERGECOMMAND_ADDBEFORE_LEN ))
+ {
+ nModIndex = 0;
+ return MergeMenuItems( pMenu, nPos, nModIndex, nItemId, rModuleIdentifier, rAddonMenuItems );
+ }
+ else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDAFTER, MERGECOMMAND_ADDAFTER_LEN ))
+ {
+ nModIndex = 1;
+ return MergeMenuItems( pMenu, nPos, nModIndex, nItemId, rModuleIdentifier, rAddonMenuItems );
+ }
+ else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REPLACE, MERGECOMMAND_REPLACE_LEN ))
+ {
+ return ReplaceMenuItem( pMenu, nPos, nItemId, rModuleIdentifier, rAddonMenuItems );
+ }
+ else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REMOVE, MERGECOMMAND_REMOVE_LEN ))
+ {
+ return RemoveMenuItems( pMenu, nPos, rMergeCommandParameter );
+ }
+
+ return false;
+}
+
+bool MenuBarMerger::ProcessFallbackOperation(
+ const ReferencePathInfo& aRefPathInfo,
+ sal_uInt16& rItemId,
+ const ::rtl::OUString& rMergeCommand,
+ const ::rtl::OUString& rMergeFallback,
+ const ::std::vector< ::rtl::OUString >& rReferencePath,
+ const ::rtl::OUString& rModuleIdentifier,
+ const AddonMenuContainer& rAddonMenuItems )
+{
+ if (( rMergeFallback.equalsAsciiL( MERGEFALLBACK_IGNORE, MERGEFALLBACK_IGNORE_LEN )) ||
+ ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REPLACE, MERGECOMMAND_REPLACE_LEN )) ||
+ ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REMOVE, MERGECOMMAND_REMOVE_LEN )) )
+ {
+ return true;
+ }
+ else if ( rMergeFallback.equalsAsciiL( MERGEFALLBACK_ADDPATH, MERGEFALLBACK_ADDPATH_LEN ))
+ {
+ Menu* pCurrMenu( aRefPathInfo.pPopupMenu );
+ sal_Int32 nLevel( aRefPathInfo.nLevel );
+ const sal_Int32 nSize( rReferencePath.size() );
+ bool bFirstLevel( true );
+
+ while ( nLevel < nSize )
+ {
+ if ( nLevel == nSize-1 )
+ {
+ const sal_uInt32 nCount = rAddonMenuItems.size();
+ for ( sal_uInt32 i = 0; i < nCount; ++i )
+ {
+ const AddonMenuItem& rMenuItem = rAddonMenuItems[i];
+ if ( IsCorrectContext( rMenuItem.aContext, rModuleIdentifier ))
+ {
+ if ( rMenuItem.aURL.equalsAsciiL( SEPARATOR_STRING, SEPARATOR_STRING_LEN ))
+ pCurrMenu->InsertSeparator( MENU_APPEND );
+ else
+ {
+ pCurrMenu->InsertItem( rItemId, rMenuItem.aTitle, 0, MENU_APPEND );
+ pCurrMenu->SetItemCommand( rItemId, rMenuItem.aURL );
+ ++rItemId;
+ }
+ }
+ }
+ }
+ else
+ {
+ const ::rtl::OUString aCmd( rReferencePath[nLevel] );
+
+ sal_uInt16 nInsPos( MENU_APPEND );
+ PopupMenu* pPopupMenu( new PopupMenu );
+
+ if ( bFirstLevel && ( aRefPathInfo.eResult == RP_MENUITEM_INSTEAD_OF_POPUPMENU_FOUND ))
+ {
+ // special case: menu item without popup
+ nInsPos = aRefPathInfo.nPos;
+ sal_uInt16 nSetItemId = pCurrMenu->GetItemId( nInsPos );
+ pCurrMenu->SetItemCommand( nSetItemId, aCmd );
+ pCurrMenu->SetPopupMenu( nSetItemId, pPopupMenu );
+ }
+ else
+ {
+ // normal case: insert a new item with popup
+ pCurrMenu->InsertItem( rItemId, ::rtl::OUString(), 0, MENU_APPEND );
+ pCurrMenu->SetItemCommand( rItemId, aCmd );
+ pCurrMenu->SetPopupMenu( rItemId, pPopupMenu );
+ }
+
+ pCurrMenu = pPopupMenu;
+ ++rItemId;
+ bFirstLevel = false;
+ }
+ ++nLevel;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+void MenuBarMerger::GetMenuEntry(
+ const uno::Sequence< beans::PropertyValue >& rAddonMenuEntry,
+ AddonMenuItem& rAddonMenuItem )
+{
+ // Reset submenu member
+ rAddonMenuItem.aSubMenu.clear();
+
+ for ( sal_Int32 i = 0; i < rAddonMenuEntry.getLength(); i++ )
+ {
+ ::rtl::OUString aMenuEntryPropName = rAddonMenuEntry[i].Name;
+ if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_URL, ADDONSMENUITEM_URL_LEN ))
+ rAddonMenuEntry[i].Value >>= rAddonMenuItem.aURL;
+ else if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_TITLE, ADDONSMENUITEM_TITLE_LEN ))
+ rAddonMenuEntry[i].Value >>= rAddonMenuItem.aTitle;
+ else if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_TARGET, ADDONSMENUITEM_TARGET_LEN ))
+ rAddonMenuEntry[i].Value >>= rAddonMenuItem.aTarget;
+ else if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_SUBMENU, ADDONSMENUITEM_SUBMENU_LEN ))
+ {
+ uno::Sequence< uno::Sequence< beans::PropertyValue > > aSubMenu;
+ rAddonMenuEntry[i].Value >>= aSubMenu;
+ GetSubMenu( aSubMenu, rAddonMenuItem.aSubMenu );
+ }
+ else if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_CONTEXT, ADDONSMENUITEM_CONTEXT_LEN ))
+ rAddonMenuEntry[i].Value >>= rAddonMenuItem.aContext;
+ else if ( aMenuEntryPropName.equalsAsciiL( ADDONSMENUITEM_STRING_IMAGEIDENTIFIER, ADDONSMENUITEM_IMAGEIDENTIFIER_LEN ))
+ rAddonMenuEntry[i].Value >>= rAddonMenuItem.aImageId;
+ }
+}
+
+void MenuBarMerger::GetSubMenu(
+ const uno::Sequence< uno::Sequence< beans::PropertyValue > >& rSubMenuEntries,
+ AddonMenuContainer& rSubMenu )
+{
+ rSubMenu.clear();
+
+ const sal_Int32 nCount = rSubMenuEntries.getLength();
+ rSubMenu.reserve(rSubMenu.size() + nCount);
+ for ( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ const uno::Sequence< beans::PropertyValue >& rMenuEntry = rSubMenuEntries[ i ];
+
+ AddonMenuItem aMenuItem;
+ GetMenuEntry( rMenuEntry, aMenuItem );
+ rSubMenu.push_back( aMenuItem );
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/menubarwrapper.cxx b/framework/source/uielement/menubarwrapper.cxx
new file mode 100644
index 000000000000..cde049579711
--- /dev/null
+++ b/framework/source/uielement/menubarwrapper.cxx
@@ -0,0 +1,379 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uielement/menubarwrapper.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <framework/actiontriggerhelper.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
+#include <com/sun/star/awt/XMenuBar.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <comphelper/processfactory.hxx>
+#include <tools/solar.h>
+#include <vcl/svapp.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::awt;
+using namespace com::sun::star::util;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_11 ( MenuBarWrapper ,
+ UIConfigElementWrapperBase ,
+ DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIElement ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIElementSettings ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ),
+ DIRECT_INTERFACE( ::com::sun::star::lang::XInitialization ),
+ DIRECT_INTERFACE( ::com::sun::star::lang::XComponent ),
+ DIRECT_INTERFACE( ::com::sun::star::util::XUpdatable ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationListener ),
+ DERIVED_INTERFACE( ::com::sun::star::container::XNameAccess, ::com::sun::star::container::XElementAccess )
+ )
+
+DEFINE_XTYPEPROVIDER_11 ( MenuBarWrapper ,
+ ::com::sun::star::lang::XTypeProvider ,
+ ::com::sun::star::ui::XUIElement ,
+ ::com::sun::star::ui::XUIElementSettings ,
+ ::com::sun::star::beans::XMultiPropertySet ,
+ ::com::sun::star::beans::XFastPropertySet ,
+ ::com::sun::star::beans::XPropertySet ,
+ ::com::sun::star::lang::XInitialization ,
+ ::com::sun::star::lang::XComponent ,
+ ::com::sun::star::util::XUpdatable ,
+ ::com::sun::star::ui::XUIConfigurationListener ,
+ ::com::sun::star::container::XNameAccess
+ )
+
+MenuBarWrapper::MenuBarWrapper(
+ const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager
+ )
+: UIConfigElementWrapperBase( UIElementType::MENUBAR,xServiceManager ),
+ m_bRefreshPopupControllerCache( sal_True )
+{
+}
+
+MenuBarWrapper::~MenuBarWrapper()
+{
+}
+
+void SAL_CALL MenuBarWrapper::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ com::sun::star::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ ResetableGuard aLock( m_aLock );
+
+ m_xMenuBarManager->dispose();
+ m_xMenuBarManager.clear();
+ m_xConfigSource.clear();
+ m_xConfigData.clear();
+
+ m_xMenuBar.clear();
+ m_bDisposed = sal_True;
+}
+
+// XInitialization
+void SAL_CALL MenuBarWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarWrapper::initialize" );
+
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( !m_bInitialized )
+ {
+ rtl::OUString aModuleIdentifier;
+ UIConfigElementWrapperBase::initialize( aArguments );
+
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ if ( xFrame.is() && m_xConfigSource.is() )
+ {
+ // Create VCL menubar which will be filled with settings data
+ MenuBar* pVCLMenuBar = 0;
+ VCLXMenuBar* pAwtMenuBar = 0;
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ pVCLMenuBar = new MenuBar();
+ }
+
+ Reference< XModuleManager > xModuleManager;
+ xModuleManager = Reference< XModuleManager >(
+ m_xServiceFactory->createInstance(
+ SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
+
+ try
+ {
+ aModuleIdentifier = xModuleManager->identify( xFrame );
+ }
+ catch( Exception& )
+ {
+ }
+
+ Reference< XURLTransformer > xTrans;
+ try
+ {
+ xTrans.set( m_xServiceFactory->createInstance(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.util.URLTransformer" ))), UNO_QUERY );
+ m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
+ if ( m_xConfigData.is() )
+ {
+ // Fill menubar with container contents
+ sal_uInt16 nId = 1;
+ MenuBarManager::FillMenuWithConfiguration( nId, pVCLMenuBar, aModuleIdentifier, m_xConfigData, xTrans );
+ }
+ }
+ catch ( NoSuchElementException& )
+ {
+ }
+
+ sal_Bool bMenuOnly( sal_False );
+ for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
+ {
+ PropertyValue aPropValue;
+ if ( aArguments[n] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("MenuOnly")) )
+ aPropValue.Value >>= bMenuOnly;
+ }
+ }
+
+ if ( !bMenuOnly )
+ {
+ // Initialize menubar manager with our vcl menu bar. There are some situations where we only want to get the menu without any
+ // interaction which is done by the menu bar manager. This must be requested by a special property called "MenuOnly". Be careful
+ // a menu bar created with this property is not fully supported. It must be attached to a real menu bar manager to have full
+ // support. This feature is currently used for "Inplace editing"!
+ Reference< XDispatchProvider > xDispatchProvider;
+
+ MenuBarManager* pMenuBarManager = new MenuBarManager( m_xServiceFactory,
+ xFrame,
+ xTrans,
+ xDispatchProvider,
+ aModuleIdentifier,
+ pVCLMenuBar,
+ sal_False,
+ sal_True );
+
+ m_xMenuBarManager = Reference< XComponent >( static_cast< OWeakObject *>( pMenuBarManager ), UNO_QUERY );
+ }
+
+ // Initialize toolkit menu bar implementation to have awt::XMenuBar for data exchange.
+ // Don't use this toolkit menu bar or one of its functions. It is only used as a data container!
+ pAwtMenuBar = new VCLXMenuBar( pVCLMenuBar );
+ m_xMenuBar = Reference< XMenuBar >( static_cast< OWeakObject *>( pAwtMenuBar ), UNO_QUERY );
+ }
+ }
+}
+
+// XUIElementSettings
+void SAL_CALL MenuBarWrapper::updateSettings() throw ( RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xMenuBarManager.is() )
+ {
+ if ( m_xConfigSource.is() && m_bPersistent )
+ {
+ try
+ {
+ MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );
+
+ m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
+ if ( m_xConfigData.is() )
+ pMenuBarManager->SetItemContainer( m_xConfigData );
+ }
+ catch ( NoSuchElementException& )
+ {
+ }
+ }
+ else if ( !m_bPersistent )
+ {
+ // Transient menubar: do nothing
+ }
+ }
+}
+void MenuBarWrapper::impl_fillNewData()
+{
+ // Transient menubar => Fill menubar with new data
+ MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );
+
+ if ( pMenuBarManager )
+ pMenuBarManager->SetItemContainer( m_xConfigData );
+}
+
+
+void MenuBarWrapper::fillPopupControllerCache()
+{
+ if ( m_bRefreshPopupControllerCache )
+ {
+ MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );
+ if ( pMenuBarManager )
+ pMenuBarManager->GetPopupController( m_aPopupControllerCache );
+ if ( !m_aPopupControllerCache.empty() )
+ m_bRefreshPopupControllerCache = sal_False;
+ }
+}
+
+// XElementAccess
+Type SAL_CALL MenuBarWrapper::getElementType()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return ::getCppuType(( Reference< XDispatchProvider >*)0);
+}
+
+::sal_Bool SAL_CALL MenuBarWrapper::hasElements()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ fillPopupControllerCache();
+ return ( !m_aPopupControllerCache.empty() );
+}
+
+// XNameAccess
+Any SAL_CALL MenuBarWrapper::getByName(
+ const ::rtl::OUString& aName )
+throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ fillPopupControllerCache();
+
+ PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName );
+ if ( pIter != m_aPopupControllerCache.end() )
+ {
+ uno::Reference< frame::XDispatchProvider > xDispatchProvider;
+ xDispatchProvider = pIter->second.m_xDispatchProvider;
+ return uno::makeAny( xDispatchProvider );
+ }
+ else
+ throw container::NoSuchElementException();
+}
+
+Sequence< ::rtl::OUString > SAL_CALL MenuBarWrapper::getElementNames()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ fillPopupControllerCache();
+
+ Sequence< rtl::OUString > aSeq( m_aPopupControllerCache.size() );
+
+ sal_Int32 i( 0 );
+ PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.begin();
+ while ( pIter != m_aPopupControllerCache.end() )
+ {
+ aSeq[i++] = pIter->first;
+ ++pIter;
+ }
+
+ return aSeq;
+}
+
+::sal_Bool SAL_CALL MenuBarWrapper::hasByName(
+ const ::rtl::OUString& aName )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ fillPopupControllerCache();
+
+ PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName );
+ if ( pIter != m_aPopupControllerCache.end() )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+// XUIElement
+Reference< XInterface > SAL_CALL MenuBarWrapper::getRealInterface() throw ( RuntimeException )
+{
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ return Reference< XInterface >( m_xMenuBarManager, UNO_QUERY );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/newmenucontroller.cxx b/framework/source/uielement/newmenucontroller.cxx
new file mode 100644
index 000000000000..ea8eaa3afd44
--- /dev/null
+++ b/framework/source/uielement/newmenucontroller.cxx
@@ -0,0 +1,579 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/newmenucontroller.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+#include <classes/resource.hrc>
+#include <classes/fwkresid.hxx>
+#include <framework/bmkmenu.hxx>
+#include <framework/imageproducer.hxx>
+#include <framework/menuconfiguration.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <osl/file.hxx>
+#include <svtools/menuoptions.hxx>
+#include <svtools/acceleratorexecute.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <dispatch/uieventloghelper.hxx>
+#include <osl/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::container;
+using namespace com::sun::star::ui;
+
+static const char SFX_REFERER_USER[] = "private:user";
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( NewMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_NEWMENUCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( NewMenuController, {} )
+
+void NewMenuController::setMenuImages( PopupMenu* pPopupMenu, sal_Bool bSetImages )
+{
+ sal_uInt16 nItemCount = pPopupMenu->GetItemCount();
+ Image aImage;
+ Reference< XFrame > xFrame( m_xFrame );
+
+ for ( sal_uInt16 i = 0; i < nItemCount; i++ )
+ {
+ sal_uInt16 nItemId = pPopupMenu->GetItemId( sal::static_int_cast<sal_uInt16>( i ));
+ if ( nItemId != 0 )
+ {
+ if ( bSetImages )
+ {
+ sal_Bool bImageSet( sal_False );
+ ::rtl::OUString aImageId;
+
+ AddInfoForId::const_iterator pInfo = m_aAddInfoForItem.find( nItemId );
+ if ( pInfo != m_aAddInfoForItem.end() )
+ aImageId = pInfo->second.aImageId; // Retrieve image id for menu item
+
+ if ( aImageId.getLength() > 0 )
+ {
+ aImage = GetImageFromURL( xFrame, aImageId, false );
+ if ( !!aImage )
+ {
+ bImageSet = sal_True;
+ pPopupMenu->SetItemImage( nItemId, aImage );
+ }
+ }
+
+ if ( !bImageSet )
+ {
+ String aCmd( pPopupMenu->GetItemCommand( nItemId ) );
+ if ( aCmd.Len() )
+ aImage = GetImageFromURL( xFrame, aCmd, false );
+
+ if ( !!aImage )
+ pPopupMenu->SetItemImage( nItemId, aImage );
+ }
+ }
+ else
+ pPopupMenu->SetItemImage( nItemId, aImage );
+ }
+ }
+}
+
+void NewMenuController::determineAndSetNewDocAccel( PopupMenu* pPopupMenu, const KeyCode& rKeyCode )
+{
+ sal_uInt16 nCount( pPopupMenu->GetItemCount() );
+ sal_uInt16 nId( 0 );
+ sal_Bool bFound( sal_False );
+ rtl::OUString aCommand;
+
+ if ( m_aEmptyDocURL.getLength() > 0 )
+ {
+ // Search for the empty document URL
+
+ for ( sal_uInt32 i = 0; i < sal_uInt32( nCount ); i++ )
+ {
+ nId = pPopupMenu->GetItemId( sal_uInt16( i ));
+ if ( nId != 0 && pPopupMenu->GetItemType( nId ) != MENUITEM_SEPARATOR )
+ {
+ aCommand = pPopupMenu->GetItemCommand( nId );
+ if ( aCommand.indexOf( m_aEmptyDocURL ) == 0 )
+ {
+ pPopupMenu->SetAccelKey( nId, rKeyCode );
+ bFound = sal_True;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !bFound )
+ {
+ // Search for the default module name
+ rtl::OUString aDefaultModuleName( SvtModuleOptions().GetDefaultModuleName() );
+ if ( aDefaultModuleName.getLength() > 0 )
+ {
+ for ( sal_uInt32 i = 0; i < sal_uInt32( nCount ); i++ )
+ {
+ nId = pPopupMenu->GetItemId( sal_uInt16( i ));
+ if ( nId != 0 && pPopupMenu->GetItemType( nId ) != MENUITEM_SEPARATOR )
+ {
+ aCommand = pPopupMenu->GetItemCommand( nId );
+ if ( aCommand.indexOf( aDefaultModuleName ) >= 0 )
+ {
+ pPopupMenu->SetAccelKey( nId, rKeyCode );
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void NewMenuController::setAccelerators( PopupMenu* pPopupMenu )
+{
+ if ( m_bModuleIdentified )
+ {
+ Reference< XAcceleratorConfiguration > xDocAccelCfg( m_xDocAcceleratorManager );
+ Reference< XAcceleratorConfiguration > xModuleAccelCfg( m_xModuleAcceleratorManager );
+ Reference< XAcceleratorConfiguration > xGlobalAccelCfg( m_xGlobalAcceleratorManager );
+
+ if ( !m_bAcceleratorCfg )
+ {
+ // Retrieve references on demand
+ m_bAcceleratorCfg = sal_True;
+ if ( !xDocAccelCfg.is() )
+ {
+ Reference< XController > xController = m_xFrame->getController();
+ Reference< XModel > xModel;
+ if ( xController.is() )
+ {
+ xModel = xController->getModel();
+ if ( xModel.is() )
+ {
+ Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
+ if ( xSupplier.is() )
+ {
+ Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY );
+ if ( xDocUICfgMgr.is() )
+ {
+ xDocAccelCfg = Reference< XAcceleratorConfiguration >( xDocUICfgMgr->getShortCutManager(), UNO_QUERY );
+ m_xDocAcceleratorManager = xDocAccelCfg;
+ }
+ }
+ }
+ }
+ }
+
+ if ( !xModuleAccelCfg.is() )
+ {
+ Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( m_xServiceManager->createInstance(
+ SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ),
+ UNO_QUERY );
+ Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
+ if ( xUICfgMgr.is() )
+ {
+ xModuleAccelCfg = Reference< XAcceleratorConfiguration >( xUICfgMgr->getShortCutManager(), UNO_QUERY );
+ m_xModuleAcceleratorManager = xModuleAccelCfg;
+ }
+ }
+
+ if ( !xGlobalAccelCfg.is() )
+ {
+ xGlobalAccelCfg = Reference< XAcceleratorConfiguration >( m_xServiceManager->createInstance(
+ SERVICENAME_GLOBALACCELERATORCONFIGURATION ),
+ UNO_QUERY );
+ m_xGlobalAcceleratorManager = xGlobalAccelCfg;
+ }
+ }
+
+ KeyCode aEmptyKeyCode;
+ sal_uInt32 nItemCount( pPopupMenu->GetItemCount() );
+ std::vector< KeyCode > aMenuShortCuts;
+ std::vector< rtl::OUString > aCmds;
+ std::vector< sal_uInt32 > aIds;
+ for ( sal_uInt32 i = 0; i < nItemCount; i++ )
+ {
+ sal_uInt16 nId( pPopupMenu->GetItemId( sal_uInt16( i )));
+ if ( nId & ( pPopupMenu->GetItemType( nId ) != MENUITEM_SEPARATOR ))
+ {
+ aIds.push_back( nId );
+ aMenuShortCuts.push_back( aEmptyKeyCode );
+ aCmds.push_back( pPopupMenu->GetItemCommand( nId ));
+ }
+ }
+
+ sal_uInt32 nSeqCount( aIds.size() );
+
+ if ( m_bNewMenu )
+ nSeqCount+=1;
+
+ Sequence< rtl::OUString > aSeq( nSeqCount );
+
+ // Add a special command for our "New" menu.
+ if ( m_bNewMenu )
+ {
+ aSeq[nSeqCount-1] = m_aCommandURL;
+ aMenuShortCuts.push_back( aEmptyKeyCode );
+ }
+
+ const sal_uInt32 nCount = aCmds.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ aSeq[i] = aCmds[i];
+
+ if ( m_xGlobalAcceleratorManager.is() )
+ retrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts );
+ if ( m_xModuleAcceleratorManager.is() )
+ retrieveShortcutsFromConfiguration( xModuleAccelCfg, aSeq, aMenuShortCuts );
+ if ( m_xDocAcceleratorManager.is() )
+ retrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts );
+
+ const sal_uInt32 nCount2 = aIds.size();
+ for ( sal_uInt32 i = 0; i < nCount2; i++ )
+ pPopupMenu->SetAccelKey( sal_uInt16( aIds[i] ), aMenuShortCuts[i] );
+
+ // Special handling for "New" menu short-cut should be set at the
+ // document which will be opened using it.
+ if ( m_bNewMenu )
+ {
+ if ( aMenuShortCuts[nSeqCount-1] != aEmptyKeyCode )
+ determineAndSetNewDocAccel( pPopupMenu, aMenuShortCuts[nSeqCount-1] );
+ }
+ }
+}
+
+void NewMenuController::retrieveShortcutsFromConfiguration(
+ const Reference< XAcceleratorConfiguration >& rAccelCfg,
+ const Sequence< rtl::OUString >& rCommands,
+ std::vector< KeyCode >& aMenuShortCuts )
+{
+ if ( rAccelCfg.is() )
+ {
+ try
+ {
+ com::sun::star::awt::KeyEvent aKeyEvent;
+ Sequence< Any > aSeqKeyCode = rAccelCfg->getPreferredKeyEventsForCommandList( rCommands );
+ for ( sal_Int32 i = 0; i < aSeqKeyCode.getLength(); i++ )
+ {
+ if ( aSeqKeyCode[i] >>= aKeyEvent )
+ aMenuShortCuts[i] = svt::AcceleratorExecute::st_AWTKey2VCLKey( aKeyEvent );
+ }
+ }
+ catch ( IllegalArgumentException& )
+ {
+ }
+ }
+}
+
+NewMenuController::NewMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::PopupMenuControllerBase( xServiceManager ),
+ m_bShowImages( sal_True ),
+ m_bNewMenu( sal_False ),
+ m_bModuleIdentified( sal_False ),
+ m_bAcceleratorCfg( sal_False ),
+ m_aTargetFrame( RTL_CONSTASCII_USTRINGPARAM( "_default" ))
+{
+}
+
+NewMenuController::~NewMenuController()
+{
+}
+
+// private function
+void NewMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
+{
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ PopupMenu* pVCLPopupMenu = 0;
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ resetPopupMenu( rPopupMenu );
+ if ( pPopupMenu )
+ pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+
+ if ( pVCLPopupMenu )
+ {
+ MenuConfiguration aMenuCfg( m_xServiceManager );
+ BmkMenu* pSubMenu( 0 );
+
+ if ( m_bNewMenu )
+ pSubMenu = (BmkMenu*)aMenuCfg.CreateBookmarkMenu( m_xFrame, BOOKMARK_NEWMENU );
+ else
+ pSubMenu = (BmkMenu*)aMenuCfg.CreateBookmarkMenu( m_xFrame, BOOKMARK_WIZARDMENU );
+
+ // copy entries as we have to use the provided popup menu
+ *pVCLPopupMenu = *pSubMenu;
+
+ Image aImage;
+ AddInfo aAddInfo;
+
+ // retrieve additional parameters from bookmark menu and
+ // store it in a boost::unordered_map.
+ for ( sal_uInt16 i = 0; i < pSubMenu->GetItemCount(); i++ )
+ {
+ sal_uInt16 nItemId = pSubMenu->GetItemId( sal::static_int_cast<sal_uInt16>( i ) );
+ if (( nItemId != 0 ) &&
+ ( pSubMenu->GetItemType( nItemId ) != MENUITEM_SEPARATOR ))
+ {
+ MenuConfiguration::Attributes* pBmkAttributes = (MenuConfiguration::Attributes *)(pSubMenu->GetUserValue( nItemId ));
+ if ( pBmkAttributes != 0 )
+ {
+ aAddInfo.aTargetFrame = pBmkAttributes->aTargetFrame;
+ aAddInfo.aImageId = pBmkAttributes->aImageId;
+
+ m_aAddInfoForItem.insert( AddInfoForId::value_type( nItemId, aAddInfo ));
+ }
+ }
+ }
+
+ if ( m_bShowImages )
+ setMenuImages( pVCLPopupMenu, m_bShowImages );
+
+ delete pSubMenu;
+ }
+}
+
+// XEventListener
+void SAL_CALL NewMenuController::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
+
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xServiceManager.clear();
+
+ if ( m_xPopupMenu.is() )
+ m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
+ m_xPopupMenu.clear();
+}
+
+// XStatusListener
+void SAL_CALL NewMenuController::statusChanged( const FeatureStateEvent& ) throw ( RuntimeException )
+{
+}
+
+// XMenuListener
+void SAL_CALL NewMenuController::select( const css::awt::MenuEvent& rEvent ) throw (RuntimeException)
+{
+ Reference< css::awt::XPopupMenu > xPopupMenu;
+ Reference< XDispatch > xDispatch;
+ Reference< XDispatchProvider > xDispatchProvider;
+ Reference< XMultiServiceFactory > xServiceManager;
+ Reference< XURLTransformer > xURLTransformer;
+
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ xPopupMenu = m_xPopupMenu;
+ xDispatchProvider = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY );
+ xServiceManager = m_xServiceManager;
+ xURLTransformer = m_xURLTransformer;
+ aLock.clear();
+
+ css::util::URL aTargetURL;
+ Sequence< PropertyValue > aArgsList( 1 );
+
+ if ( xPopupMenu.is() && xDispatchProvider.is() )
+ {
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( xPopupMenu );
+ if ( pPopupMenu )
+ {
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+ aTargetURL.Complete = pVCLPopupMenu->GetItemCommand( rEvent.MenuId );
+ }
+
+ xURLTransformer->parseStrict( aTargetURL );
+
+ aArgsList[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
+ aArgsList[0].Value = makeAny( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER )));
+
+ rtl::OUString aTargetFrame( m_aTargetFrame );
+ AddInfoForId::const_iterator pItem = m_aAddInfoForItem.find( rEvent.MenuId );
+ if ( pItem != m_aAddInfoForItem.end() )
+ aTargetFrame = pItem->second.aTargetFrame;
+
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, aTargetFrame, 0 );
+ }
+ }
+
+ if ( xDispatch.is() )
+ {
+ // Call dispatch asychronously as we can be destroyed while dispatch is
+ // executed. VCL is not able to survive this as it wants to call listeners
+ // after select!!!
+ NewDocument* pNewDocument = new NewDocument;
+ pNewDocument->xDispatch = xDispatch;
+ pNewDocument->aTargetURL = aTargetURL;
+ pNewDocument->aArgSeq = aArgsList;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NewMenuController"))).log(m_xServiceManager, m_xFrame, aTargetURL, aArgsList);
+ Application::PostUserEvent( STATIC_LINK(0, NewMenuController, ExecuteHdl_Impl), pNewDocument );
+ }
+}
+
+void SAL_CALL NewMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException)
+{
+ SolarMutexGuard aSolarMutexGuard;
+ if ( m_xFrame.is() && m_xPopupMenu.is() )
+ {
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( m_xPopupMenu );
+ if ( pPopupMenu )
+ {
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ sal_Bool bShowImages( rSettings.GetUseImagesInMenus() );
+
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+
+ if ( m_bShowImages != bShowImages )
+ {
+ m_bShowImages = bShowImages;
+ setMenuImages( pVCLPopupMenu, m_bShowImages );
+ }
+
+ setAccelerators( pVCLPopupMenu );
+ }
+ }
+}
+
+// XPopupMenuController
+void NewMenuController::impl_setPopupMenu()
+{
+
+ if ( m_xPopupMenu.is() )
+ fillPopupMenu( m_xPopupMenu );
+
+ // Identify module that we are attach to. It's our context that we need to know.
+ Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ),UNO_QUERY );
+ if ( xModuleManager.is() )
+ {
+ try
+ {
+ m_aModuleIdentifier = xModuleManager->identify( m_xFrame );
+ m_bModuleIdentified = sal_True;
+
+ Reference< XNameAccess > xNameAccess( xModuleManager, UNO_QUERY );
+ if (( m_aModuleIdentifier.getLength() > 0 ) && xNameAccess.is() )
+ {
+ Sequence< PropertyValue > aSeq;
+
+ if ( xNameAccess->getByName( m_aModuleIdentifier ) >>= aSeq )
+ {
+ for ( sal_Int32 y = 0; y < aSeq.getLength(); y++ )
+ {
+ if ( aSeq[y].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ooSetupFactoryEmptyDocumentURL")) )
+ {
+ aSeq[y].Value >>= m_aEmptyDocURL;
+ break;
+ }
+ }
+ }
+ }
+ }
+ catch ( RuntimeException& e )
+ {
+ throw e;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+// XInitialization
+void SAL_CALL NewMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ sal_Bool bInitalized( m_bInitialized );
+ if ( !bInitalized )
+ {
+ svt::PopupMenuControllerBase::initialize( aArguments );
+
+ if ( m_bInitialized )
+ {
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+
+ m_bShowImages = rSettings.GetUseImagesInMenus();
+ m_bNewMenu = m_aCommandURL.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ".uno:AddDirect" ) );
+ }
+ }
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( NewMenuController, ExecuteHdl_Impl, NewDocument*, pNewDocument )
+{
+/* i62706: Don't catch all exceptions. We hide all problems here and are not able
+ to handle them on higher levels.
+ try
+ {
+*/
+ // Asynchronous execution as this can lead to our own destruction!
+ // Framework can recycle our current frame and the layout manager disposes all user interface
+ // elements if a component gets detached from its frame!
+ pNewDocument->xDispatch->dispatch( pNewDocument->aTargetURL, pNewDocument->aArgSeq );
+ delete pNewDocument;
+ return 0;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/objectmenucontroller.cxx b/framework/source/uielement/objectmenucontroller.cxx
new file mode 100644
index 000000000000..1728fe17dc06
--- /dev/null
+++ b/framework/source/uielement/objectmenucontroller.cxx
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/objectmenucontroller.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+
+#include <com/sun/star/embed/VerbAttributes.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <dispatch/uieventloghelper.hxx>
+#include <osl/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( ObjectMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_OBJECTMENUCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( ObjectMenuController, {} )
+
+ObjectMenuController::ObjectMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::PopupMenuControllerBase( xServiceManager )
+{
+}
+
+ObjectMenuController::~ObjectMenuController()
+{
+}
+
+// private function
+void ObjectMenuController::fillPopupMenu( const Sequence< com::sun::star::embed::VerbDescriptor >& rVerbCommandSeq, Reference< css::awt::XPopupMenu >& rPopupMenu )
+{
+ const com::sun::star::embed::VerbDescriptor* pVerbCommandArray = rVerbCommandSeq.getConstArray();
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ PopupMenu* pVCLPopupMenu = 0;
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ resetPopupMenu( rPopupMenu );
+ if ( pPopupMenu )
+ pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+
+ if ( pVCLPopupMenu )
+ {
+ const rtl::OUString aVerbCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:ObjectMenue?VerbID:short=" ));
+ for ( sal_uInt16 i = 0; i < rVerbCommandSeq.getLength(); i++ )
+ {
+ const com::sun::star::embed::VerbDescriptor& rVerb = pVerbCommandArray[i];
+ if ( rVerb.VerbAttributes & com::sun::star::embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU )
+ {
+ m_xPopupMenu->insertItem( i+1, rVerb.VerbName, 0, i );
+ // use VCL popup menu pointer to set vital information that are not part of the awt implementation
+
+ rtl::OUString aCommand( aVerbCommand );
+ aCommand += rtl::OUString::valueOf( rVerb.VerbID );
+ pVCLPopupMenu->SetItemCommand( i+1, aCommand ); // Store verb command
+ }
+ }
+ }
+}
+
+// XEventListener
+void SAL_CALL ObjectMenuController::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
+
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xObjectUpdateDispatch.clear();
+ m_xServiceManager.clear();
+
+ if ( m_xPopupMenu.is() )
+ m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
+ m_xPopupMenu.clear();
+}
+
+// XStatusListener
+void SAL_CALL ObjectMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
+{
+ Sequence < com::sun::star::embed::VerbDescriptor > aVerbCommandSeq;
+ if ( Event.State >>= aVerbCommandSeq )
+ {
+ osl::MutexGuard aLock( m_aMutex );
+ if ( m_xPopupMenu.is() )
+ fillPopupMenu( aVerbCommandSeq, m_xPopupMenu );
+ }
+}
+
+// XMenuListener
+void ObjectMenuController::impl_select(const Reference< XDispatch >& _xDispatch,const ::com::sun::star::util::URL& aTargetURL)
+{
+ Sequence<PropertyValue> aArgs;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ObjectMenuController"))).log(m_xServiceManager, m_xFrame, aTargetURL, aArgs);
+ OSL_ENSURE(_xDispatch.is(),"ObjectMenuController::impl_select: No dispatch");
+ if ( _xDispatch.is() )
+ _xDispatch->dispatch( aTargetURL, aArgs );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/panelwindow.cxx b/framework/source/uielement/panelwindow.cxx
new file mode 100644
index 000000000000..c8729dbb028d
--- /dev/null
+++ b/framework/source/uielement/panelwindow.cxx
@@ -0,0 +1,77 @@
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <uielement/panelwindow.hxx>
+
+namespace framework
+{
+
+PanelWindow::PanelWindow( Window* pParent, WinBits nWinBits ) :
+ DockingWindow( pParent, nWinBits )
+{
+}
+
+PanelWindow::~PanelWindow()
+{
+}
+
+const ::rtl::OUString& PanelWindow::getResourceURL() const
+{
+ return m_aResourceURL;
+}
+
+void PanelWindow::setResourceURL(const ::rtl::OUString& rResourceURL)
+{
+ m_aResourceURL = rResourceURL;
+}
+
+Window* PanelWindow::getContentWindow() const
+{
+ return m_pContentWindow;
+}
+
+void PanelWindow::setContentWindow( Window* pContentWindow )
+{
+ m_pContentWindow = pContentWindow;
+ if ( m_pContentWindow != NULL )
+ {
+ m_pContentWindow->SetParent(this);
+ m_pContentWindow->SetSizePixel( GetOutputSizePixel() );
+ m_pContentWindow->Show();
+ }
+}
+
+void PanelWindow::Command( const CommandEvent& rCEvt )
+{
+ if ( m_aCommandHandler.IsSet() )
+ m_aCommandHandler.Call( (void *)( &rCEvt ));
+ DockingWindow::Command( rCEvt );
+}
+
+void PanelWindow::StateChanged( StateChangedType nType )
+{
+ DockingWindow::StateChanged( nType );
+ if ( m_aStateChangedHandler.IsSet() )
+ m_aStateChangedHandler.Call( &nType );
+}
+
+void PanelWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ DockingWindow::DataChanged( rDCEvt );
+ if ( m_aDataChangedHandler.IsSet() )
+ m_aDataChangedHandler.Call( (void*)&rDCEvt );
+}
+
+void PanelWindow::Resize()
+{
+ DockingWindow::Resize();
+ if ( m_pContentWindow )
+ m_pContentWindow->SetSizePixel( GetOutputSizePixel() );
+}
+
+}
diff --git a/framework/source/uielement/panelwrapper.cxx b/framework/source/uielement/panelwrapper.cxx
new file mode 100644
index 000000000000..2587f629b6e1
--- /dev/null
+++ b/framework/source/uielement/panelwrapper.cxx
@@ -0,0 +1,226 @@
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <services.h>
+#include <uielement/panelwrapper.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <uielement/constitemcontainer.hxx>
+#include <uielement/rootitemcontainer.hxx>
+#include <uielement/panelwindow.hxx>
+#include <services/modelwinservice.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
+#include <com/sun/star/awt/XMenuBar.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <toolkit/unohlp.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <comphelper/processfactory.hxx>
+#include <svtools/miscopt.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::awt;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+PanelWrapper::PanelWrapper( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ UIElementWrapperBase( UIElementType::DOCKINGWINDOW ),
+ m_xServiceManager( xServiceManager ),
+ m_bNoClose(false)
+{
+}
+
+PanelWrapper::~PanelWrapper()
+{
+}
+
+// XInterface
+void SAL_CALL PanelWrapper::acquire() throw()
+{
+ UIElementWrapperBase::acquire();
+}
+
+void SAL_CALL PanelWrapper::release() throw()
+{
+ UIElementWrapperBase::release();
+}
+
+uno::Any SAL_CALL PanelWrapper::queryInterface( const uno::Type & rType )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ return UIElementWrapperBase::queryInterface( rType );
+}
+
+// XComponent
+void SAL_CALL PanelWrapper::dispose() throw ( RuntimeException )
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+ Reference< XMultiServiceFactory > xSMGR( m_xServiceManager );
+ Reference< XWindow > xWindow;
+
+ {
+ ResetableGuard aLock( m_aLock );
+ if ( m_bDisposed )
+ return;
+ xSMGR = m_xServiceManager;
+ }
+
+ com::sun::star::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ rtl::OUString aModelWinService( SERVICENAME_MODELWINSERVICE );
+ Reference< XNameAccess > xNameAccess( xSMGR->createInstance( aModelWinService ), UNO_QUERY );
+ if ( xNameAccess.is() )
+ {
+ ModelWinService* pService = dynamic_cast< ModelWinService* >( xNameAccess.get() );
+ if ( pService != 0 )
+ {
+ SolarMutexGuard aGuard;
+ PanelWindow* pPanelWindow = dynamic_cast< PanelWindow* >( m_xPanelWindow.get() );
+ if ( pPanelWindow != NULL )
+ {
+ xWindow = VCLUnoHelper::GetInterface( pPanelWindow->getContentWindow() );
+ pService->deregisterModelForXWindow( xWindow );
+ }
+ }
+ }
+
+ ResetableGuard aLock( m_aLock );
+ m_xPanelWindow.clear();
+ m_bDisposed = sal_True;
+}
+
+// XInitialization
+void SAL_CALL PanelWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( !m_bInitialized )
+ {
+ UIElementWrapperBase::initialize( aArguments );
+
+ sal_Bool bPopupMode( sal_False );
+ Reference< XWindow > xContentWindow;
+ for ( sal_Int32 i = 0; i < aArguments.getLength(); i++ )
+ {
+ PropertyValue aPropValue;
+ if ( aArguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAsciiL( "PopupMode", 9 ))
+ aPropValue.Value >>= bPopupMode;
+ else if ( aPropValue.Name.equalsAsciiL( "ContentWindow", 13 ))
+ aPropValue.Value >>= xContentWindow;
+ }
+ }
+
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ if ( xFrame.is() )
+ {
+ PanelWindow* pPanelWindow(0);
+ Window* pContentWindow(0);
+ {
+ SolarMutexGuard aGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ pContentWindow = VCLUnoHelper::GetWindow( xContentWindow );
+ if ( pWindow )
+ {
+ sal_uInt32 nStyles = WB_LINESPACING | WB_BORDER | WB_SCROLL | WB_MOVEABLE | WB_3DLOOK | WB_DOCKABLE | WB_SIZEABLE | WB_CLOSEABLE;
+
+ pPanelWindow = new PanelWindow( pWindow, nStyles );
+ m_xPanelWindow = VCLUnoHelper::GetInterface( pPanelWindow );
+ pPanelWindow->setResourceURL( m_aResourceURL );
+ pPanelWindow->setContentWindow( pContentWindow );
+ }
+ }
+
+ try
+ {
+ }
+ catch ( NoSuchElementException& )
+ {
+ }
+ }
+ }
+}
+
+// XEventListener
+void SAL_CALL PanelWrapper::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ // nothing todo
+}
+
+// XUpdatable
+void SAL_CALL PanelWrapper::update() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+}
+
+// XUIElement interface
+Reference< XInterface > SAL_CALL PanelWrapper::getRealInterface( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+ return m_xPanelWindow;
+}
+
+void SAL_CALL PanelWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const com::sun::star::uno::Any& aValue ) throw( com::sun::star::uno::Exception )
+{
+ ResetableGuard aLock( m_aLock );
+ sal_Bool bNoClose( m_bNoClose );
+ aLock.unlock();
+
+ UIElementWrapperBase::setFastPropertyValue_NoBroadcast( nHandle, aValue );
+
+ aLock.lock();
+
+ sal_Bool bNewNoClose( m_bNoClose );
+ if ( m_xPanelWindow.is() && !m_bDisposed && ( bNewNoClose != bNoClose ))
+ {
+ PanelWindow* pPanelWindow = dynamic_cast< PanelWindow* >( VCLUnoHelper::GetWindow( m_xPanelWindow ) );
+ if ( pPanelWindow )
+ {
+ if ( bNewNoClose )
+ {
+ pPanelWindow->SetStyle( pPanelWindow->GetStyle() & ~WB_CLOSEABLE );
+ pPanelWindow->SetFloatStyle( pPanelWindow->GetFloatStyle() & ~WB_CLOSEABLE );
+ }
+ else
+ {
+ pPanelWindow->SetStyle( pPanelWindow->GetStyle() | WB_CLOSEABLE );
+ pPanelWindow->SetFloatStyle( pPanelWindow->GetFloatStyle() | WB_CLOSEABLE );
+ }
+ }
+ }
+}
+
+} // namespace framework
diff --git a/framework/source/uielement/popupmenucontroller.cxx b/framework/source/uielement/popupmenucontroller.cxx
new file mode 100644
index 000000000000..ab455cc5296a
--- /dev/null
+++ b/framework/source/uielement/popupmenucontroller.cxx
@@ -0,0 +1,249 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <com/sun/star/awt/XPopupMenu.hpp>
+#include <com/sun/star/frame/XPopupMenuController.hpp>
+
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <rtl/ref.hxx>
+
+#include <vcl/toolbox.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+
+#include "uielement/popupmenucontroller.hxx"
+#include "services.h"
+
+using rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+
+// --------------------------------------------------------------------
+
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( PopupMenuController ,
+ OWeakObject ,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ToolbarController" ) ) ,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.framework.PopupMenuController" ) )
+ )
+
+DEFINE_INIT_SERVICE ( PopupMenuController, {} )
+
+class PopupMenuControllerImpl
+{
+};
+
+//========================================================================
+// class PopupMenuController
+//========================================================================
+
+PopupMenuController::PopupMenuController( const Reference< lang::XMultiServiceFactory >& rServiceManager )
+: svt::ToolboxController( rServiceManager, Reference< frame::XFrame >(), OUString() )
+{
+}
+
+// --------------------------------------------------------------------
+
+PopupMenuController::~PopupMenuController()
+{
+}
+
+// --------------------------------------------------------------------
+// XInterface
+// --------------------------------------------------------------------
+
+Any SAL_CALL PopupMenuController::queryInterface( const Type& aType ) throw (RuntimeException)
+{
+ Any a( ToolboxController::queryInterface( aType ) );
+ if ( a.hasValue() )
+ return a;
+
+ return ::cppu::queryInterface( aType, static_cast< lang::XServiceInfo* >( this ));
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL PopupMenuController::acquire() throw ()
+{
+ ToolboxController::acquire();
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL PopupMenuController::release() throw ()
+{
+ ToolboxController::release();
+}
+
+// --------------------------------------------------------------------
+// XComponent
+// --------------------------------------------------------------------
+
+void SAL_CALL PopupMenuController::dispose() throw (RuntimeException)
+{
+ if( mxPopupMenuController.is() )
+ {
+ Reference< XComponent > xComponent( mxPopupMenuController, UNO_QUERY );
+ if( xComponent.is() )
+ xComponent->dispose();
+ mxPopupMenuController.clear();
+ }
+
+ mxPopupMenu.clear();
+
+ svt::ToolboxController::dispose();
+}
+
+// --------------------------------------------------------------------
+// XStatusListener
+// --------------------------------------------------------------------
+
+void SAL_CALL PopupMenuController::statusChanged( const frame::FeatureStateEvent& rEvent ) throw ( RuntimeException )
+{
+ svt::ToolboxController::statusChanged(rEvent);
+ enable( rEvent.IsEnabled );
+}
+
+// --------------------------------------------------------------------
+// XToolbarController
+// --------------------------------------------------------------------
+
+void SAL_CALL PopupMenuController::execute( sal_Int16 KeyModifier ) throw (RuntimeException)
+{
+ svt::ToolboxController::execute( KeyModifier );
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL PopupMenuController::click() throw (RuntimeException)
+{
+ svt::ToolboxController::click();
+}
+
+// --------------------------------------------------------------------
+
+void SAL_CALL PopupMenuController::doubleClick() throw (RuntimeException)
+{
+ svt::ToolboxController::doubleClick();
+}
+
+// --------------------------------------------------------------------
+
+bool PopupMenuController::CreatePopupMenuController() throw (Exception)
+{
+ Reference< XMultiComponentFactory > xPopupMenuControllerRegistration( getServiceManager()->createInstance( SERVICENAME_POPUPMENUCONTROLLERFACTORY ), UNO_QUERY_THROW );
+
+ Sequence< Any > aSeq( 2 );
+ PropertyValue aPropValue;
+
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
+ aPropValue.Value <<= getModuleName();
+ aSeq[0] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropValue.Value <<= m_xFrame;
+ aSeq[1] <<= aPropValue;
+
+ Reference< XPropertySet > xProps( getServiceManager(), UNO_QUERY_THROW );
+ Reference< XComponentContext > xComponentContext( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), UNO_QUERY_THROW );
+
+ Reference< XPopupMenuController > xPopupMenuController( xPopupMenuControllerRegistration->createInstanceWithArgumentsAndContext( getCommandURL(), aSeq, xComponentContext ), UNO_QUERY );
+ if ( xPopupMenuController.is() )
+ {
+ mxPopupMenuController = xPopupMenuController;
+ return true;
+ }
+ return false;
+}
+
+Reference< awt::XWindow > SAL_CALL PopupMenuController::createPopupWindow() throw (RuntimeException)
+{
+ SolarMutexGuard aSolarLock;
+
+ Reference< awt::XWindow > xRet;
+
+ try
+ {
+ ToolBox* pToolBox = dynamic_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
+ if( !pToolBox )
+ return xRet;
+
+ // get selected button
+ sal_uInt16 nItemId = pToolBox->GetDownItemId();
+ if( !nItemId )
+ return xRet;
+
+ ::Rectangle aRect( pToolBox->GetItemRect( nItemId ) );
+
+ if( !mxPopupMenuController.is() && !CreatePopupMenuController() )
+ return xRet;
+
+ if( !mxPopupMenu.is() )
+ {
+ mxPopupMenu = Reference< awt::XPopupMenu >( getServiceManager()->createInstance( DECLARE_ASCII( "stardiv.Toolkit.VCLXPopupMenu" ) ), UNO_QUERY_THROW );
+ mxPopupMenuController->setPopupMenu( mxPopupMenu );
+ }
+ else
+ {
+ mxPopupMenuController->updatePopupMenu();
+
+ }
+ pToolBox->SetItemDown( nItemId, sal_True );
+ Reference< awt::XWindowPeer > xPeer( getParent(), UNO_QUERY_THROW );
+ mxPopupMenu->execute( xPeer, VCLUnoHelper::ConvertToAWTRect( aRect ), 0 );
+ pToolBox->SetItemDown( nItemId, sal_False );
+ }
+ catch( Exception& )
+ {
+ }
+
+ return xRet;
+}
+
+// --------------------------------------------------------------------
+
+Reference< awt::XWindow > SAL_CALL PopupMenuController::createItemWindow( const Reference< awt::XWindow >& /*Parent*/ ) throw (RuntimeException)
+{
+ return Reference< awt::XWindow >();
+}
+
+// --------------------------------------------------------------------
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/progressbarwrapper.cxx b/framework/source/uielement/progressbarwrapper.cxx
new file mode 100644
index 000000000000..55c2a6a12293
--- /dev/null
+++ b/framework/source/uielement/progressbarwrapper.cxx
@@ -0,0 +1,366 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <uielement/progressbarwrapper.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <helper/statusindicator.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <uielement/statusindicatorinterfacewrapper.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+using namespace ::com::sun::star;
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+ProgressBarWrapper::ProgressBarWrapper() :
+UIElementWrapperBase( ::com::sun::star::ui::UIElementType::PROGRESSBAR )
+ , m_bOwnsInstance( sal_False )
+ , m_nRange( 100 )
+ , m_nValue( 0 )
+{
+}
+
+ProgressBarWrapper::~ProgressBarWrapper()
+{
+}
+
+// public interfaces
+void ProgressBarWrapper::setStatusBar( const uno::Reference< awt::XWindow >& rStatusBar, sal_Bool bOwnsInstance )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ if ( m_bOwnsInstance )
+ {
+ // dispose XWindow reference our our status bar
+ uno::Reference< lang::XComponent > xComponent( m_xStatusBar, uno::UNO_QUERY );
+ try
+ {
+ if ( xComponent.is() )
+ xComponent->dispose();
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ m_xStatusBar.clear();
+ }
+
+ m_bOwnsInstance = bOwnsInstance;
+ m_xStatusBar = rStatusBar;
+}
+
+uno::Reference< awt::XWindow > ProgressBarWrapper::getStatusBar() const
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return uno::Reference< awt::XWindow >();
+
+ return m_xStatusBar;
+}
+
+// wrapped methods of ::com::sun::star::task::XStatusIndicator
+void ProgressBarWrapper::start( const ::rtl::OUString& Text, ::sal_Int32 Range )
+throw (uno::RuntimeException)
+{
+ uno::Reference< awt::XWindow > xWindow;
+ sal_Int32 nValue( 0 );
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ xWindow = m_xStatusBar;
+ m_nValue = 0;
+ m_nRange = Range;
+ nValue = m_nValue;
+ }
+
+ if ( xWindow.is() )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR )
+ {
+ StatusBar* pStatusBar = (StatusBar *)pWindow;
+ if ( !pStatusBar->IsProgressMode() )
+ pStatusBar->StartProgressMode( Text );
+ else
+ {
+ pStatusBar->SetUpdateMode( sal_False );
+ pStatusBar->EndProgressMode();
+ pStatusBar->StartProgressMode( Text );
+ pStatusBar->SetProgressValue( sal_uInt16( nValue ));
+ pStatusBar->SetUpdateMode( sal_True );
+ }
+ pStatusBar->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
+ }
+ }
+}
+
+void ProgressBarWrapper::end()
+throw (uno::RuntimeException)
+{
+ uno::Reference< awt::XWindow > xWindow;
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ xWindow = m_xStatusBar;
+ m_nRange = 100;
+ m_nValue = 0;
+ }
+
+ if ( xWindow.is() )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR )
+ {
+ StatusBar* pStatusBar = (StatusBar *)pWindow;
+ if ( pStatusBar->IsProgressMode() )
+ pStatusBar->EndProgressMode();
+ }
+ }
+}
+
+void ProgressBarWrapper::setText( const ::rtl::OUString& Text )
+throw (uno::RuntimeException)
+{
+ uno::Reference< awt::XWindow > xWindow;
+ sal_Int32 nValue( 0 );
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ xWindow = m_xStatusBar;
+ m_aText = Text;
+ nValue = m_nValue;
+ }
+
+ if ( xWindow.is() )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR )
+ {
+ StatusBar* pStatusBar = (StatusBar *)pWindow;
+ if( pStatusBar->IsProgressMode() )
+ {
+ pStatusBar->SetUpdateMode( sal_False );
+ pStatusBar->EndProgressMode();
+ pStatusBar->StartProgressMode( Text );
+ pStatusBar->SetProgressValue( sal_uInt16( nValue ));
+ pStatusBar->SetUpdateMode( sal_True );
+ }
+ else
+ pStatusBar->SetText( Text );
+ }
+ }
+}
+
+void ProgressBarWrapper::setValue( ::sal_Int32 nValue )
+throw (uno::RuntimeException)
+{
+ uno::Reference< awt::XWindow > xWindow;
+ rtl::OUString aText;
+ sal_Bool bSetValue( sal_False );
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ xWindow = m_xStatusBar;
+
+ double fVal( 0 );
+ if ( m_nRange > 0 )
+ {
+ fVal = ( double( nValue ) / double( m_nRange )) * 100;
+ fVal = std::max( double( 0 ), std::min( fVal, double( 100 )));
+ }
+
+ if ( m_nValue != sal_Int32( fVal ))
+ {
+ m_nValue = sal_Int32( fVal );
+ bSetValue = sal_True;
+ }
+
+ nValue = m_nValue;
+ aText = m_aText;
+ }
+
+ if ( xWindow.is() && bSetValue )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR )
+ {
+ StatusBar* pStatusBar = (StatusBar *)pWindow;
+ if ( !pStatusBar->IsProgressMode() )
+ pStatusBar->StartProgressMode( aText );
+ pStatusBar->SetProgressValue( sal_uInt16( nValue ));
+ }
+ }
+}
+
+void ProgressBarWrapper::reset()
+throw (uno::RuntimeException)
+{
+ setText( rtl::OUString() );
+ setValue( 0 );
+}
+
+// XInitialization
+void SAL_CALL ProgressBarWrapper::initialize( const uno::Sequence< uno::Any >& )
+throw (uno::Exception, uno::RuntimeException)
+{
+ // dummy - do nothing
+}
+
+// XUpdatable
+void SAL_CALL ProgressBarWrapper::update()
+throw (uno::RuntimeException)
+{
+ // dummy - do nothing
+}
+
+// XComponent
+void SAL_CALL ProgressBarWrapper::dispose()
+throw (uno::RuntimeException)
+{
+ uno::Reference< lang::XComponent > xThis(
+ static_cast< cppu::OWeakObject* >(this),
+ uno::UNO_QUERY );
+
+ {
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+ }
+
+ {
+ lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ ResetableGuard aLock( m_aLock );
+ if ( m_bOwnsInstance )
+ {
+ try
+ {
+ uno::Reference< lang::XComponent > xComponent( m_xStatusBar, uno::UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+ }
+ catch ( lang::DisposedException& )
+ {
+ }
+ }
+
+ m_xStatusBar.clear();
+ m_bDisposed = sal_True;
+ }
+}
+
+// XUIElement
+uno::Reference< uno::XInterface > SAL_CALL ProgressBarWrapper::getRealInterface()
+throw (uno::RuntimeException)
+{
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ // Ready for multithreading
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ return uno::Reference< uno::XInterface >();
+ else
+ {
+ uno::Reference< uno::XInterface > xComp( m_xProgressBarIfacWrapper );
+ if ( !xComp.is() )
+ {
+ StatusIndicatorInterfaceWrapper* pWrapper =
+ new StatusIndicatorInterfaceWrapper(
+ uno::Reference< lang::XComponent >(
+ static_cast< cppu::OWeakObject* >( this ),
+ uno::UNO_QUERY ));
+ xComp = uno::Reference< uno::XInterface >(
+ static_cast< cppu::OWeakObject* >( pWrapper ),
+ uno::UNO_QUERY );
+ m_xProgressBarIfacWrapper = xComp;
+ }
+
+ return xComp;
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/recentfilesmenucontroller.cxx b/framework/source/uielement/recentfilesmenucontroller.cxx
new file mode 100644
index 000000000000..ae976e75fe35
--- /dev/null
+++ b/framework/source/uielement/recentfilesmenucontroller.cxx
@@ -0,0 +1,521 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/recentfilesmenucontroller.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+#include <classes/resource.hrc>
+#include <classes/fwkresid.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/util/XStringWidth.hpp>
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <unotools/historyoptions.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <osl/file.hxx>
+#ifdef WNT
+#define GradientStyle_RECT BLA_GradientStyle_RECT
+#include <windows.h>
+#undef GradientStyle_RECT
+#include <odma_lib.hxx>
+#endif
+#include <dispatch/uieventloghelper.hxx>
+#include <osl/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace com::sun::star::container;
+
+static const char SFX_REFERER_USER[] = "private:user";
+
+namespace framework
+{
+
+class RecentFilesStringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
+{
+ public:
+ RecentFilesStringLength() {}
+ virtual ~RecentFilesStringLength() {}
+
+ // XStringWidth
+ sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
+ throw (::com::sun::star::uno::RuntimeException)
+ {
+ return aString.getLength();
+ }
+};
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( RecentFilesMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_RECENTFILESMENUCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( RecentFilesMenuController, {} )
+
+RecentFilesMenuController::RecentFilesMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::PopupMenuControllerBase( xServiceManager ),
+ m_bDisabled( sal_False )
+{
+}
+
+RecentFilesMenuController::~RecentFilesMenuController()
+{
+}
+
+// private function
+void RecentFilesMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
+{
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ PopupMenu* pVCLPopupMenu = 0;
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ resetPopupMenu( rPopupMenu );
+ if ( pPopupMenu )
+ pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+
+ if ( pVCLPopupMenu )
+ {
+ Sequence< Sequence< PropertyValue > > aHistoryList = SvtHistoryOptions().GetList( ePICKLIST );
+ Reference< XStringWidth > xStringLength( new RecentFilesStringLength );
+
+ int nPickListMenuItems = ( aHistoryList.getLength() > 99 ) ? 99 : aHistoryList.getLength();
+
+ // New vnd.sun.star.popup: command URL to support direct dispatches
+ const rtl::OUString aCmdPrefix( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:RecentFileList?entry=" ));
+
+ m_aRecentFilesItems.clear();
+ if (( nPickListMenuItems > 0 ) && !m_bDisabled )
+ {
+ for ( int i = 0; i < nPickListMenuItems; i++ )
+ {
+ Sequence< PropertyValue >& rPickListEntry = aHistoryList[i];
+ RecentFile aRecentFile;
+
+ for ( int j = 0; j < rPickListEntry.getLength(); j++ )
+ {
+ Any a = rPickListEntry[j].Value;
+
+ if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_URL )
+ a >>= aRecentFile.aURL;
+ else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_FILTER )
+ a >>= aRecentFile.aFilter;
+ else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_TITLE )
+ a >>= aRecentFile.aTitle;
+ else if ( rPickListEntry[j].Name == HISTORY_PROPERTYNAME_PASSWORD )
+ a >>= aRecentFile.aPassword;
+ }
+
+ m_aRecentFilesItems.push_back( aRecentFile );
+ }
+ }
+
+ if ( !m_aRecentFilesItems.empty() )
+ {
+ URL aTargetURL;
+
+ const sal_uInt32 nCount = m_aRecentFilesItems.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ char menuShortCut[5] = "~n: ";
+
+ ::rtl::OUString aMenuShortCut;
+ if ( i <= 9 )
+ {
+ if ( i == 9 )
+ aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1~0: " ));
+ else
+ {
+ menuShortCut[1] = (char)( '1' + i );
+ aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( menuShortCut ));
+ }
+ }
+ else
+ {
+ aMenuShortCut = rtl::OUString::valueOf((sal_Int32)( i + 1 ));
+ aMenuShortCut += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": " ));
+ }
+
+ // Abbreviate URL
+ rtl::OUString aURLString( aCmdPrefix + rtl::OUString::valueOf( sal_Int32( i )));
+ rtl::OUString aTipHelpText;
+ rtl::OUString aMenuTitle;
+ INetURLObject aURL( m_aRecentFilesItems[i].aURL );
+
+ if ( aURL.GetProtocol() == INET_PROT_FILE )
+ {
+ // Do handle file URL differently => convert it to a system
+ // path and abbreviate it with a special function:
+ String aFileSystemPath( aURL.getFSysPath( INetURLObject::FSYS_DETECT ) );
+
+ ::rtl::OUString aSystemPath( aFileSystemPath );
+ ::rtl::OUString aCompactedSystemPath;
+
+ aTipHelpText = aSystemPath;
+ oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, NULL );
+ if ( !nError )
+ aMenuTitle = String( aCompactedSystemPath );
+ else
+ aMenuTitle = aSystemPath;
+ }
+#if 0 // Please don't remove this commented-out code just yet,
+ // we can try to resurrect it later in case somebody complains
+#ifdef WNT
+ else if ( aURL.GetProtocol() == INET_PROT_VND_SUN_STAR_ODMA && ::odma::DMSsAvailable ())
+ {
+ String aShortTitle = m_aRecentFilesItems.at( i ).aTitle;
+
+ // This is against all rules for using
+ // proper abstraction layers and whatnot.
+ // But figuring out how to do it "right"
+ // would have taken the whole week.
+ // So just call the odma_lib functions...
+ // (odma_lib is a thin layer on
+ // top of the ODMA32 DLL)
+
+ static ODMHANDLE handle = NULL;
+ static sal_Bool beenhere = sal_False;
+ ODMSTATUS status;
+
+ if ( ! beenhere )
+ {
+ status = NODMRegisterApp( &handle, ODM_API_VERSION, "sodma", NULL, NULL );
+ beenhere = sal_True;
+ }
+
+ if ( handle != NULL )
+ {
+ rtl::OUString s = aURL.GetMainURL( INetURLObject::DECODE_WITH_CHARSET, RTL_TEXTENCODING_MS_1252 );
+ s = s.copy( strlen ( "vnd.sun.star.odma:/" ) );
+ char title[47];
+ status = NODMGetDocInfo( handle, rtl::OUStringToOString( s, RTL_TEXTENCODING_MS_1252 ).pData->buffer, ODM_NAME, title, sizeof ( title ) );
+ aShortTitle = String::CreateFromAscii( title );
+ }
+ aMenuTitle += aShortTitle;
+ aTipHelpText = aURLString;
+ }
+#endif
+#endif
+ else
+ {
+ // Use INetURLObject to abbreviate all other URLs
+ String aShortURL;
+ aShortURL = aURL.getAbbreviated( xStringLength, 46, INetURLObject::DECODE_UNAMBIGUOUS );
+ aMenuTitle += aShortURL;
+ aTipHelpText = aURLString;
+ }
+
+ ::rtl::OUString aTitle( aMenuShortCut + aMenuTitle );
+
+ pVCLPopupMenu->InsertItem( sal_uInt16( i+1 ), aTitle );
+ pVCLPopupMenu->SetTipHelpText( sal_uInt16( i+1 ), aTipHelpText );
+ pVCLPopupMenu->SetItemCommand( sal_uInt16( i+1 ), aURLString );
+ }
+ }
+ else
+ {
+ // No recent documents => insert "no document" string
+ String aNoDocumentStr = String( FwkResId( STR_NODOCUMENT ));
+ pVCLPopupMenu->InsertItem( 1, aNoDocumentStr );
+ pVCLPopupMenu->EnableItem( 1, sal_False );
+ }
+ }
+}
+
+void RecentFilesMenuController::executeEntry( sal_Int32 nIndex )
+{
+ static int NUM_OF_PICKLIST_ARGS = 3;
+
+ Reference< css::awt::XPopupMenu > xPopupMenu;
+ Reference< XDispatch > xDispatch;
+ Reference< XDispatchProvider > xDispatchProvider;
+ Reference< XMultiServiceFactory > xServiceManager;
+
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ xPopupMenu = m_xPopupMenu;
+ xDispatchProvider = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY );
+ xServiceManager = m_xServiceManager;
+ aLock.clear();
+
+ css::util::URL aTargetURL;
+ Sequence< PropertyValue > aArgsList;
+
+ if (( nIndex >= 0 ) &&
+ ( nIndex < sal::static_int_cast<sal_Int32>( m_aRecentFilesItems.size() )))
+ {
+ const RecentFile& rRecentFile = m_aRecentFilesItems[ nIndex ];
+
+ aTargetURL.Complete = rRecentFile.aURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ aArgsList.realloc( NUM_OF_PICKLIST_ARGS );
+ aArgsList[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
+ aArgsList[0].Value = makeAny( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER )));
+
+ // documents in the picklist will never be opened as templates
+ aArgsList[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AsTemplate" ));
+ aArgsList[1].Value = makeAny( (sal_Bool) sal_False );
+
+ ::rtl::OUString aFilter( rRecentFile.aFilter );
+ sal_Int32 nPos = aFilter.indexOf( '|' );
+ if ( nPos >= 0 )
+ {
+ ::rtl::OUString aFilterOptions;
+
+ if ( nPos < ( aFilter.getLength() - 1 ) )
+ aFilterOptions = aFilter.copy( nPos+1 );
+
+ aArgsList[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterOptions" ));
+ aArgsList[2].Value <<= aFilterOptions;
+
+ aFilter = aFilter.copy( 0, nPos-1 );
+ aArgsList.realloc( ++NUM_OF_PICKLIST_ARGS );
+ }
+
+ aArgsList[NUM_OF_PICKLIST_ARGS-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
+ aArgsList[NUM_OF_PICKLIST_ARGS-1].Value <<= aFilter;
+
+ xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_default")), 0 );
+ }
+
+ if ( xDispatch.is() )
+ {
+ // Call dispatch asychronously as we can be destroyed while dispatch is
+ // executed. VCL is not able to survive this as it wants to call listeners
+ // after select!!!
+ LoadRecentFile* pLoadRecentFile = new LoadRecentFile;
+ pLoadRecentFile->xDispatch = xDispatch;
+ pLoadRecentFile->aTargetURL = aTargetURL;
+ pLoadRecentFile->aArgSeq = aArgsList;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RecentFilesMenuController"))).log(m_xServiceManager, m_xFrame, aTargetURL, aArgsList);
+ Application::PostUserEvent( STATIC_LINK(0, RecentFilesMenuController, ExecuteHdl_Impl), pLoadRecentFile );
+ }
+}
+
+// XEventListener
+void SAL_CALL RecentFilesMenuController::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
+
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xServiceManager.clear();
+
+ if ( m_xPopupMenu.is() )
+ m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
+ m_xPopupMenu.clear();
+}
+
+// XStatusListener
+void SAL_CALL RecentFilesMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+ m_bDisabled = !Event.IsEnabled;
+}
+
+void SAL_CALL RecentFilesMenuController::select( const css::awt::MenuEvent& rEvent ) throw (RuntimeException)
+{
+ Reference< css::awt::XPopupMenu > xPopupMenu;
+ Reference< XDispatch > xDispatch;
+ Reference< XDispatchProvider > xDispatchProvider;
+ Reference< XMultiServiceFactory > xServiceManager;
+
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ xPopupMenu = m_xPopupMenu;
+ xDispatchProvider = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY );
+ xServiceManager = m_xServiceManager;
+ aLock.clear();
+
+ css::util::URL aTargetURL;
+ Sequence< PropertyValue > aArgsList;
+
+ if ( xPopupMenu.is() && xDispatchProvider.is() )
+ {
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( xPopupMenu );
+ if ( pPopupMenu )
+ executeEntry( rEvent.MenuId-1 );
+ }
+}
+
+void SAL_CALL RecentFilesMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException)
+{
+ osl::MutexGuard aLock( m_aMutex );
+ impl_setPopupMenu();
+}
+
+// XPopupMenuController
+void RecentFilesMenuController::impl_setPopupMenu()
+{
+ if ( m_xPopupMenu.is() )
+ fillPopupMenu( m_xPopupMenu );
+}
+
+void SAL_CALL RecentFilesMenuController::updatePopupMenu() throw (RuntimeException)
+{
+ osl::ClearableMutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XDispatch > xDispatch( m_xDispatch );
+ com::sun::star::util::URL aTargetURL;
+ aTargetURL.Complete = m_aCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ aLock.clear();
+
+ // Add/remove status listener to get a status update once
+ if ( xDispatch.is() )
+ {
+ xDispatch->addStatusListener( xStatusListener, aTargetURL );
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+}
+
+// XDispatchProvider
+Reference< XDispatch > SAL_CALL RecentFilesMenuController::queryDispatch(
+ const URL& aURL,
+ const ::rtl::OUString& /*sTarget*/,
+ sal_Int32 /*nFlags*/ )
+throw( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ if ( aURL.Complete.indexOf( m_aBaseURL ) == 0 )
+ return Reference< XDispatch >( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ else
+ return Reference< XDispatch >();
+}
+
+// XDispatch
+void SAL_CALL RecentFilesMenuController::dispatch(
+ const URL& aURL,
+ const Sequence< PropertyValue >& /*seqProperties*/ )
+throw( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ if ( aURL.Complete.indexOf( m_aBaseURL ) == 0 )
+ {
+ // Parse URL to retrieve entry argument and its value
+ sal_Int32 nQueryPart = aURL.Complete.indexOf( '?', m_aBaseURL.getLength() );
+ if ( nQueryPart > 0 )
+ {
+ const rtl::OUString aEntryArgStr( RTL_CONSTASCII_USTRINGPARAM( "entry=" ));
+ sal_Int32 nEntryArg = aURL.Complete.indexOf( aEntryArgStr, nQueryPart );
+ sal_Int32 nEntryPos = nEntryArg + aEntryArgStr.getLength();
+ if (( nEntryArg > 0 ) && ( nEntryPos < aURL.Complete.getLength() ))
+ {
+ sal_Int32 nAddArgs = aURL.Complete.indexOf( '&', nEntryPos );
+ rtl::OUString aEntryArg;
+
+ if ( nAddArgs < 0 )
+ aEntryArg = aURL.Complete.copy( nEntryPos );
+ else
+ aEntryArg = aURL.Complete.copy( nEntryPos, nAddArgs-nEntryPos );
+
+ sal_Int32 nEntry = aEntryArg.toInt32();
+ executeEntry( nEntry );
+ }
+ }
+ }
+}
+
+void SAL_CALL RecentFilesMenuController::addStatusListener(
+ const Reference< XStatusListener >& xControl,
+ const URL& aURL )
+throw( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ svt::PopupMenuControllerBase::addStatusListener( xControl, aURL );
+}
+
+void SAL_CALL RecentFilesMenuController::removeStatusListener(
+ const Reference< XStatusListener >& xControl,
+ const URL& aURL )
+throw( RuntimeException )
+{
+ svt::PopupMenuControllerBase::removeStatusListener( xControl, aURL );
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( RecentFilesMenuController, ExecuteHdl_Impl, LoadRecentFile*, pLoadRecentFile )
+{
+ try
+ {
+ // Asynchronous execution as this can lead to our own destruction!
+ // Framework can recycle our current frame and the layout manager disposes all user interface
+ // elements if a component gets detached from its frame!
+ pLoadRecentFile->xDispatch->dispatch( pLoadRecentFile->aTargetURL, pLoadRecentFile->aArgSeq );
+ }
+ catch ( Exception& )
+ {
+ }
+
+ delete pLoadRecentFile;
+ return 0;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/simpletextstatusbarcontroller.cxx b/framework/source/uielement/simpletextstatusbarcontroller.cxx
new file mode 100644
index 000000000000..df968765a6e6
--- /dev/null
+++ b/framework/source/uielement/simpletextstatusbarcontroller.cxx
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/simpletextstatusbarcontroller.hxx>
+#include <classes/fwkresid.hxx>
+#include <services.h>
+#include <classes/resource.hrc>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vcl/status.hxx>
+#include <toolkit/unohlp.hxx>
+#include <toolkit/helper/convert.hxx>
+
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+
+namespace framework
+{
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( SimpleTextStatusbarController ,
+ OWeakObject ,
+ SERVICENAME_STATUSBARCONTROLLER ,
+ IMPLEMENTATIONNAME_SIMPLETEXTSTATUSBARCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( SimpleTextStatusbarController, {} )
+
+SimpleTextStatusbarController::SimpleTextStatusbarController( const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::StatusbarController( xServiceManager, uno::Reference< frame::XFrame >(), rtl::OUString(), 0 )
+{
+}
+
+SimpleTextStatusbarController::~SimpleTextStatusbarController()
+{
+}
+
+// XInterface
+Any SAL_CALL SimpleTextStatusbarController::queryInterface( const Type& rType )
+throw ( RuntimeException )
+{
+ return svt::StatusbarController::queryInterface( rType );
+}
+
+void SAL_CALL SimpleTextStatusbarController::acquire() throw ()
+{
+ svt::StatusbarController::acquire();
+}
+
+void SAL_CALL SimpleTextStatusbarController::release() throw ()
+{
+ svt::StatusbarController::release();
+}
+
+void SAL_CALL SimpleTextStatusbarController::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ const rtl::OUString aPropValueName( RTL_CONSTASCII_USTRINGPARAM( "Value" ));
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ svt::StatusbarController::initialize( aArguments );
+
+ rtl::OUString aValue;
+ beans::PropertyValue aPropValue;
+
+ // Check arguments for optional "Value" property. We need it
+ // to set our internal simple text.
+ for ( int i = 0; i < aArguments.getLength(); i++ )
+ {
+ if (( aArguments[i] >>= aPropValue ) && ( aPropValue.Name.equals( aPropValueName )))
+ {
+ aPropValue.Value >>= aValue;
+ break;
+ }
+ }
+
+ m_aText = aValue;
+ if ( m_xParentWindow.is() && m_nID > 0 )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( m_xParentWindow );
+ if ( pWindow && ( pWindow->GetType() == WINDOW_STATUSBAR ))
+ {
+ StatusBar* pStatusBar = (StatusBar *)pWindow;
+ pStatusBar->SetItemText( m_nID, m_aText );
+ }
+ }
+}
+
+// XComponent
+void SAL_CALL SimpleTextStatusbarController::dispose()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::dispose();
+}
+
+// XEventListener
+void SAL_CALL SimpleTextStatusbarController::disposing( const EventObject& Source )
+throw ( RuntimeException )
+{
+ svt::StatusbarController::disposing( Source );
+}
+
+// XStatusListener
+void SAL_CALL SimpleTextStatusbarController::statusChanged( const FeatureStateEvent& )
+throw ( RuntimeException )
+{
+}
+
+// XStatusbarController
+::sal_Bool SAL_CALL SimpleTextStatusbarController::mouseButtonDown(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL SimpleTextStatusbarController::mouseMove(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+::sal_Bool SAL_CALL SimpleTextStatusbarController::mouseButtonUp(
+ const ::com::sun::star::awt::MouseEvent& )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+void SAL_CALL SimpleTextStatusbarController::command(
+ const ::com::sun::star::awt::Point& aPos,
+ ::sal_Int32 nCommand,
+ ::sal_Bool bMouseEvent,
+ const ::com::sun::star::uno::Any& aData )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::command( aPos, nCommand, bMouseEvent, aData );
+}
+
+void SAL_CALL SimpleTextStatusbarController::paint(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >& xGraphics,
+ const ::com::sun::star::awt::Rectangle& rOutputRectangle,
+ ::sal_Int32 nItemId,
+ ::sal_Int32 nStyle )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::paint( xGraphics, rOutputRectangle, nItemId, nStyle );
+}
+
+void SAL_CALL SimpleTextStatusbarController::click()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::click();
+}
+
+void SAL_CALL SimpleTextStatusbarController::doubleClick() throw (::com::sun::star::uno::RuntimeException)
+{
+ svt::StatusbarController::doubleClick();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/spinfieldtoolbarcontroller.cxx b/framework/source/uielement/spinfieldtoolbarcontroller.cxx
new file mode 100644
index 000000000000..02f9ab5ab644
--- /dev/null
+++ b/framework/source/uielement/spinfieldtoolbarcontroller.cxx
@@ -0,0 +1,573 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <stdio.h>
+#include <wchar.h>
+
+#include "uielement/spinfieldtoolbarcontroller.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include "uielement/toolbar.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/status/ItemStatus.hpp>
+#include <com/sun/star/frame/status/ItemState.hpp>
+#include <com/sun/star/frame/status/Visibility.hpp>
+#include <com/sun/star/frame/XControlNotificationListener.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <svtools/toolboxcontroller.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <tools/urlobj.hxx>
+#ifdef WINNT
+#include <systools/win32/snprintf.h>
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::frame::status;
+using namespace ::com::sun::star::util;
+
+namespace framework
+{
+
+// ------------------------------------------------------------------
+
+// Wrapper class to notify controller about events from combobox.
+// Unfortunaltly the events are notifed through virtual methods instead
+// of Listeners.
+
+class SpinfieldControl : public SpinField
+{
+ public:
+ SpinfieldControl( Window* pParent, WinBits nStyle, ISpinfieldListener* pSpinFieldListener );
+ virtual ~SpinfieldControl();
+
+ virtual void Up();
+ virtual void Down();
+ virtual void First();
+ virtual void Last();
+ virtual void KeyInput( const ::KeyEvent& rKEvt );
+ virtual void Modify();
+ virtual void GetFocus();
+ virtual void LoseFocus();
+ virtual void StateChanged( StateChangedType nType );
+ virtual void DataChanged( const DataChangedEvent& rDCEvt );
+ virtual long PreNotify( NotifyEvent& rNEvt );
+
+ private:
+ ISpinfieldListener* m_pSpinFieldListener;
+};
+
+SpinfieldControl::SpinfieldControl( Window* pParent, WinBits nStyle, ISpinfieldListener* pSpinFieldListener ) :
+ SpinField( pParent, nStyle )
+ , m_pSpinFieldListener( pSpinFieldListener )
+{
+}
+
+SpinfieldControl::~SpinfieldControl()
+{
+ m_pSpinFieldListener = 0;
+}
+
+void SpinfieldControl::Up()
+{
+ SpinField::Up();
+ if ( m_pSpinFieldListener )
+ m_pSpinFieldListener->Up();
+}
+
+void SpinfieldControl::Down()
+{
+ SpinField::Down();
+ if ( m_pSpinFieldListener )
+ m_pSpinFieldListener->Down();
+}
+
+void SpinfieldControl::First()
+{
+ SpinField::First();
+ if ( m_pSpinFieldListener )
+ m_pSpinFieldListener->First();
+}
+
+void SpinfieldControl::Last()
+{
+ SpinField::First();
+ if ( m_pSpinFieldListener )
+ m_pSpinFieldListener->Last();
+}
+
+void SpinfieldControl::KeyInput( const ::KeyEvent& rKEvt )
+{
+ SpinField::KeyInput( rKEvt );
+ if ( m_pSpinFieldListener )
+ m_pSpinFieldListener->KeyInput( rKEvt );
+}
+
+void SpinfieldControl::Modify()
+{
+ SpinField::Modify();
+ if ( m_pSpinFieldListener )
+ m_pSpinFieldListener->Modify();
+}
+
+void SpinfieldControl::GetFocus()
+{
+ SpinField::GetFocus();
+ if ( m_pSpinFieldListener )
+ m_pSpinFieldListener->GetFocus();
+}
+
+void SpinfieldControl::LoseFocus()
+{
+ SpinField::GetFocus();
+ if ( m_pSpinFieldListener )
+ m_pSpinFieldListener->GetFocus();
+}
+
+void SpinfieldControl::StateChanged( StateChangedType nType )
+{
+ SpinField::StateChanged( nType );
+ if ( m_pSpinFieldListener )
+ m_pSpinFieldListener->StateChanged( nType );
+}
+
+void SpinfieldControl::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ SpinField::DataChanged( rDCEvt );
+ if ( m_pSpinFieldListener )
+ m_pSpinFieldListener->DataChanged( rDCEvt );
+}
+
+long SpinfieldControl::PreNotify( NotifyEvent& rNEvt )
+{
+ long nRet( 0 );
+ if ( m_pSpinFieldListener )
+ nRet = m_pSpinFieldListener->PreNotify( rNEvt );
+ if ( nRet == 0 )
+ nRet = SpinField::PreNotify( rNEvt );
+
+ return nRet;
+}
+
+// ------------------------------------------------------------------
+
+SpinfieldToolbarController::SpinfieldToolbarController(
+ const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nID,
+ sal_Int32 nWidth,
+ const ::rtl::OUString& aCommand ) :
+ ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand )
+ , m_bFloat( false )
+ , m_bMaxSet( false )
+ , m_bMinSet( false )
+ , m_nMax( 0.0 )
+ , m_nMin( 0.0 )
+ , m_nValue( 0.0 )
+ , m_nStep( 0.0 )
+ , m_pSpinfieldControl( 0 )
+{
+ m_pSpinfieldControl = new SpinfieldControl( m_pToolbar, WB_SPIN|WB_BORDER, this );
+ if ( nWidth == 0 )
+ nWidth = 100;
+
+ // Calculate height of the spin field according to the application font height
+ sal_Int32 nHeight = getFontSizePixel( m_pSpinfieldControl ) + 5 + 1;
+
+ m_pSpinfieldControl->SetSizePixel( ::Size( nWidth, nHeight ));
+ m_pToolbar->SetItemWindow( m_nID, m_pSpinfieldControl );
+}
+
+// ------------------------------------------------------------------
+
+SpinfieldToolbarController::~SpinfieldToolbarController()
+{
+}
+
+// ------------------------------------------------------------------
+
+void SAL_CALL SpinfieldToolbarController::dispose()
+throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ m_pToolbar->SetItemWindow( m_nID, 0 );
+ delete m_pSpinfieldControl;
+
+ ComplexToolbarController::dispose();
+
+ m_pSpinfieldControl = 0;
+}
+
+// ------------------------------------------------------------------
+Sequence<PropertyValue> SpinfieldToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
+{
+ Sequence<PropertyValue> aArgs( 2 );
+ ::rtl::OUString aSpinfieldText = m_pSpinfieldControl->GetText();
+
+ // Add key modifier to argument list
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
+ aArgs[0].Value <<= KeyModifier;
+ aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Value" ));
+ if ( m_bFloat )
+ aArgs[1].Value <<= aSpinfieldText.toDouble();
+ else
+ aArgs[1].Value <<= aSpinfieldText.toInt32();
+ return aArgs;
+}
+
+// ------------------------------------------------------------------
+
+void SpinfieldToolbarController::Up()
+{
+ double nValue = m_nValue + m_nStep;
+ if ( m_bMaxSet && nValue > m_nMax )
+ return;
+
+ m_nValue = nValue;
+
+ rtl::OUString aText = impl_formatOutputString( m_nValue );
+ m_pSpinfieldControl->SetText( aText );
+ execute( 0 );
+}
+
+void SpinfieldToolbarController::Down()
+{
+ double nValue = m_nValue - m_nStep;
+ if ( m_bMinSet && nValue < m_nMin )
+ return;
+
+ m_nValue = nValue;
+
+ rtl::OUString aText = impl_formatOutputString( m_nValue );
+ m_pSpinfieldControl->SetText( aText );
+ execute( 0 );
+}
+
+void SpinfieldToolbarController::First()
+{
+ if ( m_bMinSet )
+ {
+ m_nValue = m_nMin;
+
+ rtl::OUString aText = impl_formatOutputString( m_nValue );
+ m_pSpinfieldControl->SetText( aText );
+ execute( 0 );
+ }
+}
+
+void SpinfieldToolbarController::Last()
+{
+ if ( m_bMaxSet )
+ {
+ m_nValue = m_nMax;
+
+ rtl::OUString aText = impl_formatOutputString( m_nValue );
+ m_pSpinfieldControl->SetText( aText );
+ execute( 0 );
+ }
+}
+
+void SpinfieldToolbarController::Modify()
+{
+ notifyTextChanged( m_pSpinfieldControl->GetText() );
+}
+
+void SpinfieldToolbarController::KeyInput( const ::KeyEvent& /*rKEvt*/ )
+{
+}
+
+void SpinfieldToolbarController::GetFocus()
+{
+ notifyFocusGet();
+}
+
+void SpinfieldToolbarController::LoseFocus()
+{
+ notifyFocusLost();
+}
+
+void SpinfieldToolbarController::StateChanged( StateChangedType /*nType*/ )
+{
+}
+
+void SpinfieldToolbarController::DataChanged( const DataChangedEvent& /*rDCEvt*/ )
+{
+}
+
+long SpinfieldToolbarController::PreNotify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const ::KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ const KeyCode& rKeyCode = pKeyEvent->GetKeyCode();
+ if(( rKeyCode.GetModifier() | rKeyCode.GetCode()) == KEY_RETURN )
+ {
+ // Call execute only with non-empty text
+ if ( m_pSpinfieldControl->GetText().Len() > 0 )
+ execute( rKeyCode.GetModifier() );
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------
+
+void SpinfieldToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
+{
+ rtl::OUString aValue;
+ rtl::OUString aMax;
+ rtl::OUString aMin;
+ rtl::OUString aStep;
+ bool bFloatValue( false );
+
+ if ( rControlCommand.Command.equalsAsciiL( "SetStep", 7 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ sal_Int32 nValue;
+ double fValue;
+ bool bFloat( false );
+
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Step", 4 ))
+ {
+ if ( impl_getValue( rControlCommand.Arguments[i].Value, nValue, fValue, bFloat ))
+ aStep = bFloat ? ::rtl::OUString::valueOf( fValue ) :
+ ::rtl::OUString::valueOf( nValue );
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "SetValue", 8 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Value", 5 ))
+ {
+ sal_Int32 nValue;
+ double fValue;
+ bool bFloat( false );
+
+ if ( impl_getValue( rControlCommand.Arguments[i].Value, nValue, fValue, bFloat ))
+ {
+ aValue = bFloat ? ::rtl::OUString::valueOf( fValue ) : ::rtl::OUString::valueOf( nValue );
+ bFloatValue = bFloat;
+ }
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "SetValues", 9 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ sal_Int32 nValue;
+ double fValue;
+ bool bFloat( false );
+
+ rtl::OUString aName = rControlCommand.Arguments[i].Name;
+ if ( impl_getValue( rControlCommand.Arguments[i].Value, nValue, fValue, bFloat ))
+ {
+ if ( aName.equalsAsciiL( "Value", 5 ))
+ {
+ aValue = bFloat ? ::rtl::OUString::valueOf( fValue ) : ::rtl::OUString::valueOf( nValue );
+ bFloatValue = bFloat;
+ }
+ else if ( aName.equalsAsciiL( "Step", 4 ))
+ aStep = bFloat ? ::rtl::OUString::valueOf( fValue ) :
+ ::rtl::OUString::valueOf( nValue );
+ else if ( aName.equalsAsciiL( "LowerLimit", 10 ))
+ aMin = bFloat ? ::rtl::OUString::valueOf( fValue ) :
+ ::rtl::OUString::valueOf( nValue );
+ else if ( aName.equalsAsciiL( "UpperLimit", 10 ))
+ aMax = bFloat ? ::rtl::OUString::valueOf( fValue ) :
+ ::rtl::OUString::valueOf( nValue );
+ }
+ else if ( aName.equalsAsciiL( "OutputFormat", 12 ))
+ rControlCommand.Arguments[i].Value >>= m_aOutFormat;
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "SetLowerLimit", 13 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ sal_Int32 nValue;
+ double fValue;
+ bool bFloat( false );
+
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "LowerLimit", 10 ))
+ {
+ if ( impl_getValue( rControlCommand.Arguments[i].Value, nValue, fValue, bFloat ))
+ aMin = bFloat ? ::rtl::OUString::valueOf( fValue ) :
+ ::rtl::OUString::valueOf( nValue );
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "SetUpperLimit", 13 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ sal_Int32 nValue;
+ double fValue;
+ bool bFloat( false );
+
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "UpperLimit", 10 ))
+ {
+ if ( impl_getValue( rControlCommand.Arguments[i].Value, nValue, fValue, bFloat ))
+ aMax = bFloat ? ::rtl::OUString::valueOf( fValue ) :
+ ::rtl::OUString::valueOf( nValue );
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "SetOutputFormat", 15 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "OutputFormat", 10 ))
+ {
+ rControlCommand.Arguments[i].Value >>= m_aOutFormat;
+ break;
+ }
+ }
+ }
+
+ // Check values and set members
+ if ( aValue.getLength() > 0 )
+ {
+ m_bFloat = bFloatValue;
+ m_nValue = aValue.toDouble();
+
+ rtl::OUString aOutString = impl_formatOutputString( m_nValue );
+ m_pSpinfieldControl->SetText( aOutString );
+ notifyTextChanged( aOutString );
+ }
+ if ( aMax.getLength() > 0 )
+ {
+ m_nMax = aMax.toDouble();
+ m_bMaxSet = true;
+ }
+ if ( aMin.getLength() > 0 )
+ {
+ m_nMin = aMin.toDouble();
+ m_bMinSet = true;
+ }
+ if ( aStep.getLength() > 0 )
+ m_nStep = aStep.toDouble();
+}
+
+bool SpinfieldToolbarController::impl_getValue(
+ const Any& rAny, sal_Int32& nValue, double& fValue, bool& bFloat )
+{
+ using ::com::sun::star::uno::TypeClass;
+
+ bool bValueValid( false );
+
+ bFloat = false;
+ TypeClass aTypeClass = rAny.getValueTypeClass();
+ if (( aTypeClass == TypeClass( typelib_TypeClass_LONG )) ||
+ ( aTypeClass == TypeClass( typelib_TypeClass_SHORT )) ||
+ ( aTypeClass == TypeClass( typelib_TypeClass_BYTE )))
+ bValueValid = rAny >>= nValue;
+ else if (( aTypeClass == TypeClass( typelib_TypeClass_FLOAT )) ||
+ ( aTypeClass == TypeClass( typelib_TypeClass_DOUBLE )))
+ {
+ bValueValid = rAny >>= fValue;
+ bFloat = true;
+ }
+
+ return bValueValid;
+}
+
+rtl::OUString SpinfieldToolbarController::impl_formatOutputString( double fValue )
+{
+ if ( m_aOutFormat.getLength() == 0 )
+ {
+ if ( m_bFloat )
+ return rtl::OUString::valueOf( fValue );
+ else
+ return rtl::OUString::valueOf( sal_Int32( fValue ));
+ }
+ else
+ {
+#ifdef WNT
+ sal_Unicode aBuffer[128];
+
+ aBuffer[0] = 0;
+ if ( m_bFloat )
+ snwprintf( reinterpret_cast<wchar_t *>(aBuffer), 128, reinterpret_cast<const wchar_t *>(m_aOutFormat.getStr()), fValue );
+ else
+ snwprintf( reinterpret_cast<wchar_t *>(aBuffer), 128, reinterpret_cast<const wchar_t *>(m_aOutFormat.getStr()), sal_Int32( fValue ));
+
+ sal_Int32 nSize = rtl_ustr_getLength( aBuffer );
+ return rtl::OUString( aBuffer, nSize );
+#else
+ // Currently we have no support for a format string using sal_Unicode. wchar_t
+ // is 32 bit on Unix platform!
+ char aBuffer[128];
+
+ ::rtl::OString aFormat = OUStringToOString( m_aOutFormat, osl_getThreadTextEncoding() );
+ if ( m_bFloat )
+ snprintf( aBuffer, 128, aFormat.getStr(), fValue );
+ else
+ snprintf( aBuffer, 128, aFormat.getStr(), static_cast<long>( fValue ));
+
+ sal_Int32 nSize = strlen( aBuffer );
+ rtl::OString aTmp( aBuffer, nSize );
+ return rtl::OStringToOUString( aTmp, osl_getThreadTextEncoding() );
+#endif
+ }
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/statusbar.cxx b/framework/source/uielement/statusbar.cxx
new file mode 100644
index 000000000000..ea1734802417
--- /dev/null
+++ b/framework/source/uielement/statusbar.cxx
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/statusbar.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+
+namespace framework
+{
+
+FrameworkStatusBar::FrameworkStatusBar(
+ Window* pParent,
+ WinBits nWinBits ) :
+ StatusBar( pParent, nWinBits ),
+ m_pMgr( NULL ),
+ m_bShow( sal_False ),
+ m_bLock( sal_False )
+{
+ // set optimal size
+ SetOutputSizePixel( CalcWindowSizePixel() );
+}
+
+FrameworkStatusBar::~FrameworkStatusBar()
+{
+}
+
+void FrameworkStatusBar::SetStatusBarManager( StatusBarManager* pStatusBarManager )
+{
+ SolarMutexGuard aSolarMutexGuard;
+ m_pMgr = pStatusBarManager;
+}
+
+void FrameworkStatusBar::UserDraw(const UserDrawEvent& rUDEvt)
+{
+ if ( m_pMgr )
+ m_pMgr->UserDraw( rUDEvt );
+}
+
+void FrameworkStatusBar::Command( const CommandEvent& rEvt )
+{
+ if ( m_pMgr )
+ m_pMgr->Command( rEvt );
+}
+
+void FrameworkStatusBar::StateChanged( StateChangedType nType )
+{
+ if ( m_pMgr )
+ m_pMgr->StateChanged( nType );
+}
+
+void FrameworkStatusBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ StatusBar::DataChanged( rDCEvt );
+ if ( m_pMgr )
+ m_pMgr->DataChanged( rDCEvt );
+}
+
+void FrameworkStatusBar::MouseMove( const MouseEvent& rMEvt )
+{
+ StatusBar::MouseMove( rMEvt );
+ if ( m_pMgr )
+ m_pMgr->MouseMove( rMEvt );
+}
+
+void FrameworkStatusBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ StatusBar::MouseButtonDown( rMEvt );
+ if ( m_pMgr )
+ m_pMgr->MouseButtonDown( rMEvt );
+}
+
+void FrameworkStatusBar::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ StatusBar::MouseButtonUp( rMEvt );
+ if ( m_pMgr )
+ m_pMgr->MouseButtonUp( rMEvt );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/statusbarmanager.cxx b/framework/source/uielement/statusbarmanager.cxx
new file mode 100644
index 000000000000..70bcc6fae0b0
--- /dev/null
+++ b/framework/source/uielement/statusbarmanager.cxx
@@ -0,0 +1,713 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <uielement/statusbarmanager.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/threadhelpbase.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <framework/sfxhelperfunctions.hxx>
+#include <macros/generic.hxx>
+#include <macros/xinterface.hxx>
+#include <macros/xtypeprovider.hxx>
+#include <stdtypes.h>
+#include "services.h"
+#include "general.h"
+#include "properties.h"
+#include <helper/mischelper.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XStatusListener.hpp>
+#include <com/sun/star/util/XUpdatable.hpp>
+#include <com/sun/star/ui/ItemStyle.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/Command.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <toolkit/unohlp.hxx>
+#include <svtools/statusbarcontroller.hxx>
+
+#include <vcl/status.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace ::com::sun::star;
+#ifndef css
+#define css ::com::sun::star
+#endif
+#ifndef css_ui
+#define css_ui ::com::sun::star::ui
+#endif
+
+const sal_Int32 HELPID_PREFIX_LENGTH = 7;
+static const char HELPID_PREFIX[] = "helpid:";
+
+// Property names of a menu/menu item ItemDescriptor
+static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
+static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL";
+static const char ITEM_DESCRIPTOR_OFFSET[] = "Offset";
+static const char ITEM_DESCRIPTOR_STYLE[] = "Style";
+static const char ITEM_DESCRIPTOR_WIDTH[] = "Width";
+static const char ITEM_DESCRIPTOR_TYPE[] = "Type";
+
+namespace framework
+{
+
+static sal_uInt16 impl_convertItemStyleToItemBits( sal_Int16 nStyle )
+{
+ sal_uInt16 nItemBits( 0 );
+
+ if (( nStyle & css_ui::ItemStyle::ALIGN_RIGHT ) == css_ui::ItemStyle::ALIGN_RIGHT )
+ nItemBits |= SIB_RIGHT;
+ else if ( nStyle & css_ui::ItemStyle::ALIGN_LEFT )
+ nItemBits |= SIB_LEFT;
+ else
+ nItemBits |= SIB_CENTER;
+
+ if (( nStyle & css_ui::ItemStyle::DRAW_FLAT ) == css_ui::ItemStyle::DRAW_FLAT )
+ nItemBits |= SIB_FLAT;
+ else if ( nStyle & css_ui::ItemStyle::DRAW_OUT3D )
+ nItemBits |= SIB_OUT;
+ else
+ nItemBits |= SIB_IN;
+
+ if (( nStyle & css_ui::ItemStyle::AUTO_SIZE ) == css_ui::ItemStyle::AUTO_SIZE )
+ nItemBits |= SIB_AUTOSIZE;
+ if ( nStyle & css_ui::ItemStyle::OWNER_DRAW )
+ nItemBits |= SIB_USERDRAW;
+
+ return nItemBits;
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_5 ( StatusBarManager ,
+ ::cppu::OWeakObject ,
+ DIRECT_INTERFACE( lang::XTypeProvider ),
+ DIRECT_INTERFACE( lang::XComponent ),
+ DIRECT_INTERFACE( frame::XFrameActionListener ),
+ DIRECT_INTERFACE( css::ui::XUIConfigurationListener ),
+ DERIVED_INTERFACE( lang::XEventListener, frame::XFrameActionListener )
+ )
+
+DEFINE_XTYPEPROVIDER_5 ( StatusBarManager ,
+ lang::XTypeProvider ,
+ lang::XComponent ,
+ css::ui::XUIConfigurationListener ,
+ frame::XFrameActionListener ,
+ lang::XEventListener
+ )
+
+StatusBarManager::StatusBarManager(
+ const uno::Reference< lang::XMultiServiceFactory >& rServiceManager,
+ const uno::Reference< frame::XFrame >& rFrame,
+ const rtl::OUString& rResourceName,
+ StatusBar* pStatusBar ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ OWeakObject(),
+ m_bDisposed( sal_False ),
+ m_bFrameActionRegistered( sal_False ),
+ m_bUpdateControllers( sal_False ),
+ m_bModuleIdentified( sal_False ),
+ m_pStatusBar( pStatusBar ),
+ m_aResourceName( rResourceName ),
+ m_xFrame( rFrame ),
+ m_aListenerContainer( m_aLock.getShareableOslMutex() ),
+ m_xServiceManager( rServiceManager )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::StatusBarManager" );
+
+ if ( m_xServiceManager.is() )
+ m_xStatusbarControllerRegistration = uno::Reference< css::frame::XUIControllerRegistration >(
+ m_xServiceManager->createInstance( SERVICENAME_STATUSBARCONTROLLERFACTORY ),
+ uno::UNO_QUERY );
+
+ m_pStatusBar->SetClickHdl( LINK( this, StatusBarManager, Click ) );
+ m_pStatusBar->SetDoubleClickHdl( LINK( this, StatusBarManager, DoubleClick ) );
+}
+
+StatusBarManager::~StatusBarManager()
+{
+}
+
+StatusBar* StatusBarManager::GetStatusBar() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::GetStatusBar" );
+ ResetableGuard aGuard( m_aLock );
+ return m_pStatusBar;
+}
+
+void StatusBarManager::frameAction( const frame::FrameActionEvent& Action )
+throw ( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::frameAction" );
+ ResetableGuard aGuard( m_aLock );
+ if ( Action.Action == frame::FrameAction_CONTEXT_CHANGED )
+ UpdateControllers();
+}
+
+void SAL_CALL StatusBarManager::disposing( const lang::EventObject& Source ) throw ( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::disposing" );
+ {
+ ResetableGuard aGuard( m_aLock );
+ if ( m_bDisposed )
+ return;
+ }
+
+ RemoveControllers();
+
+ {
+ ResetableGuard aGuard( m_aLock );
+ if ( Source.Source == uno::Reference< uno::XInterface >( m_xFrame, uno::UNO_QUERY ))
+ m_xFrame.clear();
+
+ m_xServiceManager.clear();
+ }
+}
+
+// XComponent
+void SAL_CALL StatusBarManager::dispose() throw( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::dispose" );
+ uno::Reference< lang::XComponent > xThis(
+ static_cast< OWeakObject* >(this), uno::UNO_QUERY );
+
+ lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ {
+ ResetableGuard aGuard( m_aLock );
+ if ( !m_bDisposed )
+ {
+ RemoveControllers();
+
+ delete m_pStatusBar;
+ m_pStatusBar = 0;
+
+ if ( m_bFrameActionRegistered && m_xFrame.is() )
+ {
+ try
+ {
+ m_xFrame->removeFrameActionListener( uno::Reference< frame::XFrameActionListener >(
+ static_cast< ::cppu::OWeakObject *>( this ),
+ uno::UNO_QUERY ));
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+
+ m_xFrame.clear();
+ m_xServiceManager.clear();
+
+ m_bDisposed = sal_True;
+ }
+ }
+}
+
+void SAL_CALL StatusBarManager::addEventListener( const uno::Reference< lang::XEventListener >& xListener ) throw( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::addEventListener" );
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw lang::DisposedException();
+
+ m_aListenerContainer.addInterface( ::getCppuType(
+ ( const uno::Reference< lang::XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL StatusBarManager::removeEventListener( const uno::Reference< lang::XEventListener >& xListener ) throw( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::removeEventListener" );
+ m_aListenerContainer.removeInterface( ::getCppuType(
+ ( const uno::Reference< lang::XEventListener >* ) NULL ), xListener );
+}
+
+// XUIConfigurationListener
+void SAL_CALL StatusBarManager::elementInserted( const css::ui::ConfigurationEvent& ) throw ( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::elementInserted" );
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ return;
+}
+
+void SAL_CALL StatusBarManager::elementRemoved( const css::ui::ConfigurationEvent& ) throw ( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::elementRemoved" );
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ return;
+}
+
+void SAL_CALL StatusBarManager::elementReplaced( const css::ui::ConfigurationEvent& ) throw ( uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::elementReplaced" );
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ return;
+}
+
+void StatusBarManager::UpdateControllers()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::UpdateControllers" );
+ if ( !m_bUpdateControllers )
+ {
+ m_bUpdateControllers = sal_True;
+ const sal_uInt32 nCount = m_aControllerVector.size();
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ try
+ {
+ uno::Reference< util::XUpdatable > xUpdatable( m_aControllerVector[n], uno::UNO_QUERY );
+ if ( xUpdatable.is() )
+ xUpdatable->update();
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+ m_bUpdateControllers = sal_False;
+}
+
+void StatusBarManager::RemoveControllers()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::RemoveControllers" );
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ const sal_uInt32 nCount = m_aControllerVector.size();
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ try
+ {
+ uno::Reference< lang::XComponent > xComponent(
+ m_aControllerVector[n], uno::UNO_QUERY );
+ if ( xComponent.is() )
+ xComponent->dispose();
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ m_aControllerVector[n].clear();
+ }
+}
+
+rtl::OUString StatusBarManager::RetrieveLabelFromCommand( const rtl::OUString& aCmdURL )
+{
+ return framework::RetrieveLabelFromCommand(aCmdURL,m_xServiceManager,m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,m_bModuleIdentified,"Name");
+}
+
+void StatusBarManager::CreateControllers()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::CreateControllers" );
+ uno::Reference< lang::XMultiComponentFactory > xStatusbarControllerFactory( m_xStatusbarControllerRegistration, uno::UNO_QUERY );
+ uno::Reference< uno::XComponentContext > xComponentContext;
+ uno::Reference< beans::XPropertySet > xProps( m_xServiceManager, uno::UNO_QUERY );
+ uno::Reference< awt::XWindow > xStatusbarWindow = VCLUnoHelper::GetInterface( m_pStatusBar );
+
+ if ( xProps.is() )
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComponentContext;
+
+ for ( sal_uInt16 i = 0; i < m_pStatusBar->GetItemCount(); i++ )
+ {
+ sal_uInt16 nId = m_pStatusBar->GetItemId( i );
+ if ( nId == 0 )
+ continue;
+
+ rtl::OUString aCommandURL( m_pStatusBar->GetItemCommand( nId ));
+ sal_Bool bInit( sal_True );
+ uno::Reference< frame::XStatusListener > xController;
+
+ svt::StatusbarController* pController( 0 );
+
+ if ( m_xStatusbarControllerRegistration.is() &&
+ m_xStatusbarControllerRegistration->hasController( aCommandURL, m_aModuleIdentifier ))
+ {
+ if ( xStatusbarControllerFactory.is() )
+ {
+ uno::Sequence< uno::Any > aSeq( 5 );
+ beans::PropertyValue aPropValue;
+
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
+ aPropValue.Value = uno::makeAny( m_aModuleIdentifier );
+ aSeq[0] = uno::makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropValue.Value = uno::makeAny( m_xFrame );
+ aSeq[1] = uno::makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
+ aPropValue.Value = uno::makeAny( m_xServiceManager );
+ aSeq[2] = uno::makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
+ aPropValue.Value = uno::makeAny( xStatusbarWindow );
+ aSeq[3] = uno::makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Identifier" ));
+ aPropValue.Value = uno::makeAny( nId );
+ aSeq[4] = uno::makeAny( aPropValue );
+
+ xController = uno::Reference< frame::XStatusListener >(
+ xStatusbarControllerFactory->createInstanceWithArgumentsAndContext(
+ aCommandURL, aSeq, xComponentContext ),
+ uno::UNO_QUERY );
+ bInit = sal_False; // Initialization is done through the factory service
+ }
+ }
+
+ if ( !xController.is() )
+ {
+ pController = CreateStatusBarController( m_xFrame, m_pStatusBar, nId, aCommandURL );
+ if ( !pController )
+ pController = new svt::StatusbarController( m_xServiceManager, m_xFrame, aCommandURL, nId );
+
+ if ( pController )
+ xController = uno::Reference< frame::XStatusListener >(
+ static_cast< ::cppu::OWeakObject *>( pController ),
+ uno::UNO_QUERY );
+ }
+
+ m_aControllerVector.push_back( xController );
+ uno::Reference< lang::XInitialization > xInit( xController, uno::UNO_QUERY );
+
+ if ( xInit.is() )
+ {
+ if ( bInit )
+ {
+ beans::PropertyValue aPropValue;
+ uno::Sequence< uno::Any > aArgs( 5 );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropValue.Value = uno::makeAny( m_xFrame );
+ aArgs[0] = uno::makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
+ aPropValue.Value = uno::makeAny( aCommandURL );
+ aArgs[1] = uno::makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
+ aPropValue.Value = uno::makeAny( m_xServiceManager );
+ aArgs[2] = uno::makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
+ aPropValue.Value = uno::makeAny( xStatusbarWindow );
+ aArgs[3] = uno::makeAny( aPropValue );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Identifier" ));
+ aPropValue.Value = uno::makeAny( nId );
+ aArgs[4] = uno::makeAny( aPropValue );
+ xInit->initialize( aArgs );
+ }
+ }
+ }
+
+ AddFrameActionListener();
+}
+
+void StatusBarManager::AddFrameActionListener()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::AddFrameActionListener" );
+ if ( !m_bFrameActionRegistered && m_xFrame.is() )
+ {
+ m_bFrameActionRegistered = sal_True;
+ m_xFrame->addFrameActionListener( uno::Reference< frame::XFrameActionListener >(
+ static_cast< ::cppu::OWeakObject *>( this ), uno::UNO_QUERY ));
+ }
+}
+
+void StatusBarManager::FillStatusBar( const uno::Reference< container::XIndexAccess >& rItemContainer )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::StatusBarManager::FillStatusbar" );
+
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed || !m_pStatusBar )
+ return;
+
+ sal_uInt16 nId( 1 );
+ rtl::OUString aHelpIdPrefix( RTL_CONSTASCII_USTRINGPARAM( HELPID_PREFIX ));
+
+ RemoveControllers();
+
+ // reset and fill command map
+ m_pStatusBar->Clear();
+ m_aControllerVector.clear();
+
+ for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ )
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::FillStatusBar" );
+ uno::Sequence< beans::PropertyValue > aProp;
+ rtl::OUString aCommandURL;
+ rtl::OUString aHelpURL;
+ sal_Int16 nOffset( 0 );
+ sal_Int16 nStyle( 0 );
+ sal_Int16 nWidth( 0 );
+ sal_uInt16 nType( css_ui::ItemType::DEFAULT );
+
+ try
+ {
+ if ( rItemContainer->getByIndex( n ) >>= aProp )
+ {
+ for ( int i = 0; i < aProp.getLength(); i++ )
+ {
+ if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_COMMANDURL)) )
+ {
+ aProp[i].Value >>= aCommandURL;
+ }
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_HELPURL)) )
+ {
+ aProp[i].Value >>= aHelpURL;
+ }
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_STYLE)) )
+ {
+ aProp[i].Value >>= nStyle;
+ }
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_TYPE)) )
+ {
+ aProp[i].Value >>= nType;
+ }
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_WIDTH)) )
+ {
+ aProp[i].Value >>= nWidth;
+ }
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_OFFSET)) )
+ {
+ aProp[i].Value >>= nOffset;
+ }
+ }
+
+ if (( nType == ::com::sun::star::ui::ItemType::DEFAULT ) && ( aCommandURL.getLength() > 0 ))
+ {
+ rtl::OUString aString( RetrieveLabelFromCommand( aCommandURL ));
+ sal_uInt16 nItemBits( impl_convertItemStyleToItemBits( nStyle ));
+
+ m_pStatusBar->InsertItem( nId, nWidth, nItemBits, nOffset );
+ m_pStatusBar->SetItemCommand( nId, aCommandURL );
+ m_pStatusBar->SetAccessibleName( nId, aString );
+ ++nId;
+ }
+ }
+ }
+ catch ( ::com::sun::star::lang::IndexOutOfBoundsException& )
+ {
+ break;
+ }
+ }
+
+ // Create controllers
+ CreateControllers();
+
+ // Notify controllers that they are now correctly initialized and can start listening
+ UpdateControllers();
+}
+
+void StatusBarManager::StateChanged( StateChangedType )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::StateChanged" );
+}
+
+void StatusBarManager::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::DataChanged" );
+ ResetableGuard aGuard( m_aLock );
+
+ if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
+ ( rDCEvt.GetType() == DATACHANGED_FONTS ) ||
+ ( rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION ) ||
+ ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) &&
+ ( rDCEvt.GetFlags() & SETTINGS_STYLE ))
+ {
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ css::uno::Reference< css::beans::XPropertySet > xPropSet( m_xFrame, css::uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xLayoutManager;
+ if ( xLayoutManager.is() )
+ {
+ aGuard.unlock();
+ xLayoutManager->doLayout();
+ }
+ }
+}
+
+void StatusBarManager::UserDraw( const UserDrawEvent& rUDEvt )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::UserDraw" );
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ sal_uInt16 nId( rUDEvt.GetItemId() );
+ if (( nId > 0 ) && ( nId <= m_aControllerVector.size() ))
+ {
+ uno::Reference< frame::XStatusbarController > xController(
+ m_aControllerVector[nId-1], uno::UNO_QUERY );
+ if ( xController.is() && rUDEvt.GetDevice() )
+ {
+ uno::Reference< awt::XGraphics > xGraphics =
+ rUDEvt.GetDevice()->CreateUnoGraphics();
+
+ awt::Rectangle aRect( rUDEvt.GetRect().Left(),
+ rUDEvt.GetRect().Top(),
+ rUDEvt.GetRect().GetWidth(),
+ rUDEvt.GetRect().GetHeight() );
+ aGuard.unlock();
+ xController->paint( xGraphics, aRect, rUDEvt.GetItemId(), rUDEvt.GetStyle() );
+ }
+ }
+}
+
+void StatusBarManager::Command( const CommandEvent& rEvt )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::Command" );
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ if ( rEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ sal_uInt16 nId = m_pStatusBar->GetItemId( rEvt.GetMousePosPixel() );
+ if (( nId > 0 ) && ( nId <= m_aControllerVector.size() ))
+ {
+ uno::Reference< frame::XStatusbarController > xController(
+ m_aControllerVector[nId-1], uno::UNO_QUERY );
+ if ( xController.is() )
+ {
+ awt::Point aPos;
+ aPos.X = rEvt.GetMousePosPixel().X();
+ aPos.Y = rEvt.GetMousePosPixel().Y();
+ xController->command( aPos, awt::Command::CONTEXTMENU, sal_True, uno::Any() );
+ }
+ }
+ }
+}
+
+void StatusBarManager::MouseMove( const MouseEvent& rMEvt )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::MouseMove" );
+ MouseButton(rMEvt,&frame::XStatusbarController::mouseMove);
+}
+void StatusBarManager::MouseButton( const MouseEvent& rMEvt ,sal_Bool ( SAL_CALL frame::XStatusbarController::*_pMethod )(const ::com::sun::star::awt::MouseEvent&))
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::MouseButton" );
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bDisposed )
+ {
+ sal_uInt16 nId = m_pStatusBar->GetItemId( rMEvt.GetPosPixel() );
+ if (( nId > 0 ) && ( nId <= m_aControllerVector.size() ))
+ {
+ uno::Reference< frame::XStatusbarController > xController(
+ m_aControllerVector[nId-1], uno::UNO_QUERY );
+ if ( xController.is() )
+ {
+ ::com::sun::star::awt::MouseEvent aMouseEvent;
+ aMouseEvent.Buttons = rMEvt.GetButtons();
+ aMouseEvent.X = rMEvt.GetPosPixel().X();
+ aMouseEvent.Y = rMEvt.GetPosPixel().Y();
+ aMouseEvent.ClickCount = rMEvt.GetClicks();
+ (xController.get()->*_pMethod)( aMouseEvent);
+ }
+ } // if (( nId > 0 ) && ( nId <= m_aControllerVector.size() ))
+ }
+}
+void StatusBarManager::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::MouseButtonDown" );
+ MouseButton(rMEvt,&frame::XStatusbarController::mouseButtonDown);
+}
+
+void StatusBarManager::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarManager::MouseButtonUp" );
+ MouseButton(rMEvt,&frame::XStatusbarController::mouseButtonUp);
+}
+
+IMPL_LINK( StatusBarManager, Click, StatusBar*, EMPTYARG )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return 1;
+
+ sal_uInt16 nId = m_pStatusBar->GetCurItemId();
+ if (( nId > 0 ) && ( nId <= m_aControllerVector.size() ))
+ {
+ uno::Reference< frame::XStatusbarController > xController(
+ m_aControllerVector[nId-1], uno::UNO_QUERY );
+ if ( xController.is() )
+ xController->click();
+ }
+
+ return 1;
+}
+
+IMPL_LINK( StatusBarManager, DoubleClick, StatusBar*, EMPTYARG )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return 1;
+
+ sal_uInt16 nId = m_pStatusBar->GetCurItemId();
+ if (( nId > 0 ) && ( nId <= m_aControllerVector.size() ))
+ {
+ uno::Reference< frame::XStatusbarController > xController(
+ m_aControllerVector[nId-1], uno::UNO_QUERY );
+ if ( xController.is() )
+ xController->doubleClick();
+ }
+
+ return 1;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/statusbarwrapper.cxx b/framework/source/uielement/statusbarwrapper.cxx
new file mode 100644
index 000000000000..0281e1be4d88
--- /dev/null
+++ b/framework/source/uielement/statusbarwrapper.cxx
@@ -0,0 +1,205 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <uielement/statusbarwrapper.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include <framework/actiontriggerhelper.hxx>
+#include <uielement/constitemcontainer.hxx>
+#include <uielement/rootitemcontainer.hxx>
+#include <uielement/statusbar.hxx>
+#include <helpid.hrc>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
+#include <com/sun/star/awt/XMenuBar.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <comphelper/processfactory.hxx>
+#include <toolkit/unohlp.hxx>
+
+#include <tools/solar.h>
+#include <vcl/svapp.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::awt;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+StatusBarWrapper::StatusBarWrapper(
+ const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager
+ )
+ : UIConfigElementWrapperBase( UIElementType::STATUSBAR,xServiceManager )
+{
+}
+
+StatusBarWrapper::~StatusBarWrapper()
+{
+}
+
+void SAL_CALL StatusBarWrapper::dispose() throw (::com::sun::star::uno::RuntimeException)
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ com::sun::star::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ ResetableGuard aLock( m_aLock );
+ if ( !m_bDisposed )
+ {
+ if ( m_xStatusBarManager.is() )
+ m_xStatusBarManager->dispose();
+ m_xStatusBarManager.clear();
+ m_xConfigSource.clear();
+ m_xConfigData.clear();
+ m_xServiceFactory.clear();
+
+ m_bDisposed = sal_True;
+ }
+ else
+ throw DisposedException();
+}
+
+// XInitialization
+void SAL_CALL StatusBarWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( !m_bInitialized )
+ {
+ UIConfigElementWrapperBase::initialize( aArguments );
+
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ if ( xFrame.is() && m_xConfigSource.is() )
+ {
+ // Create VCL based toolbar which will be filled with settings data
+ StatusBar* pStatusBar( 0 );
+ StatusBarManager* pStatusBarManager( 0 );
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ if ( pWindow )
+ {
+ sal_uLong nStyles = WinBits( WB_LEFT | WB_3DLOOK );
+
+ pStatusBar = new FrameworkStatusBar( pWindow, nStyles );
+ pStatusBarManager = new StatusBarManager( m_xServiceFactory, xFrame, m_aResourceURL, pStatusBar );
+ ((FrameworkStatusBar*)pStatusBar)->SetStatusBarManager( pStatusBarManager );
+ m_xStatusBarManager = Reference< XComponent >( static_cast< OWeakObject *>( pStatusBarManager ), UNO_QUERY );
+ pStatusBar->SetUniqueId( HID_STATUSBAR );
+ }
+ }
+
+ try
+ {
+ m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
+ if ( m_xConfigData.is() && pStatusBar && pStatusBarManager )
+ {
+ // Fill statusbar with container contents
+ pStatusBarManager->FillStatusBar( m_xConfigData );
+ }
+ }
+ catch ( NoSuchElementException& )
+ {
+ }
+ }
+ }
+}
+
+// XUIElementSettings
+void SAL_CALL StatusBarWrapper::updateSettings() throw ( RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_bPersistent &&
+ m_xConfigSource.is() &&
+ m_xStatusBarManager.is() )
+ {
+ try
+ {
+ StatusBarManager* pStatusBarManager = static_cast< StatusBarManager *>( m_xStatusBarManager.get() );
+
+ m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
+ if ( m_xConfigData.is() )
+ pStatusBarManager->FillStatusBar( m_xConfigData );
+ }
+ catch ( NoSuchElementException& )
+ {
+ }
+ }
+}
+
+Reference< XInterface > SAL_CALL StatusBarWrapper::getRealInterface() throw ( RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_xStatusBarManager.is() )
+ {
+ StatusBarManager* pStatusBarManager = static_cast< StatusBarManager *>( m_xStatusBarManager.get() );
+ if ( pStatusBarManager )
+ {
+ Window* pWindow = (Window *)pStatusBarManager->GetStatusBar();
+ if ( pWindow )
+ return Reference< XInterface >( VCLUnoHelper::GetInterface( pWindow ), UNO_QUERY );
+ }
+ }
+
+ return Reference< XInterface >();
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/statusindicatorinterfacewrapper.cxx b/framework/source/uielement/statusindicatorinterfacewrapper.cxx
new file mode 100644
index 000000000000..28bc86fb49b5
--- /dev/null
+++ b/framework/source/uielement/statusindicatorinterfacewrapper.cxx
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uielement/statusindicatorinterfacewrapper.hxx>
+#include <uielement/progressbarwrapper.hxx>
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+
+namespace framework
+{
+
+
+StatusIndicatorInterfaceWrapper::StatusIndicatorInterfaceWrapper(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& rStatusIndicatorImpl ) :
+ m_xStatusIndicatorImpl( rStatusIndicatorImpl )
+{
+}
+
+StatusIndicatorInterfaceWrapper::~StatusIndicatorInterfaceWrapper()
+{
+}
+
+
+void SAL_CALL StatusIndicatorInterfaceWrapper::start(
+ const ::rtl::OUString& sText,
+ sal_Int32 nRange )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ Reference< XComponent > xComp( m_xStatusIndicatorImpl );
+ if ( xComp.is() )
+ {
+ ProgressBarWrapper* pProgressBar = (ProgressBarWrapper*)xComp.get();
+ if ( pProgressBar )
+ pProgressBar->start( sText, nRange );
+ }
+}
+
+void SAL_CALL StatusIndicatorInterfaceWrapper::end()
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ Reference< XComponent > xComp( m_xStatusIndicatorImpl );
+ if ( xComp.is() )
+ {
+ ProgressBarWrapper* pProgressBar = (ProgressBarWrapper*)xComp.get();
+ if ( pProgressBar )
+ pProgressBar->end();
+ }
+}
+
+void SAL_CALL StatusIndicatorInterfaceWrapper::reset()
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ Reference< XComponent > xComp( m_xStatusIndicatorImpl );
+ if ( xComp.is() )
+ {
+ ProgressBarWrapper* pProgressBar = (ProgressBarWrapper*)xComp.get();
+ if ( pProgressBar )
+ pProgressBar->reset();
+ }
+}
+
+void SAL_CALL StatusIndicatorInterfaceWrapper::setText(
+ const ::rtl::OUString& sText )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ Reference< XComponent > xComp( m_xStatusIndicatorImpl );
+ if ( xComp.is() )
+ {
+ ProgressBarWrapper* pProgressBar = (ProgressBarWrapper*)xComp.get();
+ if ( pProgressBar )
+ pProgressBar->setText( sText );
+ }
+}
+
+void SAL_CALL StatusIndicatorInterfaceWrapper::setValue(
+ sal_Int32 nValue )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ Reference< XComponent > xComp( m_xStatusIndicatorImpl );
+ if ( xComp.is() )
+ {
+ ProgressBarWrapper* pProgressBar = (ProgressBarWrapper*)xComp.get();
+ if ( pProgressBar )
+ pProgressBar->setValue( nValue );
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/togglebuttontoolbarcontroller.cxx b/framework/source/uielement/togglebuttontoolbarcontroller.cxx
new file mode 100644
index 000000000000..0e310669b0fd
--- /dev/null
+++ b/framework/source/uielement/togglebuttontoolbarcontroller.cxx
@@ -0,0 +1,320 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include "uielement/togglebuttontoolbarcontroller.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <framework/addonsoptions.hxx>
+#include "uielement/toolbar.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/XControlNotificationListener.hpp>
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <rtl/uri.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vcl/window.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/bitmap.hxx>
+#include <svtools/filter.hxx>
+#include <svtools/miscopt.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::util;
+
+namespace framework
+{
+
+// ------------------------------------------------------------------
+
+ToggleButtonToolbarController::ToggleButtonToolbarController(
+ const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nID,
+ Style eStyle,
+ const ::rtl::OUString& aCommand ) :
+ ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand ),
+ m_eStyle( eStyle )
+{
+ if ( eStyle == STYLE_DROPDOWNBUTTON )
+ m_pToolbar->SetItemBits( m_nID, TIB_DROPDOWNONLY | m_pToolbar->GetItemBits( m_nID ) );
+ else if ( eStyle == STYLE_TOGGLE_DROPDOWNBUTTON )
+ m_pToolbar->SetItemBits( m_nID, TIB_DROPDOWN | m_pToolbar->GetItemBits( m_nID ) );
+}
+
+// ------------------------------------------------------------------
+
+ToggleButtonToolbarController::~ToggleButtonToolbarController()
+{
+}
+
+// ------------------------------------------------------------------
+
+void SAL_CALL ToggleButtonToolbarController::dispose()
+throw ( RuntimeException )
+{
+ SolarMutexGuard aSolarMutexGuard;
+ ComplexToolbarController::dispose();
+}
+
+// ------------------------------------------------------------------
+Sequence<PropertyValue> ToggleButtonToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
+{
+ Sequence<PropertyValue> aArgs( 2 );
+
+ // Add key modifier to argument list
+ aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
+ aArgs[0].Value <<= KeyModifier;
+ aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ));
+ aArgs[1].Value <<= m_aCurrentSelection;
+ return aArgs;
+}
+
+// ------------------------------------------------------------------
+
+uno::Reference< awt::XWindow > SAL_CALL ToggleButtonToolbarController::createPopupWindow()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ uno::Reference< awt::XWindow > xWindow;
+
+ SolarMutexGuard aSolarMutexGuard;
+ if (( m_eStyle == STYLE_DROPDOWNBUTTON ) ||
+ ( m_eStyle == STYLE_TOGGLE_DROPDOWNBUTTON ))
+ {
+ // create popup menu
+ PopupMenu aPopup;
+ const sal_uInt32 nCount = m_aDropdownMenuList.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ rtl::OUString aLabel( m_aDropdownMenuList[i] );
+ aPopup.InsertItem( sal_uInt16( i+1 ), aLabel );
+ if ( aLabel == m_aCurrentSelection )
+ aPopup.CheckItem( sal_uInt16( i+1 ), sal_True );
+ else
+ aPopup.CheckItem( sal_uInt16( i+1 ), sal_False );
+ }
+
+ m_pToolbar->SetItemDown( m_nID, sal_True );
+ aPopup.SetSelectHdl( LINK( this, ToggleButtonToolbarController, MenuSelectHdl ));
+ aPopup.Execute( m_pToolbar, m_pToolbar->GetItemRect( m_nID ));
+ m_pToolbar->SetItemDown( m_nID, sal_False );
+ }
+
+ return xWindow;
+}
+
+// ------------------------------------------------------------------
+
+void ToggleButtonToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
+{
+ SolarMutexGuard aSolarMutexGuard;
+
+ if (( m_eStyle == STYLE_DROPDOWNBUTTON ) ||
+ ( m_eStyle == STYLE_TOGGLE_DROPDOWNBUTTON ))
+ {
+ if ( rControlCommand.Command.equalsAsciiL( "SetList", 7 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "List", 4 ))
+ {
+ Sequence< ::rtl::OUString > aList;
+ m_aDropdownMenuList.clear();
+
+ rControlCommand.Arguments[i].Value >>= aList;
+ for ( sal_Int32 j = 0; j < aList.getLength(); j++ )
+ m_aDropdownMenuList.push_back( aList[j] );
+
+ // send notification
+ uno::Sequence< beans::NamedValue > aInfo( 1 );
+ aInfo[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "List" ));
+ aInfo[0].Value <<= aList;
+ addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListChanged" )),
+ getDispatchFromCommand( m_aCommandURL ),
+ aInfo );
+
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "CheckItemPos", 12 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
+ {
+ sal_Int32 nPos( -1 );
+
+ rControlCommand.Arguments[i].Value >>= nPos;
+ if ( nPos >= 0 &&
+ ( sal::static_int_cast< sal_uInt32 >(nPos)
+ < m_aDropdownMenuList.size() ) )
+ {
+ m_aCurrentSelection = m_aDropdownMenuList[nPos];
+
+ // send notification
+ uno::Sequence< beans::NamedValue > aInfo( 1 );
+ aInfo[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ItemChecked" ));
+ aInfo[0].Value <<= nPos;
+ addNotifyInfo( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pos" )),
+ getDispatchFromCommand( m_aCommandURL ),
+ aInfo );
+ }
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "AddEntry", 8 ))
+ {
+ rtl::OUString aText;
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ {
+ if ( rControlCommand.Arguments[i].Value >>= aText )
+ m_aDropdownMenuList.push_back( aText );
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "InsertEntry", 11 ))
+ {
+ sal_Int32 nPos( COMBOBOX_APPEND );
+ sal_Int32 nSize = sal_Int32( m_aDropdownMenuList.size() );
+ rtl::OUString aText;
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
+ {
+ sal_Int32 nTmpPos = 0;
+ if ( rControlCommand.Arguments[i].Value >>= nTmpPos )
+ {
+ if (( nTmpPos >= 0 ) && ( nTmpPos < sal_Int32( nSize )))
+ nPos = nTmpPos;
+ }
+ }
+ else if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ rControlCommand.Arguments[i].Value >>= aText;
+ }
+
+ std::vector< ::rtl::OUString >::iterator aIter = m_aDropdownMenuList.begin();
+ aIter += nPos;
+ m_aDropdownMenuList.insert( aIter, aText );
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryPos", 14 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Pos", 3 ))
+ {
+ sal_Int32 nPos( -1 );
+ if ( rControlCommand.Arguments[i].Value >>= nPos )
+ {
+ if ( nPos < sal_Int32( m_aDropdownMenuList.size() ))
+ {
+ std::vector< ::rtl::OUString >::iterator aIter = m_aDropdownMenuList.begin();
+ aIter += nPos;
+ m_aDropdownMenuList.erase( aIter );
+ }
+ }
+ break;
+ }
+ }
+ }
+ else if ( rControlCommand.Command.equalsAsciiL( "RemoveEntryText", 15 ))
+ {
+ for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
+ {
+ if ( rControlCommand.Arguments[i].Name.equalsAsciiL( "Text", 4 ))
+ {
+ rtl::OUString aText;
+ if ( rControlCommand.Arguments[i].Value >>= aText )
+ {
+ sal_Int32 nSize = sal_Int32( m_aDropdownMenuList.size() );
+ for ( sal_Int32 j = 0; j < nSize; j++ )
+ {
+ if ( m_aDropdownMenuList[j] == aText )
+ {
+ std::vector< ::rtl::OUString >::iterator aIter = m_aDropdownMenuList.begin();
+ aIter += j;
+ m_aDropdownMenuList.erase( aIter );
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+IMPL_LINK( ToggleButtonToolbarController, MenuSelectHdl, Menu *, pMenu )
+{
+ SolarMutexGuard aGuard;
+
+ sal_uInt16 nItemId = pMenu->GetCurItemId();
+ if ( nItemId > 0 && nItemId <= m_aDropdownMenuList.size() )
+ {
+ m_aCurrentSelection = m_aDropdownMenuList[nItemId-1];
+
+ execute( 0 );
+ }
+ return 0;
+}
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/toolbar.cxx b/framework/source/uielement/toolbar.cxx
new file mode 100644
index 000000000000..b0ea29a997de
--- /dev/null
+++ b/framework/source/uielement/toolbar.cxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uielement/toolbar.hxx>
+#include <uielement/toolbarmanager.hxx>
+#include <rtl/logfile.hxx>
+
+namespace framework
+{
+
+ToolBar::ToolBar( Window* pParent, WinBits nWinBits ) :
+ ToolBox( pParent, nWinBits )
+ , m_pToolBarManager( 0 )
+{
+}
+
+ToolBar::~ToolBar()
+{
+}
+
+void ToolBar::SetToolBarManager( ToolBarManager* pTbMgr )
+{
+ m_pToolBarManager = pTbMgr;
+}
+
+void ToolBar::Command( const CommandEvent& rCEvt )
+{
+ if ( m_aCommandHandler.IsSet() )
+ m_aCommandHandler.Call( (void *)( &rCEvt ));
+ ToolBox::Command( rCEvt );
+}
+
+void ToolBar::StateChanged( StateChangedType nType )
+{
+ ToolBox::StateChanged( nType );
+ if ( m_aStateChangedHandler.IsSet() )
+ m_aStateChangedHandler.Call( &nType );
+}
+
+void ToolBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ ToolBox::DataChanged( rDCEvt );
+ if ( m_aDataChangedHandler.IsSet() )
+ m_aDataChangedHandler.Call( (void*)&rDCEvt );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/toolbarmanager.cxx b/framework/source/uielement/toolbarmanager.cxx
new file mode 100644
index 000000000000..f6f59c4e51d6
--- /dev/null
+++ b/framework/source/uielement/toolbarmanager.cxx
@@ -0,0 +1,2325 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/toolbarmanager.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+
+#include <uielement/toolbar.hxx>
+#include <uielement/generictoolbarcontroller.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+#include "general.h"
+#include "properties.h"
+#include <framework/imageproducer.hxx>
+#include <framework/sfxhelperfunctions.hxx>
+#include <classes/fwkresid.hxx>
+#include <classes/resource.hrc>
+#include <framework/addonsoptions.hxx>
+#include <uielement/toolbarmerger.hxx>
+#include <framework/acceleratorinfo.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XDockableWindow.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/ui/DockingArea.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+#include <com/sun/star/ui/XUIElementSettings.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <comphelper/sequence.hxx>
+#include <com/sun/star/frame/status/Visibility.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <svtools/imgdef.hxx>
+#include <svtools/toolboxcontroller.hxx>
+#include <unotools/cmdoptions.hxx>
+#include <toolkit/unohlp.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <svtools/miscopt.hxx>
+#include <svl/imageitm.hxx>
+#include <svtools/framestatuslistener.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/syswin.hxx>
+#include <vcl/taskpanelist.hxx>
+#include <rtl/logfile.hxx>
+#include <svtools/menuoptions.hxx>
+#include <unotools/cmdoptions.hxx>
+#include <boost/bind.hpp>
+#include <svtools/acceleratorexecute.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using rtl::OUString;
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::graphic;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::ui;
+using namespace ::com::sun::star;
+
+namespace framework
+{
+
+static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
+static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL";
+static const char ITEM_DESCRIPTOR_TOOLTIP[] = "Tooltip";
+static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer";
+static const char ITEM_DESCRIPTOR_LABEL[] = "Label";
+static const char ITEM_DESCRIPTOR_TYPE[] = "Type";
+static const char ITEM_DESCRIPTOR_VISIBLE[] = "IsVisible";
+static const char ITEM_DESCRIPTOR_WIDTH[] = "Width";
+static const char ITEM_DESCRIPTOR_STYLE[] = "Style";
+
+static const sal_Int32 ITEM_DESCRIPTOR_COMMANDURL_LEN = RTL_CONSTASCII_LENGTH(ITEM_DESCRIPTOR_COMMANDURL);
+static const sal_Int32 ITEM_DESCRIPTOR_HELPURL_LEN = RTL_CONSTASCII_LENGTH(ITEM_DESCRIPTOR_HELPURL);
+static const sal_Int32 ITEM_DESCRIPTOR_TOOLTIP_LEN = RTL_CONSTASCII_LENGTH(ITEM_DESCRIPTOR_TOOLTIP);
+static const sal_Int32 ITEM_DESCRIPTOR_CONTAINER_LEN = RTL_CONSTASCII_LENGTH(ITEM_DESCRIPTOR_CONTAINER);
+static const sal_Int32 ITEM_DESCRIPTOR_LABEL_LEN = RTL_CONSTASCII_LENGTH(ITEM_DESCRIPTOR_LABEL);
+static const sal_Int32 ITEM_DESCRIPTOR_TYPE_LEN = RTL_CONSTASCII_LENGTH(ITEM_DESCRIPTOR_TYPE);
+static const sal_Int32 ITEM_DESCRIPTOR_VISIBLE_LEN = RTL_CONSTASCII_LENGTH(ITEM_DESCRIPTOR_VISIBLE);
+static const sal_Int32 ITEM_DESCRIPTOR_WIDTH_LEN = RTL_CONSTASCII_LENGTH(ITEM_DESCRIPTOR_WIDTH);
+static const sal_Int32 ITEM_DESCRIPTOR_STYLE_LEN = RTL_CONSTASCII_LENGTH(ITEM_DESCRIPTOR_STYLE);
+
+static const char HELPID_PREFIX[] = "helpid:";
+static const char HELPID_PREFIX_TESTTOOL[] = ".HelpId:";
+static const sal_uInt16 STARTID_CUSTOMIZE_POPUPMENU = 1000;
+
+#define MENUPREFIX "private:resource/menubar/"
+
+class ImageOrientationListener : public svt::FrameStatusListener
+{
+ public:
+ ImageOrientationListener( const Reference< XStatusListener > rReceiver,
+ const Reference< XMultiServiceFactory > rServiceManager,
+ const Reference< XFrame > rFrame );
+ virtual ~ImageOrientationListener();
+
+ virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException );
+
+ private:
+ Reference< XStatusListener > m_xReceiver;
+};
+
+ImageOrientationListener::ImageOrientationListener(
+ const Reference< XStatusListener > rReceiver,
+ const Reference< XMultiServiceFactory > rServiceManager,
+ const Reference< XFrame > rFrame ) :
+ FrameStatusListener( rServiceManager, rFrame ),
+ m_xReceiver( rReceiver )
+{
+}
+
+ImageOrientationListener::~ImageOrientationListener()
+{
+}
+
+void SAL_CALL ImageOrientationListener::statusChanged( const FeatureStateEvent& Event )
+throw ( RuntimeException )
+{
+ if ( m_xReceiver.is() )
+ m_xReceiver->statusChanged( Event );
+}
+
+//*****************************************************************************************************************
+
+static sal_Int16 getImageTypeFromBools( sal_Bool bBig )
+{
+ sal_Int16 n( 0 );
+ if ( bBig )
+ n |= ::com::sun::star::ui::ImageType::SIZE_LARGE;
+ return n;
+}
+
+static ::com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > getLayoutManagerFromFrame(
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame )
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager;
+
+ Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xLayoutManager;
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ return xLayoutManager;
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XINTERFACE_6 ( ToolBarManager ,
+ OWeakObject ,
+ DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ),
+ DIRECT_INTERFACE( ::com::sun::star::lang::XComponent ),
+ DIRECT_INTERFACE( ::com::sun::star::frame::XFrameActionListener ),
+ DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationListener ),
+ DIRECT_INTERFACE( ::com::sun::star::frame::XStatusListener ),
+ DERIVED_INTERFACE( ::com::sun::star::lang::XEventListener, ::com::sun::star::frame::XFrameActionListener )
+ )
+
+DEFINE_XTYPEPROVIDER_6 ( ToolBarManager ,
+ ::com::sun::star::lang::XTypeProvider ,
+ ::com::sun::star::lang::XComponent ,
+ ::com::sun::star::ui::XUIConfigurationListener ,
+ ::com::sun::star::frame::XFrameActionListener ,
+ ::com::sun::star::frame::XStatusListener ,
+ ::com::sun::star::lang::XEventListener
+ )
+
+ToolBarManager::ToolBarManager( const Reference< XMultiServiceFactory >& rServiceManager,
+ const Reference< XFrame >& rFrame,
+ const rtl::OUString& rResourceName,
+ ToolBar* pToolBar ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ OWeakObject(),
+ m_bDisposed( sal_False ),
+ m_bSmallSymbols( !SvtMiscOptions().AreCurrentSymbolsLarge() ),
+ m_bModuleIdentified( sal_False ),
+ m_bAddedToTaskPaneList( sal_True ),
+ m_bFrameActionRegistered( sal_False ),
+ m_bUpdateControllers( sal_False ),
+ m_bImageOrientationRegistered( sal_False ),
+ m_bImageMirrored( sal_False ),
+ m_bCanBeCustomized( !SvtMiscOptions().DisableUICustomization() ),
+ m_lImageRotation( 0 ),
+ m_pToolBar( pToolBar ),
+ m_aResourceName( rResourceName ),
+ m_xFrame( rFrame ),
+ m_aListenerContainer( m_aLock.getShareableOslMutex() ),
+ m_xServiceManager( rServiceManager ),
+ m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() ),
+ m_bAcceleratorCfg( sal_False )
+{
+ Window* pWindow = m_pToolBar;
+ while ( pWindow && !pWindow->IsSystemWindow() )
+ pWindow = pWindow->GetParent();
+
+ if ( pWindow )
+ ((SystemWindow *)pWindow)->GetTaskPaneList()->AddWindow( m_pToolBar );
+
+ if ( m_xServiceManager.is() )
+ {
+ m_xToolbarControllerRegistration = Reference< XUIControllerRegistration >(
+ m_xServiceManager->createInstance( SERVICENAME_TOOLBARCONTROLLERFACTORY ),
+ UNO_QUERY );
+
+ m_xURLTransformer.set( m_xServiceManager->createInstance(
+ SERVICENAME_URLTRANSFORMER),
+ UNO_QUERY );
+ }
+
+ m_pToolBar->SetSelectHdl( LINK( this, ToolBarManager, Select) );
+ m_pToolBar->SetActivateHdl( LINK( this, ToolBarManager, Activate) );
+ m_pToolBar->SetDeactivateHdl( LINK( this, ToolBarManager, Deactivate) );
+ m_pToolBar->SetClickHdl( LINK( this, ToolBarManager, Click ) );
+ m_pToolBar->SetDropdownClickHdl( LINK( this, ToolBarManager, DropdownClick ) );
+ m_pToolBar->SetDoubleClickHdl( LINK( this, ToolBarManager, DoubleClick ) );
+ m_pToolBar->SetStateChangedHdl( LINK( this, ToolBarManager, StateChanged ) );
+ m_pToolBar->SetDataChangedHdl( LINK( this, ToolBarManager, DataChanged ) );
+ m_pToolBar->SetToolboxButtonSize( m_bSmallSymbols ? TOOLBOX_BUTTONSIZE_SMALL : TOOLBOX_BUTTONSIZE_LARGE );
+
+ // enables a menu for clipped items and customization
+ SvtCommandOptions aCmdOptions;
+ sal_uInt16 nMenuType = TOOLBOX_MENUTYPE_CLIPPEDITEMS;
+ if ( !aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CreateDialog"))))
+ nMenuType |= TOOLBOX_MENUTYPE_CUSTOMIZE;
+ //added for issue33668 by shizhoubo
+ m_pToolBar->SetCommandHdl( LINK( this, ToolBarManager, Command ) );
+ //end
+ m_pToolBar->SetMenuType( nMenuType );
+ m_pToolBar->SetMenuButtonHdl( LINK( this, ToolBarManager, MenuButton ) );
+ m_pToolBar->GetMenu()->SetSelectHdl( LINK( this, ToolBarManager, MenuSelect ) );
+ m_pToolBar->GetMenu()->SetDeactivateHdl( LINK( this, ToolBarManager, MenuDeactivate ) );
+
+ // set name for testtool, the useful part is after the last '/'
+ sal_Int32 idx = rResourceName.lastIndexOf('/');
+ idx++; // will become 0 if '/' not found: use full string
+ ::rtl::OString aHelpIdAsString( HELPID_PREFIX_TESTTOOL );
+ ::rtl::OUString aToolbarName = rResourceName.copy( idx );
+ aHelpIdAsString += rtl::OUStringToOString( aToolbarName, RTL_TEXTENCODING_UTF8 );;
+ m_pToolBar->SetHelpId( aHelpIdAsString );
+
+ m_aAsyncUpdateControllersTimer.SetTimeout( 50 );
+ m_aAsyncUpdateControllersTimer.SetTimeoutHdl( LINK( this, ToolBarManager, AsyncUpdateControllersHdl ) );
+}
+
+ToolBarManager::~ToolBarManager()
+{
+ OSL_ASSERT( m_pToolBar == 0 );
+ OSL_ASSERT( !m_bAddedToTaskPaneList );
+}
+
+void ToolBarManager::Destroy()
+{
+ ResetableGuard aGuard( m_aLock );
+ if ( m_bAddedToTaskPaneList )
+ {
+ Window* pWindow = m_pToolBar;
+ while ( pWindow && !pWindow->IsSystemWindow() )
+ pWindow = pWindow->GetParent();
+
+ if ( pWindow )
+ ((SystemWindow *)pWindow)->GetTaskPaneList()->RemoveWindow( m_pToolBar );
+ m_bAddedToTaskPaneList = sal_False;
+ }
+
+ // Delete the additional add-ons data
+ for ( sal_uInt16 i = 0; i < m_pToolBar->GetItemCount(); i++ )
+ {
+ sal_uInt16 nItemId = m_pToolBar->GetItemId( i );
+ if ( nItemId > 0 )
+ delete static_cast< AddonsParams* >( m_pToolBar->GetItemData( nItemId ));
+ }
+
+ // Hide toolbar as lazy delete can destroy the toolbar much later.
+ m_pToolBar->Hide();
+ /* #i99167# removed change for i93173 since there is some weird crash */
+ // #i93173# delete toolbar lazily as we can still be in one of its handlers
+ m_pToolBar->doLazyDelete();
+
+ Link aEmpty;
+ m_pToolBar->SetSelectHdl( aEmpty );
+ m_pToolBar->SetActivateHdl( aEmpty );
+ m_pToolBar->SetDeactivateHdl( aEmpty );
+ m_pToolBar->SetClickHdl( aEmpty );
+ m_pToolBar->SetDropdownClickHdl( aEmpty );
+ m_pToolBar->SetDoubleClickHdl( aEmpty );
+ m_pToolBar->SetStateChangedHdl( aEmpty );
+ m_pToolBar->SetDataChangedHdl( aEmpty );
+
+ m_pToolBar = 0;
+}
+
+ToolBox* ToolBarManager::GetToolBar() const
+{
+ ResetableGuard aGuard( m_aLock );
+ return m_pToolBar;
+}
+
+void ToolBarManager::CheckAndUpdateImages()
+{
+ ResetableGuard aGuard( m_aLock );
+ sal_Bool bRefreshImages = sal_False;
+
+ SvtMiscOptions aMiscOptions;
+ bool bCurrentSymbolsSmall = !aMiscOptions.AreCurrentSymbolsLarge();
+ if ( m_bSmallSymbols != bCurrentSymbolsSmall )
+ {
+ bRefreshImages = sal_True;
+ m_bSmallSymbols = bCurrentSymbolsSmall;
+ }
+
+ sal_Int16 nCurrentSymbolsStyle = aMiscOptions.GetCurrentSymbolsStyle();
+ if ( m_nSymbolsStyle != nCurrentSymbolsStyle )
+ {
+ bRefreshImages = sal_True;
+ m_nSymbolsStyle = nCurrentSymbolsStyle;
+ }
+
+ // Refresh images if requested
+ if ( bRefreshImages )
+ RefreshImages();
+}
+
+void ToolBarManager::RefreshImages()
+{
+ ResetableGuard aGuard( m_aLock );
+
+ sal_Bool bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() );
+ for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); nPos++ )
+ {
+ sal_uInt16 nId( m_pToolBar->GetItemId( nPos ) );
+
+ if ( nId > 0 )
+ {
+ ::rtl::OUString aCommandURL = m_pToolBar->GetItemCommand( nId );
+ Image aImage = GetImageFromURL( m_xFrame, aCommandURL, bBigImages );
+ // Try also to query for add-on images before giving up and use an
+ // empty image.
+ if ( !aImage )
+ aImage = QueryAddonsImage( aCommandURL, bBigImages );
+ m_pToolBar->SetItemImage( nId, aImage );
+ }
+ }
+
+ m_pToolBar->SetToolboxButtonSize( bBigImages ? TOOLBOX_BUTTONSIZE_LARGE : TOOLBOX_BUTTONSIZE_SMALL );
+ ::Size aSize = m_pToolBar->CalcWindowSizePixel();
+ m_pToolBar->SetOutputSizePixel( aSize );
+}
+
+void ToolBarManager::UpdateImageOrientation()
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_xUICommandLabels.is() )
+ {
+ sal_Int32 i;
+ Sequence< rtl::OUString > aSeqMirrorCmd;
+ Sequence< rtl::OUString > aSeqRotateCmd;
+ m_xUICommandLabels->getByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDMIRRORIMAGELIST ))) >>= aSeqMirrorCmd;
+ m_xUICommandLabels->getByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDROTATEIMAGELIST ))) >>= aSeqRotateCmd;
+
+ CommandToInfoMap::iterator pIter;
+ for ( i = 0; i < aSeqMirrorCmd.getLength(); i++ )
+ {
+ rtl::OUString aMirrorCmd = aSeqMirrorCmd[i];
+ pIter = m_aCommandMap.find( aMirrorCmd );
+ if ( pIter != m_aCommandMap.end() )
+ pIter->second.bMirrored = sal_True;
+ }
+ for ( i = 0; i < aSeqRotateCmd.getLength(); i++ )
+ {
+ rtl::OUString aRotateCmd = aSeqRotateCmd[i];
+ pIter = m_aCommandMap.find( aRotateCmd );
+ if ( pIter != m_aCommandMap.end() )
+ pIter->second.bRotated = sal_True;
+ }
+ }
+
+ for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); nPos++ )
+ {
+ sal_uInt16 nId = m_pToolBar->GetItemId( nPos );
+ if ( nId > 0 )
+ {
+ rtl::OUString aCmd = m_pToolBar->GetItemCommand( nId );
+
+ CommandToInfoMap::const_iterator pIter = m_aCommandMap.find( aCmd );
+ if ( pIter != m_aCommandMap.end() )
+ {
+ if ( pIter->second.bRotated )
+ {
+ m_pToolBar->SetItemImageMirrorMode( nId, sal_False );
+ m_pToolBar->SetItemImageAngle( nId, m_lImageRotation );
+ }
+ if ( pIter->second.bMirrored )
+ m_pToolBar->SetItemImageMirrorMode( nId, m_bImageMirrored );
+ }
+ }
+ }
+}
+
+void ToolBarManager::UpdateControllers()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ToolBarManager::UpdateControllers" );
+
+ if( !m_bCanBeCustomized )
+ {
+ Any a;
+ Reference< XLayoutManager > xLayoutManager;
+ Reference< XPropertySet > xFramePropSet( m_xFrame, UNO_QUERY );
+ if ( xFramePropSet.is() )
+ a = xFramePropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" )));
+ a >>= xLayoutManager;
+ Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY );
+ if ( xLayoutManager.is() && xDockable.is() )
+ {
+ ::com::sun::star::awt::Point aPoint;
+ aPoint.X = aPoint.Y = SAL_MAX_INT32;
+ xLayoutManager->dockWindow( m_aResourceName, DockingArea_DOCKINGAREA_DEFAULT, aPoint );
+ xLayoutManager->lockWindow( m_aResourceName );
+ }
+ }
+
+ if ( !m_bUpdateControllers )
+ {
+ m_bUpdateControllers = sal_True;
+ ToolBarControllerMap::iterator pIter = m_aControllerMap.begin();
+
+ while ( pIter != m_aControllerMap.end() )
+ {
+ try
+ {
+ Reference< XUpdatable > xUpdatable( pIter->second, UNO_QUERY );
+ if ( xUpdatable.is() )
+ xUpdatable->update();
+ }
+ catch ( Exception& )
+ {
+ }
+ ++pIter;
+ }
+ }
+ m_bUpdateControllers = sal_False;
+}
+//for update toolbar controller via Support Visible by shizhoubo
+void ToolBarManager::UpdateController( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XToolbarController > xController)
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ToolBarManager::UpdateControllers" );
+
+ if ( !m_bUpdateControllers )
+ {
+ m_bUpdateControllers = sal_True;
+ try
+ { if(xController.is())
+ {
+ Reference< XUpdatable > xUpdatable( xController, UNO_QUERY );
+ if ( xUpdatable.is() )
+ xUpdatable->update();
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+
+ }
+ m_bUpdateControllers = sal_False;
+}
+//end
+void ToolBarManager::frameAction( const FrameActionEvent& Action )
+throw ( RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+ if ( Action.Action == FrameAction_CONTEXT_CHANGED )
+ m_aAsyncUpdateControllersTimer.Start();
+}
+
+void SAL_CALL ToolBarManager::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event )
+throw ( ::com::sun::star::uno::RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+ if ( m_bDisposed )
+ return;
+
+ if ( Event.FeatureURL.Complete.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".uno:ImageOrientation")) )
+ {
+ SfxImageItem aItem( 1, 0 );
+ aItem.PutValue( Event.State );
+
+ m_lImageRotation = aItem.GetRotation();
+ m_bImageMirrored = aItem.IsMirrored();
+ UpdateImageOrientation();
+ }
+}
+
+void SAL_CALL ToolBarManager::disposing( const EventObject& Source ) throw ( RuntimeException )
+{
+ {
+ ResetableGuard aGuard( m_aLock );
+ if ( m_bDisposed )
+ return;
+ }
+
+ RemoveControllers();
+
+ {
+ ResetableGuard aGuard( m_aLock );
+ if ( m_xDocImageManager.is() )
+ {
+ try
+ {
+ m_xDocImageManager->removeConfigurationListener(
+ Reference< XUIConfigurationListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ if ( m_xModuleImageManager.is() )
+ {
+ try
+ {
+ m_xModuleImageManager->removeConfigurationListener(
+ Reference< XUIConfigurationListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ if ( m_xImageOrientationListener.is() )
+ {
+ ImageOrientationListener* pImageOrientation =
+ (ImageOrientationListener*)m_xImageOrientationListener.get();
+ pImageOrientation->unbindListener();
+ m_xImageOrientationListener.clear();
+ }
+
+ m_xDocImageManager.clear();
+ m_xModuleImageManager.clear();
+
+ if ( Source.Source == Reference< XInterface >( m_xFrame, UNO_QUERY ))
+ m_xFrame.clear();
+
+ m_xServiceManager.clear();
+ }
+}
+
+// XComponent
+void SAL_CALL ToolBarManager::dispose() throw( RuntimeException )
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ // stop timer to prevent timer events after dispose
+ m_aAsyncUpdateControllersTimer.Stop();
+
+ RemoveControllers();
+
+ if ( m_xDocImageManager.is() )
+ {
+ try
+ {
+ m_xDocImageManager->removeConfigurationListener(
+ Reference< XUIConfigurationListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ m_xDocImageManager.clear();
+ if ( m_xModuleImageManager.is() )
+ {
+ try
+ {
+ m_xModuleImageManager->removeConfigurationListener(
+ Reference< XUIConfigurationListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ m_xModuleImageManager.clear();
+
+ ImplClearPopupMenu( m_pToolBar );
+
+ // We have to destroy our toolbar instance now.
+ Destroy();
+
+ if ( m_bFrameActionRegistered && m_xFrame.is() )
+ {
+ try
+ {
+ m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >(
+ static_cast< ::cppu::OWeakObject *>( this ), UNO_QUERY ));
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ if ( m_xImageOrientationListener.is() )
+ {
+ ImageOrientationListener* pImageOrientation =
+ (ImageOrientationListener*)m_xImageOrientationListener.get();
+ pImageOrientation->unbindListener();
+ m_xImageOrientationListener.clear();
+ }
+
+ m_xFrame.clear();
+ m_xServiceManager.clear();
+ m_xGlobalAcceleratorManager.clear();
+ m_xModuleAcceleratorManager.clear();
+ m_xDocAcceleratorManager.clear();
+
+ m_bDisposed = sal_True;
+ }
+}
+
+void SAL_CALL ToolBarManager::addEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+void SAL_CALL ToolBarManager::removeEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException )
+{
+ m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
+}
+
+// XUIConfigurationListener
+void SAL_CALL ToolBarManager::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
+{
+ impl_elementChanged(false,Event);
+}
+
+void SAL_CALL ToolBarManager::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
+{
+ impl_elementChanged(true,Event);
+}
+void ToolBarManager::impl_elementChanged(bool _bRemove,const ::com::sun::star::ui::ConfigurationEvent& Event )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ /* SAFE AREA ----------------------------------------------------------------------------------------------- */
+ if ( m_bDisposed )
+ return;
+
+ Reference< XNameAccess > xNameAccess;
+ sal_Int16 nImageType = sal_Int16();
+ sal_Int16 nCurrentImageType = getImageTypeFromBools(
+ SvtMiscOptions().AreCurrentSymbolsLarge()
+ );
+
+ if (( Event.aInfo >>= nImageType ) &&
+ ( nImageType == nCurrentImageType ) &&
+ ( Event.Element >>= xNameAccess ))
+ {
+ sal_Int16 nImageInfo( 1 );
+ Reference< XInterface > xIfacDocImgMgr( m_xDocImageManager, UNO_QUERY );
+ if ( xIfacDocImgMgr == Event.Source )
+ nImageInfo = 0;
+
+ Sequence< rtl::OUString > aSeq = xNameAccess->getElementNames();
+ for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ )
+ {
+ CommandToInfoMap::iterator pIter = m_aCommandMap.find( aSeq[i] );
+ if ( pIter != m_aCommandMap.end() && ( pIter->second.nImageInfo >= nImageInfo ))
+ {
+ if ( _bRemove )
+ {
+ Image aImage;
+ if (( pIter->second.nImageInfo == 0 ) && ( pIter->second.nImageInfo == nImageInfo ))
+ {
+ // Special case: An image from the document image manager has been removed.
+ // It is possible that we have a image at our module image manager. Before
+ // we can remove our image we have to ask our module image manager.
+ Sequence< rtl::OUString > aCmdURLSeq( 1 );
+ Sequence< Reference< XGraphic > > aGraphicSeq;
+ aCmdURLSeq[0] = pIter->first;
+ aGraphicSeq = m_xModuleImageManager->getImages( nImageType, aCmdURLSeq );
+ aImage = Image( aGraphicSeq[0] );
+ }
+
+ setToolBarImage(aImage,pIter);
+ } // if ( _bRemove )
+ else
+ {
+ Reference< XGraphic > xGraphic;
+ if ( xNameAccess->getByName( aSeq[i] ) >>= xGraphic )
+ {
+ Image aImage( xGraphic );
+ setToolBarImage(aImage,pIter);
+ }
+ pIter->second.nImageInfo = nImageInfo;
+ }
+ }
+ }
+ }
+}
+void ToolBarManager::setToolBarImage(const Image& _aImage,const CommandToInfoMap::const_iterator& _pIter)
+{
+ const ::std::vector< sal_uInt16 >& _rIDs = _pIter->second.aIds;
+ m_pToolBar->SetItemImage( _pIter->second.nId, _aImage );
+ ::std::for_each(_rIDs.begin(),_rIDs.end(),::boost::bind(&ToolBar::SetItemImage,m_pToolBar,_1,_aImage));
+}
+
+void SAL_CALL ToolBarManager::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
+{
+ impl_elementChanged(false,Event);
+}
+
+void ToolBarManager::RemoveControllers()
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ m_aSubToolBarControllerMap.clear();
+
+
+ // i90033
+ // Remove item window pointers from the toolbar. They were
+ // destroyed by the dispose() at the XComponent. This is needed
+ // as VCL code later tries to access the item window data in certain
+ // dtors where the item window is already invalid!
+ for ( sal_uInt16 i = 0; i < m_pToolBar->GetItemCount(); i++ )
+ {
+ sal_uInt16 nItemId = m_pToolBar->GetItemId( i );
+ if ( nItemId > 0 )
+ {
+ Reference< XComponent > xComponent( m_aControllerMap[ nItemId ], UNO_QUERY );
+ if ( xComponent.is() )
+ {
+ try
+ {
+ xComponent->dispose();
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ m_pToolBar->SetItemWindow(nItemId, 0);
+ }
+ }
+ m_aControllerMap.clear();
+}
+
+uno::Sequence< beans::PropertyValue > ToolBarManager::GetPropsForCommand( const ::rtl::OUString& rCmdURL )
+{
+ Sequence< PropertyValue > aPropSeq;
+
+ // Retrieve properties for command
+ try
+ {
+ if ( !m_bModuleIdentified )
+ {
+ Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
+ Reference< XInterface > xIfac( m_xFrame, UNO_QUERY );
+
+ m_bModuleIdentified = sal_True;
+ m_aModuleIdentifier = xModuleManager->identify( xIfac );
+
+ if ( m_aModuleIdentifier.getLength() > 0 )
+ {
+ Reference< XNameAccess > xNameAccess( m_xServiceManager->createInstance( SERVICENAME_UICOMMANDDESCRIPTION ), UNO_QUERY );
+ if ( xNameAccess.is() )
+ xNameAccess->getByName( m_aModuleIdentifier ) >>= m_xUICommandLabels;
+ }
+ }
+
+ if ( m_xUICommandLabels.is() )
+ {
+ if ( rCmdURL.getLength() > 0 )
+ m_xUICommandLabels->getByName( rCmdURL ) >>= aPropSeq;
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ return aPropSeq;
+}
+
+::rtl::OUString ToolBarManager::RetrieveLabelFromCommand( const ::rtl::OUString& aCmdURL )
+{
+ ::rtl::OUString aLabel;
+ Sequence< PropertyValue > aPropSeq;
+
+ // Retrieve popup menu labels
+ aPropSeq = GetPropsForCommand( aCmdURL );
+ for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
+ {
+ if ( aPropSeq[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Name")) )
+ {
+ aPropSeq[i].Value >>= aLabel;
+ break;
+ }
+ }
+ return aLabel;
+}
+
+sal_Int32 ToolBarManager::RetrievePropertiesFromCommand( const ::rtl::OUString& aCmdURL )
+{
+ sal_Int32 nProperties(0);
+ Sequence< PropertyValue > aPropSeq;
+
+ // Retrieve popup menu labels
+ aPropSeq = GetPropsForCommand( aCmdURL );
+ for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
+ {
+ if ( aPropSeq[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Properties")) )
+ {
+ aPropSeq[i].Value >>= nProperties;
+ break;
+ }
+ }
+ return nProperties;
+}
+
+void ToolBarManager::CreateControllers()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ToolBarManager::CreateControllers" );
+
+ Reference< XMultiComponentFactory > xToolbarControllerFactory( m_xToolbarControllerRegistration, UNO_QUERY );
+ Reference< XComponentContext > xComponentContext;
+ Reference< XPropertySet > xProps( m_xServiceManager, UNO_QUERY );
+ Reference< XWindow > xToolbarWindow = VCLUnoHelper::GetInterface( m_pToolBar );
+
+ css::util::URL aURL;
+ sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
+ SvtCommandOptions aCmdOptions;
+
+ if ( xProps.is() )
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComponentContext;
+
+ for ( sal_uInt16 i = 0; i < m_pToolBar->GetItemCount(); i++ )
+ {
+ sal_uInt16 nId = m_pToolBar->GetItemId( i );
+ if ( nId == 0 )
+ continue;
+
+ rtl::OUString aLoadURL( RTL_CONSTASCII_USTRINGPARAM( ".uno:OpenUrl" ));
+ rtl::OUString aCommandURL( m_pToolBar->GetItemCommand( nId ));
+ sal_Bool bInit( sal_True );
+ sal_Bool bCreate( sal_True );
+ Reference< XStatusListener > xController;
+ CommandToInfoMap::iterator pCommandIter = m_aCommandMap.find( aCommandURL );
+ sal_Int16 nWidth = ( pCommandIter != m_aCommandMap.end() ? pCommandIter->second.nWidth : 0 );
+
+ svt::ToolboxController* pController( 0 );
+
+ if ( bHasDisabledEntries )
+ {
+ aURL.Complete = aCommandURL;
+ m_xURLTransformer->parseStrict( aURL );
+ if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aURL.Path ))
+ {
+ m_aControllerMap[ nId ] = xController;
+ m_pToolBar->HideItem( nId );
+ continue;
+ }
+ }
+
+ if ( m_xToolbarControllerRegistration.is() &&
+ m_xToolbarControllerRegistration->hasController( aCommandURL, m_aModuleIdentifier ))
+ {
+ if ( xToolbarControllerFactory.is() )
+ {
+ PropertyValue aPropValue;
+ std::vector< Any > aPropertyVector;
+
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
+ aPropValue.Value <<= m_aModuleIdentifier;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropValue.Value <<= m_xFrame;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
+ aPropValue.Value <<= m_xServiceManager;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
+ aPropValue.Value <<= xToolbarWindow;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+
+ if ( nWidth > 0 )
+ {
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ));
+ aPropValue.Value <<= nWidth;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+ }
+
+ Sequence< Any > aArgs( comphelper::containerToSequence( aPropertyVector ));
+ xController = Reference< XStatusListener >( xToolbarControllerFactory->createInstanceWithArgumentsAndContext(
+ aCommandURL, aArgs, xComponentContext ),
+ UNO_QUERY );
+ bInit = sal_False; // Initialization is done through the factory service
+ }
+ }
+
+ if (( aCommandURL == aLoadURL ) && ( !m_pToolBar->IsItemVisible(nId)))
+ bCreate = sal_False;
+
+ if ( !xController.is() && m_pToolBar && bCreate )
+ {
+ pController = CreateToolBoxController( m_xFrame, m_pToolBar, nId, aCommandURL );
+ if ( !pController )
+ {
+ if ( m_pToolBar->GetItemData( nId ) != 0 )
+ {
+ // retrieve additional parameters
+ ::rtl::OUString aControlType = static_cast< AddonsParams* >( m_pToolBar->GetItemData( nId ))->aControlType;
+
+ Reference< XStatusListener > xStatusListener(
+ ToolBarMerger::CreateController( m_xServiceManager,
+ m_xFrame,
+ m_pToolBar,
+ aCommandURL,
+ nId,
+ nWidth,
+ aControlType ), UNO_QUERY );
+
+ xController = xStatusListener;
+ }
+ else
+ {
+ MenuDescriptionMap::iterator it = m_aMenuMap.find( nId );
+ if ( it == m_aMenuMap.end() )
+ {
+ xController = Reference< XStatusListener >(
+ new GenericToolbarController( m_xServiceManager, m_xFrame, m_pToolBar, nId, aCommandURL ));
+
+ // Accessibility support: Set toggle button role for specific commands
+ sal_Int32 nProps = RetrievePropertiesFromCommand( aCommandURL );
+ if ( nProps & UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON )
+ m_pToolBar->SetItemBits( nId, m_pToolBar->GetItemBits( nId ) | TIB_CHECKABLE );
+ }
+ else
+ xController = Reference< XStatusListener >(
+ new MenuToolbarController( m_xServiceManager, m_xFrame, m_pToolBar, nId, aCommandURL, m_aModuleIdentifier, m_aMenuMap[ nId ] ));
+ }
+ }
+ else if ( pController )
+ {
+ xController = Reference< XStatusListener >( static_cast< ::cppu::OWeakObject *>( pController ), UNO_QUERY );
+ }
+ }
+
+ // Associate ID and controller to be able to retrieve
+ // the controller from the ID later.
+ m_aControllerMap[ nId ] = xController;
+
+ // Fill sub-toolbars into our hash-map
+ Reference< XSubToolbarController > xSubToolBar( xController, UNO_QUERY );
+ if ( xSubToolBar.is() && xSubToolBar->opensSubToolbar() )
+ {
+ rtl::OUString aSubToolBarName = xSubToolBar->getSubToolbarName();
+ if ( aSubToolBarName.getLength() != 0 )
+ {
+ SubToolBarToSubToolBarControllerMap::iterator pIter =
+ m_aSubToolBarControllerMap.find( aSubToolBarName );
+ if ( pIter == m_aSubToolBarControllerMap.end() )
+ {
+ SubToolBarControllerVector aSubToolBarVector;
+ aSubToolBarVector.push_back( xSubToolBar );
+ m_aSubToolBarControllerMap.insert(
+ SubToolBarToSubToolBarControllerMap::value_type(
+ aSubToolBarName, aSubToolBarVector ));
+ }
+ else
+ pIter->second.push_back( xSubToolBar );
+ }
+ }
+
+ Reference< XInitialization > xInit( xController, UNO_QUERY );
+ if ( xInit.is() )
+ {
+ if ( bInit )
+ {
+ PropertyValue aPropValue;
+ std::vector< Any > aPropertyVector;
+
+ aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropValue.Value <<= m_xFrame;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+ aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
+ aPropValue.Value <<= aCommandURL;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+ aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
+ aPropValue.Value <<= m_xServiceManager;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
+ aPropValue.Value <<= xToolbarWindow;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
+ aPropValue.Value <<= m_aModuleIdentifier;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+
+ if ( nWidth > 0 )
+ {
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ));
+ aPropValue.Value <<= nWidth;
+ aPropertyVector.push_back( makeAny( aPropValue ));
+ }
+
+ Sequence< Any > aArgs( comphelper::containerToSequence( aPropertyVector ));
+ xInit->initialize( aArgs );
+ //for Support Visiblitly by shizhoubo
+ if (pController)
+ {
+ if(aCommandURL == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SwitchXFormsDesignMode" )) ||
+ aCommandURL == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ViewDataSourceBrowser" )) ||
+ aCommandURL == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ParaLeftToRight" )) ||
+ aCommandURL == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ParaRightToLeft" ))
+ )
+ pController->setFastPropertyValue_NoBroadcast(1,makeAny(sal_True));
+ }
+
+ //end
+ }
+
+ // Request a item window from the toolbar controller and set it at the VCL toolbar
+ Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
+ if ( xTbxController.is() && xToolbarWindow.is() )
+ {
+ Reference< XWindow > xWindow = xTbxController->createItemWindow( xToolbarWindow );
+ if ( xWindow.is() )
+ {
+ Window* pItemWin = VCLUnoHelper::GetWindow( xWindow );
+ if ( pItemWin )
+ {
+ WindowType nType = pItemWin->GetType();
+ if ( nType == WINDOW_LISTBOX || nType == WINDOW_MULTILISTBOX || nType == WINDOW_COMBOBOX )
+ pItemWin->SetAccessibleName( m_pToolBar->GetItemText( nId ) );
+ m_pToolBar->SetItemWindow( nId, pItemWin );
+ }
+ }
+ }
+ }
+ //for update Controller via support visiable state by shizhoubo
+ Reference< XPropertySet > xPropSet( xController, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ sal_Bool bSupportVisiable = sal_True;
+ Any a( xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SupportsVisiable" ))) );
+ a >>= bSupportVisiable;
+ if ( bSupportVisiable )
+ {
+ Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
+ UpdateController(xTbxController);
+ }
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ //end
+
+ }
+
+ AddFrameActionListener();
+ AddImageOrientationListener();
+}
+
+void ToolBarManager::AddFrameActionListener()
+{
+ if ( !m_bFrameActionRegistered && m_xFrame.is() )
+ {
+ m_bFrameActionRegistered = sal_True;
+ m_xFrame->addFrameActionListener( Reference< XFrameActionListener >(
+ static_cast< ::cppu::OWeakObject *>( this ), UNO_QUERY ));
+ }
+}
+
+void ToolBarManager::AddImageOrientationListener()
+{
+ if ( !m_bImageOrientationRegistered && m_xFrame.is() )
+ {
+ m_bImageOrientationRegistered = sal_True;
+ ImageOrientationListener* pImageOrientation = new ImageOrientationListener(
+ Reference< XStatusListener >( static_cast< ::cppu::OWeakObject *>( this ), UNO_QUERY ),
+ m_xServiceManager,
+ m_xFrame );
+ m_xImageOrientationListener = Reference< XComponent >( static_cast< ::cppu::OWeakObject *>(
+ pImageOrientation ), UNO_QUERY );
+ pImageOrientation->addStatusListener(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ImageOrientation" )));
+ pImageOrientation->bindListener();
+ }
+}
+
+sal_uInt16 ToolBarManager::ConvertStyleToToolboxItemBits( sal_Int32 nStyle )
+{
+ sal_uInt16 nItemBits( 0 );
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::RADIO_CHECK )
+ nItemBits |= TIB_RADIOCHECK;
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::ALIGN_LEFT )
+ nItemBits |= TIB_LEFT;
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::AUTO_SIZE )
+ nItemBits |= TIB_AUTOSIZE;
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::DROP_DOWN )
+ nItemBits |= TIB_DROPDOWN;
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::REPEAT )
+ nItemBits |= TIB_REPEAT;
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY )
+ nItemBits |= TIB_DROPDOWNONLY;
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::TEXT )
+ nItemBits |= TIB_TEXT_ONLY;
+ if ( nStyle & ::com::sun::star::ui::ItemStyle::ICON )
+ nItemBits |= TIB_ICON_ONLY;
+
+ return nItemBits;
+}
+
+void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContainer )
+{
+ ::rtl::OString aTbxName = rtl::OUStringToOString( m_aResourceName, RTL_TEXTENCODING_ASCII_US );
+
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ToolBarManager::FillToolbar" );
+ RTL_LOGFILE_CONTEXT_TRACE1( aLog, "framework (cd100003) ::ToolBarManager::FillToolbar %s", aTbxName.getStr() );
+
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return;
+
+ sal_uInt16 nId( 1 );
+ ::rtl::OUString aHelpIdPrefix( RTL_CONSTASCII_USTRINGPARAM( HELPID_PREFIX ));
+
+ Reference< XModuleManager > xModuleManager( Reference< XModuleManager >(
+ m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY ));
+ if ( !m_xDocImageManager.is() )
+ {
+ Reference< XModel > xModel( GetModelFromFrame() );
+ if ( xModel.is() )
+ {
+ Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
+ if ( xSupplier.is() )
+ {
+ m_xDocUICfgMgr.set( xSupplier->getUIConfigurationManager(), UNO_QUERY );
+ m_xDocImageManager = Reference< XImageManager >( m_xDocUICfgMgr->getImageManager(), UNO_QUERY );
+ m_xDocImageManager->addConfigurationListener(
+ Reference< XUIConfigurationListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+ }
+ }
+
+ try
+ {
+ if ( xModuleManager.is() )
+ m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) );
+ }
+ catch( Exception& )
+ {
+ }
+
+ if ( !m_xModuleImageManager.is() )
+ {
+ Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( m_xServiceManager->createInstance(
+ SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ),
+ UNO_QUERY );
+ m_xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
+ m_xModuleImageManager = Reference< XImageManager >( m_xUICfgMgr->getImageManager(), UNO_QUERY );
+ m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >(
+ static_cast< OWeakObject* >( this ), UNO_QUERY ));
+ }
+
+ RemoveControllers();
+
+ // reset and fill command map
+ m_pToolBar->Clear();
+ m_aControllerMap.clear();
+ m_aCommandMap.clear();
+
+ m_aMenuMap.clear();
+
+ CommandInfo aCmdInfo;
+ for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ )
+ {
+ Sequence< PropertyValue > aProp;
+ rtl::OUString aCommandURL;
+ rtl::OUString aLabel;
+ rtl::OUString aHelpURL;
+ rtl::OUString aTooltip;
+ sal_uInt16 nType( ::com::sun::star::ui::ItemType::DEFAULT );
+ sal_uInt16 nWidth( 0 );
+ sal_Bool bIsVisible( sal_True );
+ sal_uInt32 nStyle( 0 );
+
+ Reference< XIndexAccess > aMenuDesc;
+ try
+ {
+ if ( rItemContainer->getByIndex( n ) >>= aProp )
+ {
+ for ( int i = 0; i < aProp.getLength(); i++ )
+ {
+ if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_COMMANDURL)) )
+ {
+ aProp[i].Value >>= aCommandURL;
+ if ( aCommandURL.compareToAscii(MENUPREFIX, RTL_CONSTASCII_LENGTH(MENUPREFIX) ) == 0 )
+ {
+ try
+ {
+ Reference< XIndexAccess > xMenuContainer;
+ if ( m_xDocUICfgMgr.is() )
+ xMenuContainer = m_xDocUICfgMgr->getSettings( aCommandURL, sal_False );
+ if ( !xMenuContainer.is() && m_xUICfgMgr.is() )
+ xMenuContainer = m_xUICfgMgr->getSettings( aCommandURL, sal_False );
+ if ( xMenuContainer.is() && xMenuContainer->getCount() )
+ {
+ Sequence< PropertyValue > aProps;
+ // drop down menu info is currently
+ // the first ( and only ) menu
+ // in the menusettings container
+ xMenuContainer->getByIndex(0) >>= aProps;
+ for ( sal_Int32 index=0; index<aProps.getLength(); ++index )
+ {
+ if ( aProps[ index ].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_CONTAINER)) )
+
+ {
+ aProps[ index ].Value >>= aMenuDesc;
+ break;
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ }
+ }
+ }
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_HELPURL)) )
+ aProp[i].Value >>= aHelpURL;
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_TOOLTIP)) )
+ aProp[i].Value >>= aTooltip;
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_LABEL)) )
+ aProp[i].Value >>= aLabel;
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_TYPE)) )
+ aProp[i].Value >>= nType;
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_VISIBLE)) )
+ aProp[i].Value >>= bIsVisible;
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_WIDTH)) )
+ aProp[i].Value >>= nWidth;
+ else if ( aProp[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_STYLE)) )
+ aProp[i].Value >>= nStyle;
+ }
+
+ if (( nType == ::com::sun::star::ui::ItemType::DEFAULT ) && ( aCommandURL.getLength() > 0 ))
+ {
+ ::rtl::OUString aString( RetrieveLabelFromCommand( aCommandURL ));
+
+ sal_uInt16 nItemBits = ConvertStyleToToolboxItemBits( nStyle );
+ if ( aMenuDesc.is() )
+ m_aMenuMap[ nId ] = aMenuDesc;
+ m_pToolBar->InsertItem( nId, aString, nItemBits );
+ m_pToolBar->SetItemCommand( nId, aCommandURL );
+ if ( aTooltip.getLength() )
+ {
+ m_pToolBar->SetQuickHelpText( nId, aTooltip );
+ }
+ else
+ {
+ ::rtl::OUString sQuickHelp( aString );
+ ::rtl::OUString sShortCut;
+ if( RetrieveShortcut( aCommandURL, sShortCut ) )
+ {
+ sQuickHelp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " (" ) );
+ sQuickHelp += sShortCut;
+ sQuickHelp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) );
+ }
+
+ m_pToolBar->SetQuickHelpText( nId, sQuickHelp );
+ }
+
+ if ( aLabel.getLength() > 0 )
+ {
+ m_pToolBar->SetItemText( nId, aLabel );
+ }
+ else
+ {
+ m_pToolBar->SetItemText( nId, aString );
+ }
+ m_pToolBar->EnableItem( nId, sal_True );
+ m_pToolBar->SetItemState( nId, STATE_NOCHECK );
+
+ // Fill command map. It stores all our commands and from what
+ // image manager we got our image. So we can decide if we have to use an
+ // image from a notification message.
+ CommandToInfoMap::iterator pIter = m_aCommandMap.find( aCommandURL );
+ if ( pIter == m_aCommandMap.end())
+ {
+ aCmdInfo.nId = nId;
+ aCmdInfo.nWidth = nWidth;
+ m_aCommandMap.insert( CommandToInfoMap::value_type( aCommandURL, aCmdInfo ));
+ }
+ else
+ {
+ pIter->second.aIds.push_back( nId );
+ }
+
+ if ( !bIsVisible )
+ m_pToolBar->HideItem( nId );
+
+ ++nId;
+ }
+ else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINE )
+ {
+ m_pToolBar->InsertSeparator();
+ }
+ else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_SPACE )
+ {
+ m_pToolBar->InsertSpace();
+ }
+ else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK )
+ {
+ m_pToolBar->InsertBreak();
+ }
+ }
+ }
+ catch ( ::com::sun::star::lang::IndexOutOfBoundsException& )
+ {
+ break;
+ }
+ }
+
+ // Support add-on toolbar merging here. Working directly on the toolbar object is much
+ // simpler and faster.
+ const sal_uInt16 TOOLBAR_ITEM_STARTID = 1000;
+
+ MergeToolbarInstructionContainer aMergeInstructionContainer;
+
+ // Retrieve the toolbar name from the resource name
+ ::rtl::OUString aToolbarName( m_aResourceName );
+ sal_Int32 nIndex = aToolbarName.lastIndexOf( '/' );
+ if (( nIndex > 0 ) && ( nIndex < aToolbarName.getLength() ))
+ aToolbarName = aToolbarName.copy( nIndex+1 );
+
+ AddonsOptions().GetMergeToolbarInstructions( aToolbarName, aMergeInstructionContainer );
+
+ if ( !aMergeInstructionContainer.empty() )
+ {
+ sal_uInt16 nItemId( TOOLBAR_ITEM_STARTID );
+ const sal_uInt32 nCount = aMergeInstructionContainer.size();
+ for ( sal_uInt32 i=0; i < nCount; i++ )
+ {
+ MergeToolbarInstruction& rInstruction = aMergeInstructionContainer[i];
+ if ( ToolBarMerger::IsCorrectContext( rInstruction.aMergeContext, m_aModuleIdentifier ))
+ {
+ ReferenceToolbarPathInfo aRefPoint = ToolBarMerger::FindReferencePoint( m_pToolBar, rInstruction.aMergePoint );
+
+ // convert the sequence< sequence< propertyvalue > > structure to
+ // something we can better handle. A vector with item data
+ AddonToolbarItemContainer aItems;
+ ToolBarMerger::ConvertSeqSeqToVector( rInstruction.aMergeToolbarItems, aItems );
+
+ if ( aRefPoint.bResult )
+ {
+ ToolBarMerger::ProcessMergeOperation( m_xFrame,
+ m_pToolBar,
+ aRefPoint.nPos,
+ nItemId,
+ m_aCommandMap,
+ m_aModuleIdentifier,
+ rInstruction.aMergeCommand,
+ rInstruction.aMergeCommandParameter,
+ aItems );
+ }
+ else
+ {
+ ToolBarMerger::ProcessMergeFallback( m_xFrame,
+ m_pToolBar,
+ aRefPoint.nPos,
+ nItemId,
+ m_aCommandMap,
+ m_aModuleIdentifier,
+ rInstruction.aMergeCommand,
+ rInstruction.aMergeFallback,
+ aItems );
+ }
+ }
+ }
+ }
+
+ // Request images for all toolbar items. Must be done before CreateControllers as
+ // some controllers need access to the image.
+ RequestImages();
+
+ // Create controllers after we set the images. There are controllers which needs
+ // an image at the toolbar at creation time!
+ CreateControllers();
+
+ // Notify controllers that they are now correctly initialized and can start listening
+ // toolbars that will open in popup mode will be updated immediately to avoid flickering
+ if( m_pToolBar->WillUsePopupMode() )
+ UpdateControllers();
+ else if ( m_pToolBar->IsReallyVisible() )
+ m_aAsyncUpdateControllersTimer.Start();
+
+ // Try to retrieve UIName from the container property set and set it as the title
+ // if it is not empty.
+ Reference< XPropertySet > xPropSet( rItemContainer, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ rtl::OUString aUIName;
+ xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= aUIName;
+ if ( aUIName.getLength() > 0 )
+ m_pToolBar->SetText( aUIName );
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+}
+
+void ToolBarManager::RequestImages()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ToolBarManager::RequestImages" );
+
+ // Request images from image manager
+ Sequence< rtl::OUString > aCmdURLSeq( m_aCommandMap.size() );
+ Sequence< Reference< XGraphic > > aDocGraphicSeq;
+ Sequence< Reference< XGraphic > > aModGraphicSeq;
+
+ sal_uInt32 i = 0;
+ CommandToInfoMap::iterator pIter = m_aCommandMap.begin();
+ CommandToInfoMap::iterator pEnd = m_aCommandMap.end();
+ while ( pIter != pEnd )
+ {
+ aCmdURLSeq[i++] = pIter->first;
+ ++pIter;
+ }
+
+ sal_Bool bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() );
+ sal_Int16 p = getImageTypeFromBools( SvtMiscOptions().AreCurrentSymbolsLarge() );
+
+ if ( m_xDocImageManager.is() )
+ aDocGraphicSeq = m_xDocImageManager->getImages( p, aCmdURLSeq );
+ aModGraphicSeq = m_xModuleImageManager->getImages( p, aCmdURLSeq );
+
+ i = 0;
+ pIter = m_aCommandMap.begin();
+ while ( pIter != pEnd )
+ {
+ rtl::OUString aCommandURL = aCmdURLSeq[i];
+
+ Image aImage;
+ if ( aDocGraphicSeq.getLength() > 0 )
+ aImage = Image( aDocGraphicSeq[i] );
+ if ( !aImage )
+ {
+ aImage = Image( aModGraphicSeq[i] );
+ // Try also to query for add-on images before giving up and use an
+ // empty image.
+ if ( !aImage )
+ aImage = QueryAddonsImage( aCmdURLSeq[i], bBigImages );
+
+ pIter->second.nImageInfo = 1; // mark image as module based
+ }
+ else
+ {
+ pIter->second.nImageInfo = 0; // mark image as document based
+ }
+ setToolBarImage(aImage,pIter);
+ ++pIter;
+ ++i;
+ }
+}
+
+void ToolBarManager::notifyRegisteredControllers( const rtl::OUString& aUIElementName, const rtl::OUString& aCommand )
+{
+ ResetableGuard aGuard( m_aLock );
+ if ( !m_aSubToolBarControllerMap.empty() )
+ {
+ SubToolBarToSubToolBarControllerMap::const_iterator pIter =
+ m_aSubToolBarControllerMap.find( aUIElementName );
+
+ if ( pIter != m_aSubToolBarControllerMap.end() )
+ {
+ const SubToolBarControllerVector& rSubToolBarVector = pIter->second;
+ if ( !rSubToolBarVector.empty() )
+ {
+ SubToolBarControllerVector aNotifyVector = rSubToolBarVector;
+ aGuard.unlock();
+
+ const sal_uInt32 nCount = aNotifyVector.size();
+ for ( sal_uInt32 i=0; i < nCount; i++ )
+ {
+ try
+ {
+ Reference< XSubToolbarController > xController = aNotifyVector[i];
+ if ( xController.is() )
+ xController->functionSelected( aCommand );
+ }
+ catch ( RuntimeException& e )
+ {
+ throw e;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+}
+long ToolBarManager::HandleClick(void ( SAL_CALL XToolbarController::*_pClick )())
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return 1;
+
+ sal_uInt16 nId( m_pToolBar->GetCurItemId() );
+ ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
+ if ( pIter != m_aControllerMap.end() )
+ {
+ Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
+
+ if ( xController.is() )
+ (xController.get()->*_pClick)( );
+ } // if ( pIter != m_aControllerMap.end() )
+ return 1;
+}
+
+IMPL_LINK( ToolBarManager, Click, ToolBox*, EMPTYARG )
+{
+ return HandleClick(&XToolbarController::click);
+}
+
+IMPL_LINK( ToolBarManager, DropdownClick, ToolBox*, EMPTYARG )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return 1;
+
+ sal_uInt16 nId( m_pToolBar->GetCurItemId() );
+ ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
+ if ( pIter != m_aControllerMap.end() )
+ {
+ Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
+
+ if ( xController.is() )
+ {
+ Reference< XWindow > xWin = xController->createPopupWindow();
+ if ( xWin.is() )
+ xWin->setFocus();
+ }
+ }
+ return 1;
+}
+
+IMPL_LINK( ToolBarManager, DoubleClick, ToolBox*, EMPTYARG )
+{
+ return HandleClick(&XToolbarController::doubleClick);
+}
+
+void ToolBarManager::ImplClearPopupMenu( ToolBox *pToolBar )
+{
+ if ( m_bDisposed )
+ return;
+
+ PopupMenu *pMenu = pToolBar->GetMenu();
+
+ // remove config entries from menu, so we have a clean menu to start with
+ // remove submenu first
+ PopupMenu* pItemMenu = pMenu->GetPopupMenu( 1 );
+ if( pItemMenu )
+ {
+ pItemMenu->Clear();
+ delete pItemMenu;
+ pItemMenu = NULL;
+ pMenu->SetPopupMenu( 1, pItemMenu );
+ }
+
+ // remove all items that were not added by the toolbar itself
+ sal_uInt16 i;
+ for( i=0; i<pMenu->GetItemCount(); )
+ {
+ if( pMenu->GetItemId( i ) < TOOLBOX_MENUITEM_START )
+ pMenu->RemoveItem( i );
+ else
+ i++;
+ }
+}
+
+IMPL_LINK( ToolBarManager, MenuDeactivate, Menu*, pMenu )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return 1;
+
+ if( pMenu != m_pToolBar->GetMenu() )
+ return 1;
+
+ ImplClearPopupMenu( m_pToolBar );
+
+ return 0;
+}
+
+Reference< XModel > ToolBarManager::GetModelFromFrame() const
+{
+ Reference< XController > xController = m_xFrame->getController();
+ Reference< XModel > xModel;
+ if ( xController.is() )
+ xModel = xController->getModel();
+
+ return xModel;
+}
+
+sal_Bool ToolBarManager::IsPluginMode() const
+{
+ sal_Bool bPluginMode( sal_False );
+
+ if ( m_xFrame.is() )
+ {
+ Reference< XModel > xModel = GetModelFromFrame();
+ if ( xModel.is() )
+ {
+ Sequence< PropertyValue > aSeq = xModel->getArgs();
+ comphelper::MediaDescriptor aMediaDescriptor( aSeq );
+ bPluginMode = aMediaDescriptor.getUnpackedValueOrDefault< sal_Bool >(
+ comphelper::MediaDescriptor::PROP_VIEWONLY(), sal_False );
+ }
+ }
+
+ return bPluginMode;
+}
+
+bool ToolBarManager::MenuItemAllowed( sal_uInt16 ) const
+{
+ return true;
+}
+
+//added for i33668 by shizhoubo : 200804
+PopupMenu * ToolBarManager::GetToolBarCustomMeun(ToolBox* pToolBar)
+{
+ PopupMenu *pMenu = pToolBar->GetMenu();
+ // remove all entries before inserting new ones
+ ImplClearPopupMenu( pToolBar );
+ // No config menu entries if command ".uno:ConfigureDialog" is not enabled
+ Reference< XDispatch > xDisp;
+ com::sun::star::util::URL aURL;
+ if ( m_xFrame.is() )
+ {
+ Reference< XDispatchProvider > xProv( m_xFrame, UNO_QUERY );
+ aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ConfigureDialog" ));
+ m_xURLTransformer->parseStrict( aURL );
+ if ( xProv.is() )
+ xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 );
+
+ if ( !xDisp.is() || IsPluginMode() )
+ return 0;
+ }
+
+ // popup menu for quick customization
+ sal_Bool bHideDisabledEntries = !SvtMenuOptions().IsEntryHidingEnabled();
+ PopupMenu aPopupMenu( FwkResId( POPUPMENU_TOOLBAR_QUICKCUSTOMIZATION ));
+
+ if ( m_pToolBar->IsCustomize() )
+ {
+ sal_uInt16 nPos( 0 );
+ PopupMenu* pItemMenu( aPopupMenu.GetPopupMenu( 1 ));
+
+ sal_Bool bIsFloating( sal_False );
+
+ DockingManager* pDockMgr = Window::GetDockingManager();
+ if ( pDockMgr )
+ bIsFloating = pDockMgr->IsFloating( m_pToolBar );
+
+ if ( !bIsFloating )
+ {
+ aPopupMenu.EnableItem( MENUITEM_TOOLBAR_DOCKTOOLBAR, sal_False );
+ aPopupMenu.EnableItem( MENUITEM_TOOLBAR_DOCKALLTOOLBAR, sal_False );
+ Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY );
+ if( xDockable.is() )
+ aPopupMenu.CheckItem( MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, xDockable->isLocked() );
+ }
+ else
+ aPopupMenu.EnableItem( MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, sal_False );
+
+ if ( !m_bCanBeCustomized )
+ {
+ // Non-configurable toolbars should disable configuration menu items
+ aPopupMenu.EnableItem( MENUITEM_TOOLBAR_VISIBLEBUTTON, sal_False );
+ aPopupMenu.EnableItem( MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR, sal_False );
+ aPopupMenu.EnableItem( MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, sal_False );
+ }
+
+ // Disable menu item CLOSE if the toolbar has no closer
+ //added for issue64028 by shizhoubo
+ if( !(pToolBar->GetFloatStyle() & WB_CLOSEABLE) )
+ aPopupMenu.EnableItem(MENUITEM_TOOLBAR_CLOSE, sal_False);
+ //end
+
+ pItemMenu->SetMenuFlags (pItemMenu->GetMenuFlags () |
+ MENU_FLAG_SHOWCHECKIMAGES);
+
+ for ( nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos )
+ {
+ if ( m_pToolBar->GetItemType(nPos) == TOOLBOXITEM_BUTTON )
+ {
+ sal_uInt16 nId = m_pToolBar->GetItemId(nPos);
+ ::rtl::OUString aCommandURL = m_pToolBar->GetItemCommand( nId );
+ pItemMenu->InsertItem( STARTID_CUSTOMIZE_POPUPMENU+nPos, m_pToolBar->GetItemText( nId ), MIB_CHECKABLE );
+ pItemMenu->CheckItem( STARTID_CUSTOMIZE_POPUPMENU+nPos, m_pToolBar->IsItemVisible( nId ) );
+ pItemMenu->SetItemCommand( STARTID_CUSTOMIZE_POPUPMENU+nPos, aCommandURL );
+ pItemMenu->SetItemImage( STARTID_CUSTOMIZE_POPUPMENU+nPos,
+ GetImageFromURL( m_xFrame, aCommandURL, sal_False )
+ );
+ }
+ else
+ {
+ pItemMenu->InsertSeparator();
+ }
+ }
+ }
+ else
+ {
+ sal_uInt16 nPos = aPopupMenu.GetItemPos( MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR );
+ if ( nPos != MENU_ITEM_NOTFOUND )
+ aPopupMenu.RemoveItem( nPos );
+ }
+
+ // copy all menu items to the toolbar menu
+ if( pMenu->GetItemCount() )
+ pMenu->InsertSeparator();
+
+ sal_uInt16 i;
+ for( i=0; i< aPopupMenu.GetItemCount(); i++)
+ {
+ sal_uInt16 nId = aPopupMenu.GetItemId( i );
+ if ( MenuItemAllowed( nId ))
+ pMenu->CopyItem( aPopupMenu, i, MENU_APPEND );
+ }
+
+ // set submenu to toolbar menu
+ if( aPopupMenu.GetPopupMenu( 1 ) )
+ {
+ // create an own submenu to avoid auto-delete when resource menu is deleted
+ PopupMenu *pItemMenu = new PopupMenu();
+
+ pItemMenu->SetMenuFlags (pItemMenu->GetMenuFlags () |
+ MENU_FLAG_SHOWCHECKIMAGES);
+
+ for( i=0; i< aPopupMenu.GetPopupMenu( 1 )->GetItemCount(); i++)
+ pItemMenu->CopyItem( *aPopupMenu.GetPopupMenu( 1 ), i, MENU_APPEND );
+
+ pMenu->SetPopupMenu( 1, pItemMenu );
+ }
+
+ if ( bHideDisabledEntries )
+ pMenu->RemoveDisabledEntries();
+
+ return pMenu;
+}
+
+// addd for 33668 by shizhoubo
+IMPL_LINK( ToolBarManager, Command, CommandEvent*, pCmdEvt )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return 1;
+ if ( pCmdEvt->GetCommand() != COMMAND_CONTEXTMENU )
+ return 0;
+
+ PopupMenu * pMenu = GetToolBarCustomMeun(m_pToolBar);
+ if (pMenu)
+ {
+ // make sure all disabled entries will be shown
+ pMenu->SetMenuFlags( pMenu->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES );
+ ::Point aPoint( pCmdEvt->GetMousePosPixel() );
+ pMenu->Execute( m_pToolBar, aPoint );
+ }
+
+ return 0;
+}
+//end
+
+IMPL_LINK( ToolBarManager, MenuButton, ToolBox*, pToolBar )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return 1;
+ //modify for i33668 by shizhoubo:2008:04
+ GetToolBarCustomMeun(pToolBar);
+ //end
+ return 0;
+ }
+
+IMPL_LINK( ToolBarManager, MenuSelect, Menu*, pMenu )
+{
+ // We have to hold a reference to ourself as it is possible that we will be disposed and
+ // our refcount could be zero (destruction) otherwise.
+ Reference< XInterface > xInterface( static_cast< OWeakObject* >( this ), UNO_QUERY );
+
+ {
+ // The guard must be in its own context as the we can get destroyed when our
+ // own xInterface reference get destroyed!
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return 1;
+
+ switch ( pMenu->GetCurItemId() )
+ {
+ case MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR:
+ {
+ Reference< XDispatch > xDisp;
+ com::sun::star::util::URL aURL;
+ if ( m_xFrame.is() )
+ {
+ Reference< XDispatchProvider > xProv( m_xFrame, UNO_QUERY );
+ aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ConfigureDialog" ));
+ m_xURLTransformer->parseStrict( aURL );
+ if ( xProv.is() )
+ xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 );
+ }
+
+ if ( xDisp.is() )
+ {
+ Sequence< PropertyValue > aPropSeq( 1 );
+
+ aPropSeq[ 0 ].Name =
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ResourceURL"));
+ aPropSeq[ 0 ].Value <<= m_aResourceName;
+
+ xDisp->dispatch( aURL, aPropSeq );
+ }
+ break;
+ }
+
+ case MENUITEM_TOOLBAR_DOCKTOOLBAR:
+ {
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+
+ pExecuteInfo->aToolbarResName = m_aResourceName;
+ pExecuteInfo->nCmd = EXEC_CMD_DOCKTOOLBAR;
+ pExecuteInfo->xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
+
+ Application::PostUserEvent( STATIC_LINK(0, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
+ break;
+ }
+
+ case MENUITEM_TOOLBAR_DOCKALLTOOLBAR:
+ {
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+
+ pExecuteInfo->aToolbarResName = m_aResourceName;
+ pExecuteInfo->nCmd = EXEC_CMD_DOCKALLTOOLBARS;
+ pExecuteInfo->xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
+
+ Application::PostUserEvent( STATIC_LINK(0, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
+ break;
+ }
+
+ case MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION:
+ {
+ Reference< XLayoutManager > xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
+ if ( xLayoutManager.is() )
+ {
+ Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY );
+
+ if( xDockable->isLocked() )
+ xLayoutManager->unlockWindow( m_aResourceName );
+ else
+ xLayoutManager->lockWindow( m_aResourceName );
+ }
+ break;
+ }
+
+ case MENUITEM_TOOLBAR_CLOSE:
+ {
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+
+ pExecuteInfo->aToolbarResName = m_aResourceName;
+ pExecuteInfo->nCmd = EXEC_CMD_CLOSETOOLBAR;
+ pExecuteInfo->xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
+ pExecuteInfo->xWindow = VCLUnoHelper::GetInterface( m_pToolBar );
+
+ Application::PostUserEvent( STATIC_LINK(0, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
+ }
+
+ default:
+ {
+ sal_uInt16 nId = pMenu->GetCurItemId();
+ if(( nId > 0 ) && ( nId < TOOLBOX_MENUITEM_START ))
+ {
+ // toggle toolbar button visibility
+ rtl::OUString aCommand = pMenu->GetItemCommand( nId );
+
+ Reference< XLayoutManager > xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
+ if ( xLayoutManager.is() )
+ {
+ Reference< XUIElementSettings > xUIElementSettings( xLayoutManager->getElement( m_aResourceName ), UNO_QUERY );
+ if ( xUIElementSettings.is() )
+ {
+ Reference< XIndexContainer > xItemContainer( xUIElementSettings->getSettings( sal_True ), UNO_QUERY );
+ sal_Int32 nCount = xItemContainer->getCount();
+ for ( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ Sequence< PropertyValue > aProp;
+ sal_Int32 nVisibleIndex( -1 );
+ rtl::OUString aCommandURL;
+ sal_Bool bVisible( sal_False );
+
+ if ( xItemContainer->getByIndex( i ) >>= aProp )
+ {
+ for ( sal_Int32 j = 0; j < aProp.getLength(); j++ )
+ {
+ if ( aProp[j].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_COMMANDURL)) )
+ {
+ aProp[j].Value >>= aCommandURL;
+ }
+ else if ( aProp[j].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(ITEM_DESCRIPTOR_VISIBLE)) )
+ {
+ aProp[j].Value >>= bVisible;
+ nVisibleIndex = j;
+ }
+ }
+
+ if (( aCommandURL == aCommand ) && ( nVisibleIndex >= 0 ))
+ {
+ // We have found the requested item, toggle the visible flag
+ // and write back the configuration settings to the toolbar
+ aProp[nVisibleIndex].Value = makeAny( !bVisible );
+ try
+ {
+ xItemContainer->replaceByIndex( i, makeAny( aProp ));
+ xUIElementSettings->setSettings( Reference< XIndexAccess >( xItemContainer, UNO_QUERY ));
+ Reference< XPropertySet > xPropSet( xUIElementSettings, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ Reference< XUIConfigurationPersistence > xUICfgMgr;
+ if (( xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ConfigurationSource" ))) >>= xUICfgMgr ) && ( xUICfgMgr.is() ))
+ xUICfgMgr->store();
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ // remove all entries - deactivate is not reliable
+ // The method checks if we are already disposed and in that case does nothing!
+ ImplClearPopupMenu( m_pToolBar );
+ }
+
+ return 1;
+}
+
+IMPL_LINK( ToolBarManager, Select, ToolBox*, EMPTYARG )
+{
+ if ( m_bDisposed )
+ return 1;
+
+ sal_Int16 nKeyModifier( (sal_Int16)m_pToolBar->GetModifier() );
+ sal_uInt16 nId( m_pToolBar->GetCurItemId() );
+
+ ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
+ if ( pIter != m_aControllerMap.end() )
+ {
+ Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
+
+ if ( xController.is() )
+ xController->execute( nKeyModifier );
+ }
+
+ return 1;
+}
+
+IMPL_LINK( ToolBarManager, Highlight, ToolBox*, EMPTYARG )
+{
+ return 1;
+}
+
+IMPL_LINK( ToolBarManager, Activate, ToolBox*, EMPTYARG )
+{
+ return 1;
+}
+
+IMPL_LINK( ToolBarManager, Deactivate, ToolBox*, EMPTYARG )
+{
+ return 1;
+}
+
+IMPL_LINK( ToolBarManager, StateChanged, StateChangedType*, pStateChangedType )
+{
+ if ( m_bDisposed )
+ return 1;
+
+ if ( *pStateChangedType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ CheckAndUpdateImages();
+ }
+ else if ( *pStateChangedType == STATE_CHANGE_VISIBLE )
+ {
+ if ( m_pToolBar->IsReallyVisible() )
+ m_aAsyncUpdateControllersTimer.Start();
+ }
+ else if ( *pStateChangedType == STATE_CHANGE_INITSHOW )
+ {
+ m_aAsyncUpdateControllersTimer.Start();
+ }
+ return 1;
+}
+
+IMPL_LINK( ToolBarManager, DataChanged, DataChangedEvent*, pDataChangedEvent )
+{
+ if ((( pDataChangedEvent->GetType() == DATACHANGED_SETTINGS ) ||
+ ( pDataChangedEvent->GetType() == DATACHANGED_DISPLAY )) &&
+ ( pDataChangedEvent->GetFlags() & SETTINGS_STYLE ))
+ {
+ CheckAndUpdateImages();
+ }
+
+ for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos )
+ {
+ const sal_uInt16 nId = m_pToolBar->GetItemId(nPos);
+ Window* pWindow = m_pToolBar->GetItemWindow( nId );
+ if ( pWindow )
+ {
+ const DataChangedEvent& rDCEvt( *pDataChangedEvent );
+ pWindow->DataChanged( rDCEvt );
+ }
+ }
+
+ if ( !m_pToolBar->IsFloatingMode() &&
+ m_pToolBar->IsVisible() )
+ {
+ // Resize toolbar, layout manager is resize listener and will calc
+ // the layout automatically.
+ ::Size aSize( m_pToolBar->CalcWindowSizePixel() );
+ m_pToolBar->SetOutputSizePixel( aSize );
+ }
+
+ return 1;
+}
+
+IMPL_LINK( ToolBarManager, AsyncUpdateControllersHdl, Timer *, EMPTYARG )
+{
+ // The guard must be in its own context as the we can get destroyed when our
+ // own xInterface reference get destroyed!
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ ResetableGuard aGuard( m_aLock );
+
+ if ( m_bDisposed )
+ return 1;
+
+ // Request to update our controllers
+ m_aAsyncUpdateControllersTimer.Stop();
+ UpdateControllers();
+
+ return 0;
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( ToolBarManager, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
+{
+ try
+ {
+ // Asynchronous execution as this can lead to our own destruction!
+ if (( pExecuteInfo->nCmd == EXEC_CMD_CLOSETOOLBAR ) &&
+ ( pExecuteInfo->xLayoutManager.is() ) &&
+ ( pExecuteInfo->xWindow.is() ))
+ {
+ // Use docking window close to close the toolbar. The layout manager is
+ // listener and will react correctly according to the context sensitive
+ // flag of our toolbar.
+ Window* pWin = VCLUnoHelper::GetWindow( pExecuteInfo->xWindow );
+ DockingWindow* pDockWin = dynamic_cast< DockingWindow* >( pWin );
+ if ( pDockWin )
+ pDockWin->Close();
+ }
+ else if (( pExecuteInfo->nCmd == EXEC_CMD_DOCKTOOLBAR ) &&
+ ( pExecuteInfo->xLayoutManager.is() ))
+ {
+ ::com::sun::star::awt::Point aPoint;
+ aPoint.X = aPoint.Y = SAL_MAX_INT32;
+ pExecuteInfo->xLayoutManager->dockWindow( pExecuteInfo->aToolbarResName,
+ DockingArea_DOCKINGAREA_DEFAULT,
+ aPoint );
+ }
+ else if (( pExecuteInfo->nCmd == EXEC_CMD_DOCKALLTOOLBARS ) &&
+ ( pExecuteInfo->xLayoutManager.is() ))
+ {
+ pExecuteInfo->xLayoutManager->dockAllWindows( UIElementType::TOOLBAR );
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ delete pExecuteInfo;
+ return 0;
+}
+
+Image ToolBarManager::QueryAddonsImage( const ::rtl::OUString& aCommandURL, bool bBigImages )
+{
+ Image aImage = framework::AddonsOptions().GetImageFromURL( aCommandURL, bBigImages );
+ return aImage;
+}
+
+bool ToolBarManager::impl_RetrieveShortcutsFromConfiguration(
+ const Reference< XAcceleratorConfiguration >& rAccelCfg,
+ const rtl::OUString& rCommand,
+ rtl::OUString& rShortCut )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ToolBarManager::impl_RetrieveShortcutsFromConfiguration" );
+ if ( rAccelCfg.is() )
+ {
+ try
+ {
+ com::sun::star::awt::KeyEvent aKeyEvent;
+ Sequence< OUString > aCommands(1);
+ aCommands[0] = rCommand;
+
+ Sequence< Any > aSeqKeyCode( rAccelCfg->getPreferredKeyEventsForCommandList( aCommands ) );
+ if( aSeqKeyCode.getLength() == 1 )
+ {
+ if ( aSeqKeyCode[0] >>= aKeyEvent )
+ {
+ rShortCut = svt::AcceleratorExecute::st_AWTKey2VCLKey( aKeyEvent ).GetName();
+ return true;
+ }
+ }
+ }
+ catch ( IllegalArgumentException& )
+ {
+ }
+ }
+
+ return false;
+}
+
+bool ToolBarManager::RetrieveShortcut( const rtl::OUString& rCommandURL, rtl::OUString& rShortCut )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ToolBarManager::RetrieveShortcuts" );
+ if ( m_bModuleIdentified )
+ {
+ Reference< XAcceleratorConfiguration > xDocAccelCfg( m_xDocAcceleratorManager );
+ Reference< XAcceleratorConfiguration > xModuleAccelCfg( m_xModuleAcceleratorManager );
+ Reference< XAcceleratorConfiguration > xGlobalAccelCfg( m_xGlobalAcceleratorManager );
+
+ if ( !m_bAcceleratorCfg )
+ {
+ // Retrieve references on demand
+ m_bAcceleratorCfg = sal_True;
+ if ( !xDocAccelCfg.is() )
+ {
+ Reference< XController > xController = m_xFrame->getController();
+ Reference< XModel > xModel;
+ if ( xController.is() )
+ {
+ xModel = xController->getModel();
+ if ( xModel.is() )
+ {
+ Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
+ if ( xSupplier.is() )
+ {
+ Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY );
+ if ( xDocUICfgMgr.is() )
+ {
+ xDocAccelCfg = Reference< XAcceleratorConfiguration >( xDocUICfgMgr->getShortCutManager(), UNO_QUERY );
+ m_xDocAcceleratorManager = xDocAccelCfg;
+ }
+ }
+ }
+ }
+ }
+
+ if ( !xModuleAccelCfg.is() )
+ {
+ Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( m_xServiceManager->createInstance(
+ SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ),
+ UNO_QUERY );
+ try
+ {
+ Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
+ if ( xUICfgMgr.is() )
+ {
+ xModuleAccelCfg = Reference< XAcceleratorConfiguration >( xUICfgMgr->getShortCutManager(), UNO_QUERY );
+ m_xModuleAcceleratorManager = xModuleAccelCfg;
+ }
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ if ( !xGlobalAccelCfg.is() )
+ {
+ xGlobalAccelCfg = Reference< XAcceleratorConfiguration >( m_xServiceManager->createInstance(
+ SERVICENAME_GLOBALACCELERATORCONFIGURATION ),
+ UNO_QUERY );
+ m_xGlobalAcceleratorManager = xGlobalAccelCfg;
+ }
+ }
+
+ bool bFound = false;
+
+ if ( m_xGlobalAcceleratorManager.is() )
+ bFound = impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, rCommandURL, rShortCut );
+ if ( !bFound && m_xModuleAcceleratorManager.is() )
+ bFound = impl_RetrieveShortcutsFromConfiguration( xModuleAccelCfg, rCommandURL, rShortCut );
+ if ( !bFound && m_xDocAcceleratorManager.is() )
+ impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, rCommandURL, rShortCut );
+
+ if( bFound )
+ return true;
+ }
+ return false;
+}
+
+}
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/toolbarmerger.cxx b/framework/source/uielement/toolbarmerger.cxx
new file mode 100644
index 000000000000..c5745e33c586
--- /dev/null
+++ b/framework/source/uielement/toolbarmerger.cxx
@@ -0,0 +1,719 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <uielement/toolbarmerger.hxx>
+#include <uielement/generictoolbarcontroller.hxx>
+#include <framework/imageproducer.hxx>
+
+#include <svtools/miscopt.hxx>
+
+namespace framework
+{
+
+static const char MERGE_TOOLBAR_URL[] = "URL";
+static const sal_uInt32 MERGE_TOOLBAR_URL_LEN = 3;
+static const char MERGE_TOOLBAR_TITLE[] = "Title";
+static const sal_uInt32 MERGE_TOOLBAR_TITLE_LEN = 5;
+static const char MERGE_TOOLBAR_IMAGEID[] = "ImageIdentifier";
+static const sal_uInt32 MERGE_TOOLBAR_IMAGEID_LEN = 15;
+static const char MERGE_TOOLBAR_CONTEXT[] = "Context";
+static const sal_uInt32 MERGE_TOOLBAR_CONTEXT_LEN = 7;
+static const char MERGE_TOOLBAR_TARGET[] = "Target";
+static const sal_uInt32 MERGE_TOOLBAR_TARGET_LEN = 6;
+static const char MERGE_TOOLBAR_CONTROLTYPE[] = "ControlType";
+static const char MERGE_TOOLBAR_CONTROLTYPE_LEN = 11;
+static const char MERGE_TOOLBAR_WIDTH[] = "Width";
+static const char MERGE_TOOLBAR_WIDTH_LEN = 5;
+
+static const char MERGECOMMAND_ADDAFTER[] = "AddAfter";
+static const sal_uInt32 MERGECOMMAND_ADDAFTER_LEN = 8;
+static const char MERGECOMMAND_ADDBEFORE[] = "AddBefore";
+static const sal_uInt32 MERGECOMMAND_ADDBEFORE_LEN = 9;
+static const char MERGECOMMAND_REPLACE[] = "Replace";
+static const sal_uInt32 MERGECOMMAND_REPLACE_LEN = 7;
+static const char MERGECOMMAND_REMOVE[] = "Remove";
+static const sal_uInt32 MERGECOMMAND_REMOVE_LEN = 6;
+
+static const char MERGEFALLBACK_ADDLAST[] = "AddLast";
+static const char MERGEFALLBACK_ADDLAST_LEN = 7;
+static const char MERGEFALLBACK_ADDFIRST[] = "AddFirst";
+static const char MERGEFALLBACK_ADDFIRST_LEN = 8;
+static const char MERGEFALLBACK_IGNORE[] = "Ignore";
+static const char MERGEFALLBACK_IGNORE_LEN = 6;
+
+static const char TOOLBARCONTROLLER_BUTTON[] = "Button";
+static const sal_uInt32 TOOLBARCONTROLLER_BUTTON_LEN = 6;
+static const char TOOLBARCONTROLLER_COMBOBOX[] = "Combobox";
+static const sal_uInt32 TOOLBARCONTROLLER_COMBOBOX_LEN = 8;
+static const char TOOLBARCONTROLLER_EDIT[] = "Editfield";
+static const sal_uInt32 TOOLBARCONTROLLER_EDIT_LEN = 9;
+static const char TOOLBARCONTROLLER_SPINFIELD[] = "Spinfield";
+static const sal_uInt32 TOOLBARCONTROLLER_SPINFIELD_LEN = 9;
+static const char TOOLBARCONTROLLER_IMGBUTTON[] = "ImageButton";
+static const sal_uInt32 TOOLBARCONTROLLER_IMGBUTTON_LEN = 11;
+static const char TOOLBARCONTROLLER_DROPDOWNBOX[] = "Dropdownbox";
+static const sal_uInt32 TOOLBARCONTROLLER_DROPDOWNBOX_LEN = 11;
+static const char TOOLBARCONTROLLER_DROPDOWNBTN[] = "DropdownButton";
+static const sal_uInt32 TOOLBARCONTROLLER_DROPDOWNBTN_LEN = 14;
+static const char TOOLBARCONTROLLER_TOGGLEDDBTN[] = "ToggleDropdownButton";
+static const sal_uInt32 TOOLBARCONTROLLER_TOGGLEDDBTN_LEN = 20;
+
+static const char TOOLBOXITEM_SEPARATOR_STR[] = "private:separator";
+static const sal_uInt16 TOOLBOXITEM_SEPARATOR_STR_LEN = sizeof( TOOLBOXITEM_SEPARATOR_STR )-1;
+
+using namespace ::com::sun::star;
+
+/**
+ Check whether a module identifier is part of a context
+ defined by a colon separated list of module identifier.
+
+ @param
+ rContext
+
+ Describes a context string list where all contexts
+ are delimited by a colon. For more information about
+ the module identifier used as context strings see the
+ IDL description of com::sun::star::frame::XModuleManager
+
+ @param
+ rModuleIdentifier
+
+ A string describing a module identifier. See IDL
+ description of com::sun::star::frame::XModuleManager.
+
+ @result
+ The result is true if the rContext is an empty string
+ or rModuleIdentifier is part of the context string.
+
+*/
+bool ToolBarMerger::IsCorrectContext(
+ const ::rtl::OUString& rContext,
+ const ::rtl::OUString& rModuleIdentifier )
+{
+ return (( rContext.getLength() == 0 ) || ( rContext.indexOf( rModuleIdentifier ) >= 0 ));
+}
+
+/**
+ Converts a sequence, sequence of property values to
+ a vector of structs.
+
+ @param
+ rSequence
+
+ Provides a sequence, sequence of property values.
+
+ @param
+ rContainer
+
+ A vector of AddonToolbarItems which will hold the
+ conversion from the rSequence argument.
+
+ @result
+ The result is true if the sequence, sequence of property
+ values could be converted to a vector of structs.
+
+*/
+bool ToolBarMerger::ConvertSeqSeqToVector(
+ const uno::Sequence< uno::Sequence< beans::PropertyValue > > rSequence,
+ AddonToolbarItemContainer& rContainer )
+{
+ sal_Int32 nLen( rSequence.getLength() );
+ for ( sal_Int32 i = 0; i < nLen; i++ )
+ {
+ AddonToolbarItem aAddonToolbarItem;
+ ConvertSequenceToValues( rSequence[i],
+ aAddonToolbarItem.aCommandURL,
+ aAddonToolbarItem.aLabel,
+ aAddonToolbarItem.aImageIdentifier,
+ aAddonToolbarItem.aTarget,
+ aAddonToolbarItem.aContext,
+ aAddonToolbarItem.aControlType,
+ aAddonToolbarItem.nWidth );
+ rContainer.push_back( aAddonToolbarItem );
+ }
+
+ return true;
+}
+
+/**
+ Converts a sequence of property values to single
+ values.
+
+ @param
+ rSequence
+
+ Provides a sequence of property values.
+
+ @param
+ rCommandURL
+
+ Contains the value of the property with
+ Name="CommandURL".
+
+ @param
+ rLabel
+
+ Contains the value of the property with
+ Name="Title"
+
+ @param
+ rImageIdentifier
+
+ Contains the value of the property with
+ Name="ImageIdentifier"
+
+ @param
+ rTarget
+
+ Contains the value of the property with
+ Name="Target"
+
+ @param
+ rContext
+
+ Contains the value of the property with
+ Name="Context"
+
+ @param
+ rControlType
+
+ Contains the value of the property with
+ Name="ControlType"
+
+ @result
+ All possible mapping between sequence of property
+ values and the single values are done.
+
+*/
+void ToolBarMerger::ConvertSequenceToValues(
+ const uno::Sequence< beans::PropertyValue > rSequence,
+ ::rtl::OUString& rCommandURL,
+ ::rtl::OUString& rLabel,
+ ::rtl::OUString& rImageIdentifier,
+ ::rtl::OUString& rTarget,
+ ::rtl::OUString& rContext,
+ ::rtl::OUString& rControlType,
+ sal_uInt16& rWidth )
+{
+ for ( sal_Int32 i = 0; i < rSequence.getLength(); i++ )
+ {
+ if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_URL, MERGE_TOOLBAR_URL_LEN ))
+ rSequence[i].Value >>= rCommandURL;
+ else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_TITLE, MERGE_TOOLBAR_TITLE_LEN ))
+ rSequence[i].Value >>= rLabel;
+ else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_IMAGEID, MERGE_TOOLBAR_IMAGEID_LEN ))
+ rSequence[i].Value >>= rImageIdentifier;
+ else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_CONTEXT, MERGE_TOOLBAR_CONTEXT_LEN ))
+ rSequence[i].Value >>= rContext;
+ else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_TARGET, MERGE_TOOLBAR_TARGET_LEN ))
+ rSequence[i].Value >>= rTarget;
+ else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_CONTROLTYPE, MERGE_TOOLBAR_CONTROLTYPE_LEN ))
+ rSequence[i].Value >>= rControlType;
+ else if ( rSequence[i].Name.equalsAsciiL( MERGE_TOOLBAR_WIDTH, MERGE_TOOLBAR_WIDTH_LEN ))
+ {
+ sal_Int32 aValue = 0;
+ rSequence[i].Value >>= aValue;
+ rWidth = sal_uInt16( aValue );
+ }
+ }
+}
+
+/**
+ Tries to find the reference point provided and delivers
+ position and result of the search process.
+
+ @param
+ pToolbar
+
+ Must be a valid pointer to a toolbar with items which
+ should be searched.
+
+ @param
+ rReferencePoint
+
+ A command URL which should be the reference point for
+ the coming merge operation.
+
+ @result
+ Provides information about the search result, the
+ position of the reference point and the toolbar used.
+*/
+ReferenceToolbarPathInfo ToolBarMerger::FindReferencePoint(
+ ToolBox* pToolbar,
+ const ::rtl::OUString& rReferencePoint )
+{
+ ReferenceToolbarPathInfo aResult;
+ aResult.bResult = false;
+ aResult.pToolbar = pToolbar;
+ aResult.nPos = TOOLBOX_ITEM_NOTFOUND;
+
+ const sal_uInt16 nSize( pToolbar->GetItemCount() );
+
+ for ( sal_uInt16 i = 0; i < nSize; i++ )
+ {
+ const sal_uInt16 nItemId = pToolbar->GetItemId( i );
+ if ( nItemId > 0 )
+ {
+ const ::rtl::OUString rCmd = pToolbar->GetItemCommand( nItemId );
+ if ( rCmd == rReferencePoint )
+ {
+ aResult.bResult = true;
+ aResult.nPos = i;
+ return aResult;
+ }
+ }
+ }
+
+ return aResult;
+}
+
+/**
+ Processes a merge operation.
+
+ @param
+ xFrame
+
+ Must be a valid reference to a frame.
+
+ @param
+ pToolbar
+
+ A valid pointer to the toolbar where the merge
+ operation is applied to.
+
+ @param
+ nPos
+
+ The reference position of the toolbar item for
+ the merge operation. Value must be between
+ 0 and number of toolbar items - 1.
+
+ @param
+ rItemId
+
+ A unique item ID.
+
+ @param
+ rModuleIdentifier
+
+ The current application module context.
+
+ @param
+ rMergeCommand
+
+ A merge command.
+
+ @param
+ rMergeCommandParameter.
+
+ An optional argument for the merge command.
+
+ @param
+ rItems
+
+ Toolbar items which are associated to the merge
+ command.
+
+ @result
+ Returns true for a successful operation otherwise
+ false.
+*/
+bool ToolBarMerger::ProcessMergeOperation(
+ const uno::Reference< frame::XFrame >& xFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nPos,
+ sal_uInt16& rItemId,
+ CommandToInfoMap& rCommandMap,
+ const ::rtl::OUString& rModuleIdentifier,
+ const ::rtl::OUString& rMergeCommand,
+ const ::rtl::OUString& rMergeCommandParameter,
+ const AddonToolbarItemContainer& rItems )
+{
+ if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDAFTER, MERGECOMMAND_ADDAFTER_LEN ))
+ return MergeItems( xFrame, pToolbar, nPos, 1, rItemId, rCommandMap, rModuleIdentifier, rItems );
+ else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDBEFORE, MERGECOMMAND_ADDBEFORE_LEN ))
+ return MergeItems( xFrame, pToolbar, nPos, 0, rItemId, rCommandMap, rModuleIdentifier, rItems );
+ else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REPLACE, MERGECOMMAND_REPLACE_LEN ))
+ return ReplaceItem( xFrame, pToolbar, nPos, rItemId, rCommandMap, rModuleIdentifier, rItems );
+ else if ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REMOVE, MERGECOMMAND_REMOVE_LEN ))
+ return RemoveItems( pToolbar, nPos, rMergeCommandParameter );
+
+ return false;
+}
+
+/**
+ Processes a merge fallback operation.
+
+ @param
+ xFrame
+
+ Must be a valid reference to a frame.
+
+ @param
+ pToolbar
+
+ A valid pointer to the toolbar where the merge
+ fall back operation is applied to.
+
+ @param
+ nPos
+
+ The reference position of the toolbar item for
+ the merge operation. Value must be between
+ 0 and number of toolbar items - 1.
+
+ @param
+ rItemId
+
+ A unique item ID.
+
+ @param
+ rModuleIdentifier
+
+ The current application module context.
+
+ @param
+ rMergeCommand
+
+ A merge command.
+
+ @param
+ rItems
+
+ Toolbar items which are associated to the merge
+ command.
+
+ @result
+ Returns true for a successful operation otherwise
+ false.
+*/
+bool ToolBarMerger::ProcessMergeFallback(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 /*nPos*/,
+ sal_uInt16& rItemId,
+ CommandToInfoMap& rCommandMap,
+ const ::rtl::OUString& rModuleIdentifier,
+ const ::rtl::OUString& rMergeCommand,
+ const ::rtl::OUString& rMergeFallback,
+ const AddonToolbarItemContainer& rItems )
+{
+ if (( rMergeFallback.equalsAsciiL( MERGEFALLBACK_IGNORE, MERGEFALLBACK_IGNORE_LEN )) ||
+ ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REPLACE, MERGECOMMAND_REPLACE_LEN )) ||
+ ( rMergeCommand.equalsAsciiL( MERGECOMMAND_REMOVE, MERGECOMMAND_REMOVE_LEN )) )
+ {
+ return true;
+ }
+ else if (( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDBEFORE, MERGECOMMAND_ADDBEFORE_LEN )) ||
+ ( rMergeCommand.equalsAsciiL( MERGECOMMAND_ADDAFTER, MERGECOMMAND_ADDAFTER_LEN )) )
+ {
+ if ( rMergeFallback.equalsAsciiL( MERGEFALLBACK_ADDFIRST, MERGEFALLBACK_ADDFIRST_LEN ))
+ return MergeItems( xFrame, pToolbar, 0, 0, rItemId, rCommandMap, rModuleIdentifier, rItems );
+ else if ( rMergeFallback.equalsAsciiL( MERGEFALLBACK_ADDLAST, MERGEFALLBACK_ADDLAST_LEN ))
+ return MergeItems( xFrame, pToolbar, TOOLBOX_APPEND, 0, rItemId, rCommandMap, rModuleIdentifier, rItems );
+ }
+
+ return false;
+}
+
+/**
+ Merges (adds) toolbar items into an existing toolbar.
+
+ @param
+ xFrame
+
+ Must be a valid reference to a frame.
+
+ @param
+ pToolbar
+
+ A valid pointer to the toolbar where the merge
+ fall back operation is applied to.
+
+ @param
+ nPos
+
+ The reference position of the toolbar item for
+ the merge operation. Value must be between
+ 0 and number of toolbar items - 1.
+
+ @param
+ rItemId
+
+ A unique item ID.
+
+ @param
+ rModuleIdentifier
+
+ The current application module context.
+
+ @param
+ rItems
+
+ Toolbar items which are associated to the merge
+ command.
+
+ @result
+ Returns true for a successful operation otherwise
+ false.
+*/
+bool ToolBarMerger::MergeItems(
+ const uno::Reference< frame::XFrame >& rFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nPos,
+ sal_uInt16 nModIndex,
+ sal_uInt16& rItemId,
+ CommandToInfoMap& rCommandMap,
+ const ::rtl::OUString& rModuleIdentifier,
+ const AddonToolbarItemContainer& rAddonToolbarItems )
+{
+ const sal_Int32 nSize( rAddonToolbarItems.size() );
+
+ uno::Reference< frame::XFrame > xFrame( rFrame );
+
+ sal_uInt16 nIndex( 0 );
+ for ( sal_Int32 i = 0; i < nSize; i++ )
+ {
+ const AddonToolbarItem& rItem = rAddonToolbarItems[i];
+ if ( IsCorrectContext( rItem.aContext, rModuleIdentifier ))
+ {
+ sal_Int32 nInsPos = nPos+nModIndex+i;
+ if ( nInsPos > sal_Int32( pToolbar->GetItemCount() ))
+ nInsPos = TOOLBOX_APPEND;
+
+ if ( rItem.aCommandURL.equalsAsciiL( TOOLBOXITEM_SEPARATOR_STR, TOOLBOXITEM_SEPARATOR_STR_LEN ))
+ pToolbar->InsertSeparator( sal_uInt16( nInsPos ));
+ else
+ {
+ CommandToInfoMap::iterator pIter = rCommandMap.find( rItem.aCommandURL );
+ if ( pIter == rCommandMap.end())
+ {
+ CommandInfo aCmdInfo;
+ aCmdInfo.nId = rItemId;
+ rCommandMap.insert( CommandToInfoMap::value_type( rItem.aCommandURL, aCmdInfo ));
+ }
+ else
+ {
+ pIter->second.aIds.push_back( rItemId );
+ }
+
+ ToolBarMerger::CreateToolbarItem( pToolbar, rCommandMap, sal_uInt16( nInsPos ), rItemId, rItem );
+ }
+
+ ++nIndex;
+ ++rItemId;
+ }
+ }
+
+ return true;
+}
+
+/**
+ Replaces a toolbar item with new items for an
+ existing toolbar.
+
+ @param
+ xFrame
+
+ Must be a valid reference to a frame.
+
+ @param
+ pToolbar
+
+ A valid pointer to the toolbar where the merge
+ fall back operation is applied to.
+
+ @param
+ nPos
+
+ The reference position of the toolbar item for
+ the merge operation. Value must be between
+ 0 and number of toolbar items - 1.
+
+ @param
+ rItemId
+
+ A unique item ID.
+
+ @param
+ rModuleIdentifier
+
+ The current application module context.
+
+ @param
+ rItems
+
+ Toolbar items which are associated to the merge
+ command.
+
+ @result
+ Returns true for a successful operation otherwise
+ false.
+*/
+bool ToolBarMerger::ReplaceItem(
+ const uno::Reference< frame::XFrame >& xFrame,
+ ToolBox* pToolbar,
+ sal_uInt16 nPos,
+ sal_uInt16& rItemId,
+ CommandToInfoMap& rCommandMap,
+ const ::rtl::OUString& rModuleIdentifier,
+ const AddonToolbarItemContainer& rAddonToolbarItems )
+{
+ pToolbar->RemoveItem( nPos );
+ return MergeItems( xFrame, pToolbar, nPos, 0, rItemId, rCommandMap, rModuleIdentifier, rAddonToolbarItems );
+}
+
+/**
+ Removes toolbar items from an existing toolbar.
+
+ @param
+ pToolbar
+
+ A valid pointer to the toolbar where the merge
+ fall back operation is applied to.
+
+ @param
+ nPos
+
+ The reference position of the toolbar item for
+ the merge operation. Value must be between
+ 0 and number of toolbar items - 1.
+
+ @param
+ rMergeCommandParameter.
+
+ An optional argument for the merge command.
+
+ @result
+ Returns true for a successful operation otherwise
+ false.
+*/
+bool ToolBarMerger::RemoveItems(
+ ToolBox* pToolbar,
+ sal_uInt16 nPos,
+ const ::rtl::OUString& rMergeCommandParameter )
+{
+ sal_Int32 nCount = rMergeCommandParameter.toInt32();
+ if ( nCount > 0 )
+ {
+ for ( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ if ( nPos < pToolbar->GetItemCount() )
+ pToolbar->RemoveItem( nPos );
+ }
+ }
+ return true;
+}
+
+/**
+ Removes toolbar items from an existing toolbar.
+
+ @param
+ pToolbar
+
+ A valid pointer to the toolbar where the merge
+ fall back operation is applied to.
+
+ @param
+ nPos
+
+ The reference position of the toolbar item for
+ the merge operation. Value must be between
+ 0 and number of toolbar items - 1.
+
+ @param
+ rMergeCommandParameter.
+
+ An optional argument for the merge command.
+
+ @result
+ Returns true for a successful operation otherwise
+ false.
+*/
+::cppu::OWeakObject* ToolBarMerger::CreateController(
+ uno::Reference< lang::XMultiServiceFactory > xSMGR,
+ uno::Reference< frame::XFrame > xFrame,
+ ToolBox* pToolbar,
+ const ::rtl::OUString& rCommandURL,
+ sal_uInt16 nId,
+ sal_uInt16 nWidth,
+ const ::rtl::OUString& rControlType )
+{
+ ::cppu::OWeakObject* pResult( 0 );
+
+ if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_BUTTON, TOOLBARCONTROLLER_BUTTON_LEN ))
+ pResult = new ButtonToolbarController( xSMGR, pToolbar, rCommandURL );
+ else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_COMBOBOX, TOOLBARCONTROLLER_COMBOBOX_LEN ))
+ pResult = new ComboboxToolbarController( xSMGR, xFrame, pToolbar, nId, nWidth, rCommandURL );
+ else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_EDIT, TOOLBARCONTROLLER_EDIT_LEN ))
+ pResult = new EditToolbarController( xSMGR, xFrame, pToolbar, nId, nWidth, rCommandURL );
+ else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_SPINFIELD, TOOLBARCONTROLLER_SPINFIELD_LEN ))
+ pResult = new SpinfieldToolbarController( xSMGR, xFrame, pToolbar, nId, nWidth, rCommandURL );
+ else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_IMGBUTTON, TOOLBARCONTROLLER_IMGBUTTON_LEN ))
+ pResult = new ImageButtonToolbarController( xSMGR, xFrame, pToolbar, nId, rCommandURL );
+ else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_DROPDOWNBOX, TOOLBARCONTROLLER_DROPDOWNBOX_LEN ))
+ pResult = new DropdownToolbarController( xSMGR, xFrame, pToolbar, nId, nWidth, rCommandURL );
+ else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_DROPDOWNBTN, TOOLBARCONTROLLER_DROPDOWNBTN_LEN ))
+ pResult = new ToggleButtonToolbarController( xSMGR, xFrame, pToolbar, nId,
+ ToggleButtonToolbarController::STYLE_DROPDOWNBUTTON, rCommandURL );
+ else if ( rControlType.equalsAsciiL( TOOLBARCONTROLLER_TOGGLEDDBTN, TOOLBARCONTROLLER_TOGGLEDDBTN_LEN ))
+ pResult = new ToggleButtonToolbarController( xSMGR, xFrame, pToolbar, nId,
+ ToggleButtonToolbarController::STYLE_TOGGLE_DROPDOWNBUTTON, rCommandURL );
+ else
+ pResult = new GenericToolbarController( xSMGR, xFrame, pToolbar, nId, rCommandURL );
+
+ return pResult;
+}
+
+void ToolBarMerger::CreateToolbarItem( ToolBox* pToolbar, CommandToInfoMap& rCommandMap, sal_uInt16 nPos, sal_uInt16 nItemId, const AddonToolbarItem& rItem )
+{
+ pToolbar->InsertItem( nItemId, rItem.aLabel, 0, nPos );
+ pToolbar->SetItemCommand( nItemId, rItem.aCommandURL );
+ pToolbar->SetQuickHelpText( nItemId, rItem.aLabel );
+ pToolbar->SetItemText( nItemId, rItem.aLabel );
+ pToolbar->EnableItem( nItemId, sal_True );
+ pToolbar->SetItemState( nItemId, STATE_NOCHECK );
+
+ CommandToInfoMap::iterator pIter = rCommandMap.find( rItem.aCommandURL );
+ if ( pIter != rCommandMap.end() )
+ pIter->second.nWidth = rItem.nWidth;
+
+ // Use the user data to store add-on specific data with the toolbar item
+ AddonsParams* pAddonParams = new AddonsParams;
+ pAddonParams->aImageId = rItem.aImageIdentifier;
+ pAddonParams->aTarget = rItem.aTarget;
+ pAddonParams->aControlType = rItem.aControlType;
+ pToolbar->SetItemData( nItemId, pAddonParams );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/toolbarsmenucontroller.cxx b/framework/source/uielement/toolbarsmenucontroller.cxx
new file mode 100644
index 000000000000..ed5eee6a3e7e
--- /dev/null
+++ b/framework/source/uielement/toolbarsmenucontroller.cxx
@@ -0,0 +1,916 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uielement/toolbarsmenucontroller.hxx>
+
+#include <algorithm>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+#include <classes/resource.hrc>
+#include <classes/fwkresid.hxx>
+#include <uiconfiguration/windowstateconfiguration.hxx>
+#include <framework/imageproducer.hxx>
+#include <framework/sfxhelperfunctions.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/ui/XUIElementSettings.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/i18nhelp.hxx>
+#include <vcl/image.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <toolkit/unohlp.hxx>
+#include <vcl/window.hxx>
+#include <svtools/menuoptions.hxx>
+#include <unotools/cmdoptions.hxx>
+#include <dispatch/uieventloghelper.hxx>
+#include <rtl/logfile.hxx>
+#include <svtools/miscopt.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::ui;
+
+static const char CONFIGURE_TOOLBARS_CMD[] = "ConfigureDialog";
+static const char CONFIGURE_TOOLBARS[] = ".uno:ConfigureDialog";
+static const char CMD_COLORBAR[] = ".uno:ColorControl";
+static const char CMD_FORMULABAR[] = ".uno:InsertFormula";
+static const char CMD_INPUTLINEBAR[] = ".uno:InputLineVisible";
+static const char CMD_RESTOREVISIBILITY[] = ".cmd:RestoreVisibility";
+static const char ITEM_DESCRIPTOR_RESOURCEURL[] = "ResourceURL";
+static const char ITEM_DESCRIPTOR_UINAME[] = "UIName";
+static const char STATIC_PRIVATE_TB_RESOURCE[] = "private:resource/toolbar/";
+
+static const char STATIC_CMD_PART[] = ".uno:AvailableToolbars?Toolbar:string=";
+static const char STATIC_INTERNAL_CMD_PART[] = ".cmd:";
+
+namespace framework
+{
+
+typedef boost::unordered_map< rtl::OUString, rtl::OUString, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > ToolbarHashMap;
+
+struct ToolBarEntry
+{
+ rtl::OUString aUIName;
+ rtl::OUString aCommand;
+ sal_Bool bVisible;
+ sal_Bool bContextSensitive;
+ const CollatorWrapper* pCollatorWrapper;
+};
+
+sal_Bool CompareToolBarEntry( const ToolBarEntry& aOne, const ToolBarEntry& aTwo )
+{
+ sal_Int32 nComp = aOne.pCollatorWrapper->compareString( aOne.aUIName, aTwo.aUIName );
+
+ if ( nComp < 0 )
+ return sal_True;
+ else if ( nComp > 0 )
+ return sal_False;
+ else
+ return sal_False;
+}
+
+Reference< XLayoutManager > getLayoutManagerFromFrame( const Reference< XFrame >& rFrame )
+{
+ Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
+ Reference< XLayoutManager > xLayoutManager;
+
+ try
+ {
+ xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xLayoutManager;
+ }
+ catch ( UnknownPropertyException& )
+ {
+ }
+
+ return xLayoutManager;
+}
+
+struct ToolBarInfo
+{
+ rtl::OUString aToolBarResName;
+ rtl::OUString aToolBarUIName;
+};
+
+DEFINE_XSERVICEINFO_MULTISERVICE ( ToolbarsMenuController ,
+ OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLER ,
+ IMPLEMENTATIONNAME_TOOLBARSMENUCONTROLLER
+ )
+
+DEFINE_INIT_SERVICE ( ToolbarsMenuController, {} )
+
+ToolbarsMenuController::ToolbarsMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ svt::PopupMenuControllerBase( xServiceManager ),
+ m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" )),
+ m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" )),
+ m_bModuleIdentified( sal_False ),
+ m_bResetActive( sal_False ),
+ m_aIntlWrapper( xServiceManager, Application::GetSettings().GetLocale() )
+{
+}
+
+ToolbarsMenuController::~ToolbarsMenuController()
+{
+}
+
+void ToolbarsMenuController::addCommand(
+ Reference< css::awt::XPopupMenu >& rPopupMenu, const rtl::OUString& rCommandURL, const rtl::OUString& rLabel )
+{
+ sal_uInt16 nItemId = m_xPopupMenu->getItemCount()+1;
+
+ rtl::OUString aLabel;
+ if ( rLabel.getLength() == 0 )
+ aLabel = getUINameFromCommand( rCommandURL );
+ else
+ aLabel = rLabel;
+
+ rPopupMenu->insertItem( nItemId, aLabel, 0, nItemId );
+ Reference< awt::XMenuExtended > xMenuExtended( m_xPopupMenu, UNO_QUERY );
+ xMenuExtended->setCommand( nItemId, rCommandURL );
+
+ bool bInternal = ( rCommandURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0);
+ if ( !bInternal )
+ {
+ if ( !getDispatchFromCommandURL( rCommandURL ).is() )
+ m_xPopupMenu->enableItem( nItemId, sal_False );
+ }
+
+ SolarMutexGuard aSolarMutexGuard;
+
+ Image aImage;
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+
+ if ( rSettings.GetUseImagesInMenus() )
+ aImage = GetImageFromURL( m_xFrame, rCommandURL, false );
+
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( rPopupMenu );
+ if ( pPopupMenu )
+ {
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+ if ( !!aImage )
+ pVCLPopupMenu->SetItemImage( nItemId, aImage );
+ }
+
+ m_aCommandVector.push_back( rCommandURL );
+}
+
+Reference< XDispatch > ToolbarsMenuController::getDispatchFromCommandURL( const rtl::OUString& rCommandURL )
+{
+ URL aTargetURL;
+ Sequence<PropertyValue> aArgs;
+ Reference< XURLTransformer > xURLTransformer;
+ Reference< XFrame > xFrame;
+
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ xURLTransformer = m_xURLTransformer;
+ xFrame = m_xFrame;
+ }
+
+ aTargetURL.Complete = rCommandURL;
+ xURLTransformer->parseStrict( aTargetURL );
+ Reference< XDispatchProvider > xDispatchProvider( xFrame, UNO_QUERY );
+ if ( xDispatchProvider.is() )
+ return xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+ else
+ return Reference< XDispatch >();
+}
+
+// private function
+rtl::OUString ToolbarsMenuController::getUINameFromCommand( const rtl::OUString& rCommandURL )
+{
+ rtl::OUString aLabel;
+
+ if ( !m_bModuleIdentified )
+ {
+ try
+ {
+ Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
+ m_aModuleIdentifier = xModuleManager->identify( m_xFrame );
+ Reference< XNameAccess > xNameAccess( m_xServiceManager->createInstance(
+ SERVICENAME_UICOMMANDDESCRIPTION ),
+ UNO_QUERY );
+ xNameAccess->getByName( m_aModuleIdentifier ) >>= m_xUICommandDescription;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ if ( m_xUICommandDescription.is() )
+ {
+ try
+ {
+ Sequence< PropertyValue > aPropSeq;
+ rtl::OUString aStr;
+ if ( m_xUICommandDescription->getByName( rCommandURL ) >>= aPropSeq )
+ {
+ for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
+ {
+ if ( aPropSeq[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Label" ) ))
+ {
+ aPropSeq[i].Value >>= aStr;
+ break;
+ }
+ }
+ }
+ aLabel = aStr;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+
+ return aLabel;
+}
+
+static void fillHashMap( const Sequence< Sequence< ::com::sun::star::beans::PropertyValue > >& rSeqToolBars,
+ ToolbarHashMap& rHashMap )
+{
+ for ( sal_Int32 i = 0; i < rSeqToolBars.getLength(); i++ )
+ {
+ rtl::OUString aResourceURL;
+ rtl::OUString aUIName;
+ const PropertyValue* pProperties = rSeqToolBars[i].getConstArray();
+ for ( sal_Int32 j = 0; j < rSeqToolBars[i].getLength(); j++ )
+ {
+ if ( pProperties[j].Name.equalsAscii( ITEM_DESCRIPTOR_RESOURCEURL) )
+ pProperties[j].Value >>= aResourceURL;
+ else if ( pProperties[j].Name.equalsAscii( ITEM_DESCRIPTOR_UINAME) )
+ pProperties[j].Value >>= aUIName;
+ }
+
+ if ( aResourceURL.getLength() > 0 &&
+ rHashMap.find( aResourceURL ) == rHashMap.end() )
+ rHashMap.insert( ToolbarHashMap::value_type( aResourceURL, aUIName ));
+ }
+}
+
+// private function
+Sequence< Sequence< com::sun::star::beans::PropertyValue > > ToolbarsMenuController::getLayoutManagerToolbars( const Reference< ::com::sun::star::frame::XLayoutManager >& rLayoutManager )
+{
+ std::vector< ToolBarInfo > aToolBarArray;
+ Sequence< Reference< XUIElement > > aUIElements = rLayoutManager->getElements();
+ for ( sal_Int32 i = 0; i < aUIElements.getLength(); i++ )
+ {
+ Reference< XUIElement > xUIElement( aUIElements[i] );
+ Reference< XPropertySet > xPropSet( aUIElements[i], UNO_QUERY );
+ if ( xPropSet.is() && xUIElement.is() )
+ {
+ try
+ {
+ rtl::OUString aResName;
+ sal_Int16 nType( -1 );
+ xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ))) >>= nType;
+ xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ))) >>= aResName;
+
+ if (( nType == ::com::sun::star::ui::UIElementType::TOOLBAR ) &&
+ ( aResName.getLength() > 0 ))
+ {
+ ToolBarInfo aToolBarInfo;
+
+ aToolBarInfo.aToolBarResName = aResName;
+
+ SolarMutexGuard aGuard;
+ Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY );
+ Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
+ if ( pWindow )
+ aToolBarInfo.aToolBarUIName = pWindow->GetText();
+
+ aToolBarArray.push_back( aToolBarInfo );
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+
+ Sequence< com::sun::star::beans::PropertyValue > aTbSeq( 2 );
+ aTbSeq[0].Name = m_aPropUIName;
+ aTbSeq[1].Name = m_aPropResourceURL;
+
+ Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeq( aToolBarArray.size() );
+ const sal_uInt32 nCount = aToolBarArray.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ aTbSeq[0].Value <<= aToolBarArray[i].aToolBarUIName;
+ aTbSeq[1].Value <<= aToolBarArray[i].aToolBarResName;
+ aSeq[i] = aTbSeq;
+ }
+
+ return aSeq;
+}
+
+sal_Bool ToolbarsMenuController::isContextSensitiveToolbarNonVisible()
+{
+ return m_bResetActive;
+}
+
+void ToolbarsMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
+{
+ if( SvtMiscOptions().DisableUICustomization() )
+ return;
+
+ SolarMutexGuard aSolarMutexGuard;
+ resetPopupMenu( rPopupMenu );
+
+ m_aCommandVector.clear();
+
+ // Retrieve layout manager for additional information
+ rtl::OUString aEmptyString;
+ Reference< awt::XMenuExtended > xMenuExtended( rPopupMenu, UNO_QUERY );
+ Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( m_xFrame ));
+
+ m_bResetActive = sal_False;
+ if ( xLayoutManager.is() )
+ {
+ ToolbarHashMap aToolbarHashMap;
+
+ if ( m_xDocCfgMgr.is() )
+ {
+ Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqDocToolBars =
+ m_xDocCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
+ fillHashMap( aSeqDocToolBars, aToolbarHashMap );
+ }
+
+ if ( m_xModuleCfgMgr.is() )
+ {
+ Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqToolBars =
+ m_xModuleCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
+ fillHashMap( aSeqToolBars, aToolbarHashMap );
+ }
+
+ std::vector< ToolBarEntry > aSortedTbs;
+ rtl::OUString aStaticCmdPart( RTL_CONSTASCII_USTRINGPARAM( STATIC_CMD_PART ));
+
+ Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqFrameToolBars = getLayoutManagerToolbars( xLayoutManager );
+ fillHashMap( aSeqFrameToolBars, aToolbarHashMap );
+
+ ToolbarHashMap::const_iterator pIter = aToolbarHashMap.begin();
+ while ( pIter != aToolbarHashMap.end() )
+ {
+ rtl::OUString aUIName = pIter->second;
+ sal_Bool bHideFromMenu( sal_False );
+ sal_Bool bContextSensitive( sal_False );
+ sal_Bool bVisible( sal_False );
+ if ( aUIName.getLength() == 0 &&
+ m_xPersistentWindowState.is() )
+ {
+ try
+ {
+ Sequence< PropertyValue > aWindowState;
+ Any a( m_xPersistentWindowState->getByName( pIter->first ));
+
+ if ( a >>= aWindowState )
+ {
+ for ( sal_Int32 i = 0; i < aWindowState.getLength(); i++ )
+ {
+ if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_UINAME ))
+ aWindowState[i].Value >>= aUIName;
+ else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_HIDEFROMENU ))
+ aWindowState[i].Value >>= bHideFromMenu;
+ else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT ))
+ aWindowState[i].Value >>= bContextSensitive;
+ else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE ))
+ aWindowState[i].Value >>= bVisible;
+ }
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ // Check if we have to enable/disable "Reset" menu item
+ if ( bContextSensitive && !bVisible )
+ m_bResetActive = sal_True;
+
+ }
+
+ if (( aUIName.getLength() > 0 ) && ( !bHideFromMenu ))
+ {
+ ToolBarEntry aTbEntry;
+ aTbEntry.aUIName = aUIName;
+ aTbEntry.aCommand = pIter->first;
+ aTbEntry.bVisible = xLayoutManager->isElementVisible( pIter->first );
+ aTbEntry.bContextSensitive = bContextSensitive;
+ aTbEntry.pCollatorWrapper = m_aIntlWrapper.getCaseCollator();
+ aSortedTbs.push_back( aTbEntry );
+ }
+ pIter++;
+ }
+
+ // sort toolbars
+ std::sort( aSortedTbs.begin(), aSortedTbs.end(), CompareToolBarEntry );
+
+ sal_Int16 nIndex( 1 );
+ const sal_uInt32 nCount = aSortedTbs.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
+ m_xPopupMenu->insertItem( nIndex, aSortedTbs[i].aUIName, css::awt::MenuItemStyle::CHECKABLE, nItemCount );
+ if ( aSortedTbs[i].bVisible )
+ m_xPopupMenu->checkItem( nIndex, sal_True );
+
+ {
+ SolarMutexGuard aGuard;
+ VCLXPopupMenu* pXPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( m_xPopupMenu );
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pXPopupMenu->GetMenu();
+
+ pVCLPopupMenu->SetUserValue( nIndex, sal_uIntPtr( aSortedTbs[i].bContextSensitive ? 1L : 0L ));
+ }
+
+ // use VCL popup menu pointer to set vital information that are not part of the awt implementation
+ rtl::OUStringBuffer aStrBuf( aStaticCmdPart );
+
+ sal_Int32 n = aSortedTbs[i].aCommand.lastIndexOf( '/' );
+ if (( n > 0 ) && (( n+1 ) < aSortedTbs[i].aCommand.getLength() ))
+ aStrBuf.append( aSortedTbs[i].aCommand.copy( n+1 ));
+
+ rtl::OUString aCmd( aStrBuf.makeStringAndClear() );
+
+ // Store complete uno-command so it can also be dispatched. This is necessary to support
+ // the test tool!
+ xMenuExtended->setCommand( nIndex, aCmd );
+ ++nIndex;
+ }
+
+ // Create commands for non-toolbars
+ if ( m_aModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.text.TextDocument" ) ) ||
+ m_aModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.text.WebDocument" ) ) ||
+ m_aModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.text.GlobalDocument" ) ) ||
+ m_aModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) ||
+ m_aModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) ||
+ m_aModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ) ))
+ {
+ if ( m_aModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) ||
+ m_aModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ))
+ addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_COLORBAR )), aEmptyString );
+ else if ( m_aModuleIdentifier.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ) ))
+ addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_INPUTLINEBAR )), aEmptyString );
+ else
+ addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_FORMULABAR )), aEmptyString );
+ }
+
+ sal_Bool bAddCommand( sal_True );
+ SvtCommandOptions aCmdOptions;
+ rtl::OUString aConfigureToolbar( RTL_CONSTASCII_USTRINGPARAM( CONFIGURE_TOOLBARS ));
+
+ if ( aCmdOptions.HasEntries( SvtCommandOptions::CMDOPTION_DISABLED ))
+ {
+ if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURE_TOOLBARS_CMD ))))
+ bAddCommand = sal_False;
+ }
+
+ if ( bAddCommand )
+ {
+ // Create command for configure
+ if ( m_xPopupMenu->getItemCount() > 0 )
+ {
+ sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
+ m_xPopupMenu->insertSeparator( nItemCount+1 );
+ }
+
+ addCommand( m_xPopupMenu, aConfigureToolbar, aEmptyString );
+ }
+
+ // Add separator if no configure has been added
+ if ( !bAddCommand )
+ {
+ // Create command for configure
+ if ( m_xPopupMenu->getItemCount() > 0 )
+ {
+ sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
+ m_xPopupMenu->insertSeparator( nItemCount+1 );
+ }
+ }
+
+ String aLabelStr = String( FwkResId( STR_RESTORE_TOOLBARS ));
+ rtl::OUString aRestoreCmd( RTL_CONSTASCII_USTRINGPARAM( CMD_RESTOREVISIBILITY ));
+ addCommand( m_xPopupMenu, aRestoreCmd, aLabelStr );
+ }
+}
+
+// XEventListener
+void SAL_CALL ToolbarsMenuController::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
+
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xDocCfgMgr.clear();
+ m_xModuleCfgMgr.clear();
+ m_xServiceManager.clear();
+
+ if ( m_xPopupMenu.is() )
+ m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
+ m_xPopupMenu.clear();
+}
+
+// XStatusListener
+void SAL_CALL ToolbarsMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
+{
+ rtl::OUString aFeatureURL( Event.FeatureURL.Complete );
+
+ // All other status events will be processed here
+ sal_Bool bSetCheckmark = sal_False;
+ sal_Bool bCheckmark = sal_False;
+
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ Reference< css::awt::XPopupMenu > xPopupMenu( m_xPopupMenu );
+ aLock.clear();
+
+ if ( xPopupMenu.is() )
+ {
+ SolarMutexGuard aGuard;
+ VCLXPopupMenu* pXPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( xPopupMenu );
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pXPopupMenu->GetMenu();
+
+ for ( sal_uInt16 i = 0; i < pVCLPopupMenu->GetItemCount(); i++ )
+ {
+ sal_uInt16 nId = pVCLPopupMenu->GetItemId( i );
+ if ( nId == 0 )
+ continue;
+
+ rtl::OUString aCmd = pVCLPopupMenu->GetItemCommand( nId );
+ if ( aCmd == aFeatureURL )
+ {
+ // Enable/disable item
+ pVCLPopupMenu->EnableItem( nId, Event.IsEnabled );
+
+ // Checkmark
+ if ( Event.State >>= bCheckmark )
+ bSetCheckmark = sal_True;
+
+ if ( bSetCheckmark )
+ pVCLPopupMenu->CheckItem( nId, bCheckmark );
+ else
+ {
+ rtl::OUString aItemText;
+
+ if ( Event.State >>= aItemText )
+ pVCLPopupMenu->SetItemText( nId, aItemText );
+ }
+ }
+ }
+ }
+}
+
+// XMenuListener
+void SAL_CALL ToolbarsMenuController::select( const css::awt::MenuEvent& rEvent ) throw (RuntimeException)
+{
+ Reference< css::awt::XPopupMenu > xPopupMenu;
+ Reference< XMultiServiceFactory > xServiceManager;
+ Reference< XURLTransformer > xURLTransformer;
+ Reference< XFrame > xFrame;
+ Reference< XNameAccess > xPersistentWindowState;
+
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ xPopupMenu = m_xPopupMenu;
+ xServiceManager = m_xServiceManager;
+ xURLTransformer = m_xURLTransformer;
+ xFrame = m_xFrame;
+ xPersistentWindowState = m_xPersistentWindowState;
+ aLock.clear();
+
+ if ( xPopupMenu.is() )
+ {
+ VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( xPopupMenu );
+ if ( pPopupMenu )
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+
+ rtl::OUString aCmd( pVCLPopupMenu->GetItemCommand( rEvent.MenuId ));
+ if ( aCmd.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0 )
+ {
+ // Command to restore the visibility of all context sensitive toolbars
+ Reference< XNameReplace > xNameReplace( xPersistentWindowState, UNO_QUERY );
+ if ( xPersistentWindowState.is() && xNameReplace.is() )
+ {
+ try
+ {
+ Sequence< rtl::OUString > aElementNames = xPersistentWindowState->getElementNames();
+ sal_Int32 nCount = aElementNames.getLength();
+ bool bRefreshToolbars( false );
+
+ for ( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ try
+ {
+ rtl::OUString aElementName = aElementNames[i];
+ Sequence< PropertyValue > aWindowState;
+
+ if ( xPersistentWindowState->getByName( aElementName ) >>= aWindowState )
+ {
+ sal_Bool bVisible( sal_False );
+ sal_Bool bContextSensitive( sal_False );
+ sal_Int32 nVisibleIndex( -1 );
+ for ( sal_Int32 j = 0; j < aWindowState.getLength(); j++ )
+ {
+ if ( aWindowState[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE ))
+ {
+ aWindowState[j].Value >>= bVisible;
+ nVisibleIndex = j;
+ }
+ else if ( aWindowState[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT ))
+ aWindowState[j].Value >>= bContextSensitive;
+ }
+
+ if ( !bVisible && bContextSensitive && nVisibleIndex >= 0 )
+ {
+ // Default is: Every context sensitive toolbar is visible
+ aWindowState[nVisibleIndex].Value <<= sal_True;
+ xNameReplace->replaceByName( aElementName, makeAny( aWindowState ));
+ bRefreshToolbars = true;
+ }
+ }
+ }
+ catch ( NoSuchElementException& )
+ {
+ }
+ }
+
+ if ( bRefreshToolbars )
+ {
+ Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame ));
+ if ( xLayoutManager.is() )
+ {
+ Reference< XPropertySet > xPropSet( xLayoutManager, UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ try
+ {
+ xPropSet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RefreshContextToolbarVisibility" )), makeAny( sal_True ));
+ }
+ catch ( RuntimeException& )
+ {
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+ RefreshToolbars( xFrame );
+ }
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+ else if ( aCmd.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_CMD_PART ))) < 0 )
+ {
+ URL aTargetURL;
+ Sequence<PropertyValue> aArgs;
+
+ aTargetURL.Complete = aCmd;
+ xURLTransformer->parseStrict( aTargetURL );
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( xDispatchProvider.is() )
+ {
+ Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch(
+ aTargetURL, ::rtl::OUString(), 0 );
+
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+ pExecuteInfo->xDispatch = xDispatch;
+ pExecuteInfo->aTargetURL = aTargetURL;
+ pExecuteInfo->aArgs = aArgs;
+ if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
+ UiEventLogHelper(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ToolbarsMenuController"))).log(m_xServiceManager, m_xFrame, aTargetURL, aArgs);
+ Application::PostUserEvent( STATIC_LINK(0, ToolbarsMenuController, ExecuteHdl_Impl), pExecuteInfo );
+ }
+ }
+ else
+ {
+ Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame ));
+ if ( xLayoutManager.is() )
+ {
+ // Extract toolbar name from the combined uno-command.
+ sal_Int32 nIndex = aCmd.indexOf( '=' );
+ if (( nIndex > 0 ) && (( nIndex+1 ) < aCmd.getLength() ))
+ {
+ rtl::OUStringBuffer aBuf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_PRIVATE_TB_RESOURCE )));
+ aBuf.append( aCmd.copy( nIndex+1 ));
+
+ sal_Bool bShow( !pVCLPopupMenu->IsItemChecked( rEvent.MenuId ));
+ rtl::OUString aToolBarResName( aBuf.makeStringAndClear() );
+ if ( bShow )
+ {
+ xLayoutManager->createElement( aToolBarResName );
+ xLayoutManager->showElement( aToolBarResName );
+ }
+ else
+ {
+ // closing means:
+ // hide and destroy element
+ xLayoutManager->hideElement( aToolBarResName );
+ xLayoutManager->destroyElement( aToolBarResName );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void SAL_CALL ToolbarsMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException)
+{
+ std::vector< rtl::OUString > aCmdVector;
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+ Reference< XURLTransformer > xURLTransformer( m_xURLTransformer );
+ {
+ osl::MutexGuard aLock( m_aMutex );
+ fillPopupMenu( m_xPopupMenu );
+ aCmdVector = m_aCommandVector;
+ }
+
+ // Update status for all commands inside our toolbars popup menu
+ const sal_uInt32 nCount = aCmdVector.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ bool bInternal = ( aCmdVector[i].indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0);
+
+ if ( !bInternal )
+ {
+ URL aTargetURL;
+ aTargetURL.Complete = aCmdVector[i];
+ xURLTransformer->parseStrict( aTargetURL );
+ Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+ if ( xDispatch.is() )
+ {
+ xDispatch->addStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
+ xDispatch->removeStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
+ }
+ }
+ else if ( aCmdVector[i].equalsAscii( CMD_RESTOREVISIBILITY ))
+ {
+ // Special code to determine the enable/disable state of this command
+ FeatureStateEvent aFeatureStateEvent;
+ aFeatureStateEvent.FeatureURL.Complete = aCmdVector[i];
+ aFeatureStateEvent.IsEnabled = isContextSensitiveToolbarNonVisible();
+ statusChanged( aFeatureStateEvent );
+ }
+ }
+}
+
+// XPopupMenuController
+void SAL_CALL ToolbarsMenuController::setPopupMenu( const Reference< css::awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ if ( m_xFrame.is() && !m_xPopupMenu.is() )
+ {
+ // Create popup menu on demand
+ SolarMutexGuard aSolarMutexGuard;
+
+ m_xPopupMenu = xPopupMenu;
+ m_xPopupMenu->addMenuListener( Reference< css::awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY ));
+ fillPopupMenu( m_xPopupMenu );
+ }
+}
+
+// XInitialization
+void SAL_CALL ToolbarsMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+ sal_Bool bInitalized( m_bInitialized );
+ if ( !bInitalized )
+ {
+ svt::PopupMenuControllerBase::initialize(aArguments);
+
+ if ( m_bInitialized )
+ {
+ Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance(
+ SERVICENAME_MODULEMANAGER ),
+ UNO_QUERY );
+ Reference< XNameAccess > xPersistentWindowStateSupplier( m_xServiceManager->createInstance(
+ SERVICENAME_WINDOWSTATECONFIGURATION ),
+ UNO_QUERY );
+
+ // Retrieve persistent window state reference for our module
+ if ( xPersistentWindowStateSupplier.is() && xModuleManager.is() )
+ {
+ rtl::OUString aModuleIdentifier;
+ try
+ {
+ aModuleIdentifier = xModuleManager->identify( m_xFrame );
+ xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= m_xPersistentWindowState;
+
+ Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier;
+ if ( m_xServiceManager.is() )
+ xModuleCfgSupplier = Reference< XModuleUIConfigurationManagerSupplier >(
+ m_xServiceManager->createInstance( SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), UNO_QUERY );
+ m_xModuleCfgMgr = xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier );
+
+ Reference< XController > xController = m_xFrame->getController();
+ Reference< XModel > xModel;
+ if ( xController.is() )
+ xModel = xController->getModel();
+ if ( xModel.is() )
+ {
+ Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY );
+ if ( xUIConfigurationManagerSupplier.is() )
+ m_xDocCfgMgr = xUIConfigurationManagerSupplier->getUIConfigurationManager();
+ }
+ m_aModuleIdentifier = aModuleIdentifier;
+ }
+ catch ( Exception& )
+ {
+ }
+ }
+ }
+ }
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( ToolbarsMenuController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
+{
+ try
+ {
+ // Asynchronous execution as this can lead to our own destruction!
+ // Framework can recycle our current frame and the layout manager disposes all user interface
+ // elements if a component gets detached from its frame!
+ if ( pExecuteInfo->xDispatch.is() )
+ {
+ pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
+ }
+ }
+ catch ( Exception& )
+ {
+ }
+
+ delete pExecuteInfo;
+ return 0;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/toolbarwrapper.cxx b/framework/source/uielement/toolbarwrapper.cxx
new file mode 100644
index 000000000000..d32ac97d186b
--- /dev/null
+++ b/framework/source/uielement/toolbarwrapper.cxx
@@ -0,0 +1,351 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+
+#include <uielement/toolbarwrapper.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <framework/actiontriggerhelper.hxx>
+#include <uielement/constitemcontainer.hxx>
+#include <uielement/rootitemcontainer.hxx>
+#include <uielement/toolbarmanager.hxx>
+
+#include <uielement/toolbar.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
+#include <com/sun/star/awt/XMenuBar.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+
+#include <toolkit/unohlp.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <svtools/miscopt.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+#include <rtl/logfile.hxx>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::awt;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+ToolBarWrapper::ToolBarWrapper( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ UIConfigElementWrapperBase( UIElementType::TOOLBAR,xServiceManager )
+{
+}
+
+ToolBarWrapper::~ToolBarWrapper()
+{
+}
+
+// XInterface
+void SAL_CALL ToolBarWrapper::acquire() throw()
+{
+ UIConfigElementWrapperBase::acquire();
+}
+
+void SAL_CALL ToolBarWrapper::release() throw()
+{
+ UIConfigElementWrapperBase::release();
+}
+
+uno::Any SAL_CALL ToolBarWrapper::queryInterface( const uno::Type & rType )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ rType ,
+ SAL_STATIC_CAST( ::com::sun::star::ui::XUIFunctionListener*, this ) );
+
+ if( a.hasValue() )
+ return a;
+
+ return UIConfigElementWrapperBase::queryInterface( rType );
+}
+
+// XComponent
+void SAL_CALL ToolBarWrapper::dispose() throw ( RuntimeException )
+{
+ Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
+
+ {
+ ResetableGuard aLock( m_aLock );
+ if ( m_bDisposed )
+ return;
+ }
+
+ com::sun::star::lang::EventObject aEvent( xThis );
+ m_aListenerContainer.disposeAndClear( aEvent );
+
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_xToolBarManager.is() )
+ m_xToolBarManager->dispose();
+ m_xToolBarManager.clear();
+ m_xConfigSource.clear();
+ m_xConfigData.clear();
+ m_xToolBarWindow.clear();
+
+ m_bDisposed = sal_True;
+}
+
+// XInitialization
+void SAL_CALL ToolBarWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( !m_bInitialized )
+ {
+ UIConfigElementWrapperBase::initialize( aArguments );
+
+ sal_Bool bPopupMode( sal_False );
+ for ( sal_Int32 i = 0; i < aArguments.getLength(); i++ )
+ {
+ PropertyValue aPropValue;
+ if ( aArguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAsciiL( "PopupMode", 9 ))
+ {
+ aPropValue.Value >>= bPopupMode;
+ break;
+ }
+ }
+ }
+
+ Reference< XFrame > xFrame( m_xWeakFrame );
+ if ( xFrame.is() && m_xConfigSource.is() )
+ {
+ // Create VCL based toolbar which will be filled with settings data
+ ToolBar* pToolBar = 0;
+ ToolBarManager* pToolBarManager = 0;
+ {
+ SolarMutexGuard aSolarMutexGuard;
+ Window* pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ if ( pWindow )
+ {
+ sal_uLong nStyles = WB_LINESPACING | WB_BORDER | WB_SCROLL | WB_MOVEABLE | WB_3DLOOK | WB_DOCKABLE | WB_SIZEABLE | WB_CLOSEABLE;
+
+ pToolBar = new ToolBar( pWindow, nStyles );
+ m_xToolBarWindow = VCLUnoHelper::GetInterface( pToolBar );
+ pToolBarManager = new ToolBarManager( m_xServiceFactory, xFrame, m_aResourceURL, pToolBar );
+ pToolBar->SetToolBarManager( pToolBarManager );
+ m_xToolBarManager = Reference< XComponent >( static_cast< OWeakObject *>( pToolBarManager ), UNO_QUERY );
+ pToolBar->WillUsePopupMode( bPopupMode );
+ }
+ }
+
+ try
+ {
+ m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
+ if ( m_xConfigData.is() && pToolBar && pToolBarManager )
+ {
+ // Fill toolbar with container contents
+ pToolBarManager->FillToolbar( m_xConfigData );
+ pToolBar->SetOutStyle( SvtMiscOptions().GetToolboxStyle() );
+ pToolBar->EnableCustomize( sal_True );
+ ::Size aActSize( pToolBar->GetSizePixel() );
+ ::Size aSize( pToolBar->CalcWindowSizePixel() );
+ aSize.Width() = aActSize.Width();
+ pToolBar->SetOutputSizePixel( aSize );
+ }
+ }
+ catch ( NoSuchElementException& )
+ {
+ // No settings in our configuration manager. This means we are
+ // a transient toolbar which has no persistent settings.
+ m_bPersistent = sal_False;
+ if ( pToolBar && pToolBarManager )
+ {
+ pToolBar->SetOutStyle( SvtMiscOptions().GetToolboxStyle() );
+ pToolBar->EnableCustomize( sal_True );
+ ::Size aActSize( pToolBar->GetSizePixel() );
+ ::Size aSize( pToolBar->CalcWindowSizePixel() );
+ aSize.Width() = aActSize.Width();
+ pToolBar->SetOutputSizePixel( aSize );
+ }
+ }
+ }
+ }
+}
+
+// XEventListener
+void SAL_CALL ToolBarWrapper::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+ // nothing todo
+}
+
+// XUpdatable
+void SAL_CALL ToolBarWrapper::update() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
+ if ( pToolBarManager )
+ pToolBarManager->CheckAndUpdateImages();
+}
+
+// XUIElementSettings
+void SAL_CALL ToolBarWrapper::updateSettings() throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_bDisposed )
+ throw DisposedException();
+
+ if ( m_xToolBarManager.is() )
+ {
+ if ( m_xConfigSource.is() && m_bPersistent )
+ {
+ try
+ {
+ ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
+
+ m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
+ if ( m_xConfigData.is() )
+ pToolBarManager->FillToolbar( m_xConfigData );
+ }
+ catch ( NoSuchElementException& )
+ {
+ }
+ }
+ else if ( !m_bPersistent )
+ {
+ // Transient toolbar: do nothing
+ }
+ }
+}
+
+void ToolBarWrapper::impl_fillNewData()
+{
+ // Transient toolbar => Fill toolbar with new data
+ ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
+ if ( pToolBarManager )
+ pToolBarManager->FillToolbar( m_xConfigData );
+}
+
+// XUIElement interface
+Reference< XInterface > SAL_CALL ToolBarWrapper::getRealInterface( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_xToolBarManager.is() )
+ {
+ ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
+ if ( pToolBarManager )
+ {
+ Window* pWindow = (Window *)pToolBarManager->GetToolBar();
+ return Reference< XInterface >( VCLUnoHelper::GetInterface( pWindow ), UNO_QUERY );
+ }
+ }
+
+ return Reference< XInterface >();
+}
+
+//XUIFunctionExecute
+void SAL_CALL ToolBarWrapper::functionExecute(
+ const ::rtl::OUString& aUIElementName,
+ const ::rtl::OUString& aCommand )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( m_xToolBarManager.is() )
+ {
+ ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
+ if ( pToolBarManager )
+ pToolBarManager->notifyRegisteredControllers( aUIElementName, aCommand );
+ }
+}
+
+void SAL_CALL ToolBarWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const com::sun::star::uno::Any& aValue ) throw( com::sun::star::uno::Exception )
+{
+ ResetableGuard aLock( m_aLock );
+ sal_Bool bNoClose( m_bNoClose );
+ aLock.unlock();
+
+ UIConfigElementWrapperBase::setFastPropertyValue_NoBroadcast( nHandle, aValue );
+
+ aLock.lock();
+
+ sal_Bool bNewNoClose( m_bNoClose );
+ if ( m_xToolBarManager.is() && !m_bDisposed && ( bNewNoClose != bNoClose ))
+ {
+ ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() );
+ if ( pToolBarManager )
+ {
+ ToolBox* pToolBox = pToolBarManager->GetToolBar();
+ if ( pToolBox )
+ {
+ if ( bNewNoClose )
+ {
+ pToolBox->SetStyle( pToolBox->GetStyle() & ~WB_CLOSEABLE );
+ pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE );
+ }
+ else
+ {
+ pToolBox->SetStyle( pToolBox->GetStyle() | WB_CLOSEABLE );
+ pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() | WB_CLOSEABLE );
+ }
+ }
+ }
+ }
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uielement/uicommanddescription.cxx b/framework/source/uielement/uicommanddescription.cxx
new file mode 100644
index 000000000000..273d46faf2d8
--- /dev/null
+++ b/framework/source/uielement/uicommanddescription.cxx
@@ -0,0 +1,808 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "uielement/uicommanddescription.hxx"
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+#include "properties.h"
+
+#include "helper/mischelper.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <unotools/configmgr.hxx>
+#include <tools/string.hxx>
+
+#include <vcl/mnemonic.hxx>
+#include <comphelper/sequence.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::frame;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+struct ModuleToCommands
+{
+ const char* pModuleId;
+ const char* pCommands;
+};
+
+static const char GENERIC_UICOMMANDS[] = "generic";
+static const char COMMANDS[] = "Commands";
+static const char CONFIGURATION_ROOT_ACCESS[] = "/org.openoffice.Office.UI.";
+static const char CONFIGURATION_CMD_ELEMENT_ACCESS[] = "/UserInterface/Commands";
+static const char CONFIGURATION_POP_ELEMENT_ACCESS[] = "/UserInterface/Popups";
+static const char CONFIGURATION_PROPERTY_LABEL[] = "Label";
+static const char CONFIGURATION_PROPERTY_CONTEXT_LABEL[] = "ContextLabel";
+
+// Property names of the resulting Property Set
+static const char PROPSET_LABEL[] = "Label";
+static const char PROPSET_NAME[] = "Name";
+static const char PROPSET_POPUP[] = "Popup";
+static const char PROPSET_PROPERTIES[] = "Properties";
+
+// Special resource URLs to retrieve additional information
+static const char PRIVATE_RESOURCE_URL[] = "private:";
+
+const sal_Int32 COMMAND_PROPERTY_IMAGE = 1;
+const sal_Int32 COMMAND_PROPERTY_ROTATE = 2;
+const sal_Int32 COMMAND_PROPERTY_MIRROR = 4;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// Configuration access class for PopupMenuControllerFactory implementation
+//*****************************************************************************************************************
+
+class ConfigurationAccess_UICommand : // Order is neccessary for right initialization!
+ private ThreadHelpBase ,
+ public ::cppu::WeakImplHelper2<XNameAccess,XContainerListener>
+{
+ public:
+ ConfigurationAccess_UICommand( const ::rtl::OUString& aModuleName, const Reference< XNameAccess >& xGenericUICommands, const Reference< XMultiServiceFactory >& rServiceManager );
+ virtual ~ConfigurationAccess_UICommand();
+
+ // XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName )
+ throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasElements()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // container.XContainerListener
+ virtual void SAL_CALL elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException);
+ virtual void SAL_CALL elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException);
+ virtual void SAL_CALL elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException);
+
+ // lang.XEventListener
+ virtual void SAL_CALL disposing( const EventObject& aEvent ) throw(RuntimeException);
+
+ protected:
+ virtual ::com::sun::star::uno::Any SAL_CALL getByNameImpl( const ::rtl::OUString& aName );
+
+ struct CmdToInfoMap
+ {
+ CmdToInfoMap() : bPopup( false ),
+ bCommandNameCreated( false ),
+ nProperties( 0 ) {}
+
+ rtl::OUString aLabel;
+ rtl::OUString aContextLabel;
+ rtl::OUString aCommandName;
+ bool bPopup : 1,
+ bCommandNameCreated : 1;
+ sal_Int32 nProperties;
+ };
+
+ Any getSequenceFromCache( const rtl::OUString& aCommandURL );
+ Any getInfoFromCommand( const rtl::OUString& rCommandURL );
+ void fillInfoFromResult( CmdToInfoMap& rCmdInfo, const rtl::OUString& aLabel );
+ Any getUILabelFromCommand( const rtl::OUString& rCommandURL );
+ Sequence< rtl::OUString > getAllCommands();
+ sal_Bool fillCache();
+ sal_Bool addGenericInfoToCache();
+ void impl_fill(const Reference< XNameAccess >& _xConfigAccess,sal_Bool _bPopup,
+ std::vector< ::rtl::OUString >& aImageCommandVector,
+ std::vector< ::rtl::OUString >& aImageRotateVector,
+ std::vector< ::rtl::OUString >& aImageMirrorVector);
+
+ private:
+ typedef ::boost::unordered_map< ::rtl::OUString,
+ CmdToInfoMap,
+ OUStringHashCode,
+ ::std::equal_to< ::rtl::OUString > > CommandToInfoCache;
+
+ sal_Bool initializeConfigAccess();
+
+ rtl::OUString m_aConfigCmdAccess;
+ rtl::OUString m_aConfigPopupAccess;
+ rtl::OUString m_aPropUILabel;
+ rtl::OUString m_aPropUIContextLabel;
+ rtl::OUString m_aPropLabel;
+ rtl::OUString m_aPropName;
+ rtl::OUString m_aPropPopup;
+ rtl::OUString m_aPropProperties;
+ rtl::OUString m_aBrandName;
+ rtl::OUString m_aXMLFileFormatVersion;
+ rtl::OUString m_aVersion;
+ rtl::OUString m_aExtension;
+ rtl::OUString m_aPrivateResourceURL;
+ Reference< XNameAccess > m_xGenericUICommands;
+ Reference< XMultiServiceFactory > m_xServiceManager;
+ Reference< XMultiServiceFactory > m_xConfigProvider;
+ Reference< XNameAccess > m_xConfigAccess;
+ Reference< XContainerListener > m_xConfigListener;
+ Reference< XNameAccess > m_xConfigAccessPopups;
+ Reference< XContainerListener > m_xConfigAccessListener;
+ Sequence< rtl::OUString > m_aCommandImageList;
+ Sequence< rtl::OUString > m_aCommandRotateImageList;
+ Sequence< rtl::OUString > m_aCommandMirrorImageList;
+ CommandToInfoCache m_aCmdInfoCache;
+ sal_Bool m_bConfigAccessInitialized;
+ sal_Bool m_bCacheFilled;
+ sal_Bool m_bGenericDataRetrieved;
+};
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+ConfigurationAccess_UICommand::ConfigurationAccess_UICommand( const rtl::OUString& aModuleName, const Reference< XNameAccess >& rGenericUICommands, const Reference< XMultiServiceFactory >& rServiceManager ) :
+ ThreadHelpBase(),
+ m_aConfigCmdAccess( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_ROOT_ACCESS )),
+ m_aConfigPopupAccess( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_ROOT_ACCESS )),
+ m_aPropUILabel( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_PROPERTY_LABEL )),
+ m_aPropUIContextLabel( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_PROPERTY_CONTEXT_LABEL )),
+ m_aPropLabel( RTL_CONSTASCII_USTRINGPARAM( PROPSET_LABEL )),
+ m_aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPSET_NAME )),
+ m_aPropPopup( RTL_CONSTASCII_USTRINGPARAM( PROPSET_POPUP )),
+ m_aPropProperties( RTL_CONSTASCII_USTRINGPARAM( PROPSET_PROPERTIES )),
+ m_aPrivateResourceURL( RTL_CONSTASCII_USTRINGPARAM( PRIVATE_RESOURCE_URL )),
+ m_xGenericUICommands( rGenericUICommands ),
+ m_xServiceManager( rServiceManager ),
+ m_bConfigAccessInitialized( sal_False ),
+ m_bCacheFilled( sal_False ),
+ m_bGenericDataRetrieved( sal_False )
+{
+ // Create configuration hierachical access name
+ m_aConfigCmdAccess += aModuleName;
+ m_aConfigCmdAccess += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_CMD_ELEMENT_ACCESS ));
+
+ m_xConfigProvider = Reference< XMultiServiceFactory >( rServiceManager->createInstance(SERVICENAME_CFGPROVIDER),UNO_QUERY );
+
+ m_aConfigPopupAccess += aModuleName;
+ m_aConfigPopupAccess += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_POP_ELEMENT_ACCESS ));
+
+ rtl::OUString aTmp;
+ ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ) >>= aTmp;
+ m_aBrandName = aTmp;
+}
+
+ConfigurationAccess_UICommand::~ConfigurationAccess_UICommand()
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ xContainer->removeContainerListener(m_xConfigListener);
+ xContainer = Reference< XContainer >( m_xConfigAccessPopups, UNO_QUERY );
+ if ( xContainer.is() )
+ xContainer->removeContainerListener(m_xConfigAccessListener);
+}
+
+
+// XNameAccess
+Any SAL_CALL ConfigurationAccess_UICommand::getByNameImpl( const ::rtl::OUString& rCommandURL )
+{
+ static sal_Int32 nRequests = 0;
+
+ ResetableGuard aLock( m_aLock );
+ if ( !m_bConfigAccessInitialized )
+ {
+ initializeConfigAccess();
+ m_bConfigAccessInitialized = sal_True;
+ fillCache();
+ }
+
+ if ( rCommandURL.indexOf( m_aPrivateResourceURL ) == 0 )
+ {
+ // special keys to retrieve information about a set of commands
+ // SAFE
+ addGenericInfoToCache();
+
+ if ( rCommandURL.equalsIgnoreAsciiCaseAscii( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDIMAGELIST ))
+ return makeAny( m_aCommandImageList );
+ else if ( rCommandURL.equalsIgnoreAsciiCaseAscii( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDROTATEIMAGELIST ))
+ return makeAny( m_aCommandRotateImageList );
+ else if ( rCommandURL.equalsIgnoreAsciiCaseAscii( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDMIRRORIMAGELIST ))
+ return makeAny( m_aCommandMirrorImageList );
+ else
+ return Any();
+ }
+ else
+ {
+ // SAFE
+ ++nRequests;
+ return getInfoFromCommand( rCommandURL );
+ }
+}
+
+Any SAL_CALL ConfigurationAccess_UICommand::getByName( const ::rtl::OUString& rCommandURL )
+throw ( NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ Any aRet( getByNameImpl( rCommandURL ) );
+ if( !aRet.hasValue() )
+ throw NoSuchElementException();
+
+ return aRet;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ConfigurationAccess_UICommand::getElementNames()
+throw ( RuntimeException )
+{
+ return getAllCommands();
+}
+
+sal_Bool SAL_CALL ConfigurationAccess_UICommand::hasByName( const ::rtl::OUString& rCommandURL )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ return getByNameImpl( rCommandURL ).hasValue();
+}
+
+// XElementAccess
+Type SAL_CALL ConfigurationAccess_UICommand::getElementType()
+throw ( RuntimeException )
+{
+ return( ::getCppuType( (const Sequence< PropertyValue >*)NULL ) );
+}
+
+sal_Bool SAL_CALL ConfigurationAccess_UICommand::hasElements()
+throw ( RuntimeException )
+{
+ // There must are global commands!
+ return sal_True;
+}
+
+void ConfigurationAccess_UICommand::fillInfoFromResult( CmdToInfoMap& rCmdInfo, const rtl::OUString& aLabel )
+{
+ String rStr( aLabel );
+ if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", m_aBrandName );
+ rCmdInfo.aLabel = ::rtl::OUString( rStr );
+ rStr.EraseTrailingChars( '.' ); // Remove "..." from string
+ rCmdInfo.aCommandName = ::rtl::OUString( MnemonicGenerator::EraseAllMnemonicChars( rStr ));
+ rCmdInfo.bCommandNameCreated = sal_True;
+}
+
+Any ConfigurationAccess_UICommand::getSequenceFromCache( const ::rtl::OUString& aCommandURL )
+{
+ CommandToInfoCache::iterator pIter = m_aCmdInfoCache.find( aCommandURL );
+ if ( pIter != m_aCmdInfoCache.end() )
+ {
+ if ( !pIter->second.bCommandNameCreated )
+ fillInfoFromResult( pIter->second, pIter->second.aLabel );
+
+ Sequence< PropertyValue > aPropSeq( 4 );
+ aPropSeq[0].Name = m_aPropLabel;
+ aPropSeq[0].Value = pIter->second.aContextLabel.getLength() ?
+ makeAny( pIter->second.aContextLabel ): makeAny( pIter->second.aLabel );
+ aPropSeq[1].Name = m_aPropName;
+ aPropSeq[1].Value <<= pIter->second.aCommandName;
+ aPropSeq[2].Name = m_aPropPopup;
+ aPropSeq[2].Value <<= pIter->second.bPopup;
+ aPropSeq[3].Name = m_aPropProperties;
+ aPropSeq[3].Value <<= pIter->second.nProperties;
+ return makeAny( aPropSeq );
+ }
+
+ return Any();
+}
+void ConfigurationAccess_UICommand::impl_fill(const Reference< XNameAccess >& _xConfigAccess,sal_Bool _bPopup,
+ std::vector< ::rtl::OUString >& aImageCommandVector,
+ std::vector< ::rtl::OUString >& aImageRotateVector,
+ std::vector< ::rtl::OUString >& aImageMirrorVector)
+{
+ if ( _xConfigAccess.is() )
+ {
+ Sequence< ::rtl::OUString> aNameSeq = _xConfigAccess->getElementNames();
+ const sal_Int32 nCount = aNameSeq.getLength();
+ for ( sal_Int32 i = 0; i < nCount; i++ )
+ {
+ try
+ {
+ Reference< XNameAccess > xNameAccess(_xConfigAccess->getByName( aNameSeq[i] ),UNO_QUERY);
+ if ( xNameAccess.is() )
+ {
+ CmdToInfoMap aCmdToInfo;
+
+ aCmdToInfo.bPopup = _bPopup;
+ xNameAccess->getByName( m_aPropUILabel ) >>= aCmdToInfo.aLabel;
+ xNameAccess->getByName( m_aPropUIContextLabel ) >>= aCmdToInfo.aContextLabel;
+ xNameAccess->getByName( m_aPropProperties ) >>= aCmdToInfo.nProperties;
+
+ m_aCmdInfoCache.insert( CommandToInfoCache::value_type( aNameSeq[i], aCmdToInfo ));
+
+ if ( aCmdToInfo.nProperties & COMMAND_PROPERTY_IMAGE )
+ aImageCommandVector.push_back( aNameSeq[i] );
+ if ( aCmdToInfo.nProperties & COMMAND_PROPERTY_ROTATE )
+ aImageRotateVector.push_back( aNameSeq[i] );
+ if ( aCmdToInfo.nProperties & COMMAND_PROPERTY_MIRROR )
+ aImageMirrorVector.push_back( aNameSeq[i] );
+ }
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ }
+ }
+}
+sal_Bool ConfigurationAccess_UICommand::fillCache()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ConfigurationAccess_UICommand::fillCache" );
+
+ if ( m_bCacheFilled )
+ return sal_True;
+
+ std::vector< ::rtl::OUString > aImageCommandVector;
+ std::vector< ::rtl::OUString > aImageRotateVector;
+ std::vector< ::rtl::OUString > aImageMirrorVector;
+
+ impl_fill(m_xConfigAccess,sal_False,aImageCommandVector,aImageRotateVector,aImageMirrorVector);
+ impl_fill(m_xConfigAccessPopups,sal_True,aImageCommandVector,aImageRotateVector,aImageMirrorVector);
+ // Create cached sequences for fast retrieving
+ m_aCommandImageList = comphelper::containerToSequence( aImageCommandVector );
+ m_aCommandRotateImageList = comphelper::containerToSequence( aImageRotateVector );
+ m_aCommandMirrorImageList = comphelper::containerToSequence( aImageMirrorVector );
+
+ m_bCacheFilled = sal_True;
+
+ return sal_True;
+}
+
+sal_Bool ConfigurationAccess_UICommand::addGenericInfoToCache()
+{
+ if ( m_xGenericUICommands.is() && !m_bGenericDataRetrieved )
+ {
+ Sequence< rtl::OUString > aCommandNameSeq;
+ try
+ {
+ if ( m_xGenericUICommands->getByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDROTATEIMAGELIST ))) >>= aCommandNameSeq )
+ m_aCommandRotateImageList = comphelper::concatSequences< rtl::OUString >( m_aCommandRotateImageList, aCommandNameSeq );
+ }
+ catch ( RuntimeException& e )
+ {
+ throw e;
+ }
+ catch ( Exception& )
+ {
+ }
+
+ try
+ {
+ if ( m_xGenericUICommands->getByName(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDMIRRORIMAGELIST ))) >>= aCommandNameSeq )
+ m_aCommandMirrorImageList = comphelper::concatSequences< rtl::OUString >( m_aCommandMirrorImageList, aCommandNameSeq );
+ }
+ catch ( RuntimeException& e )
+ {
+ throw e;
+ }
+ catch ( Exception& )
+ {
+ }
+
+ m_bGenericDataRetrieved = sal_True;
+ }
+
+ return sal_True;
+}
+
+Any ConfigurationAccess_UICommand::getInfoFromCommand( const rtl::OUString& rCommandURL )
+{
+ Any a;
+
+ try
+ {
+ a = getSequenceFromCache( rCommandURL );
+ if ( !a.hasValue() )
+ {
+ // First try to ask our global commands configuration access. It also caches maybe
+ // we find the entry in its cache first.
+ if ( m_xGenericUICommands.is() && m_xGenericUICommands->hasByName( rCommandURL ) )
+ {
+ try
+ {
+ return m_xGenericUICommands->getByName( rCommandURL );
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ catch ( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ }
+ }
+ }
+ catch( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+
+ return a;
+}
+
+Sequence< rtl::OUString > ConfigurationAccess_UICommand::getAllCommands()
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigAccessInitialized )
+ {
+ initializeConfigAccess();
+ m_bConfigAccessInitialized = sal_True;
+ fillCache();
+ }
+
+ if ( m_xConfigAccess.is() )
+ {
+ Reference< XNameAccess > xNameAccess;
+
+ try
+ {
+ Sequence< ::rtl::OUString > aNameSeq = m_xConfigAccess->getElementNames();
+
+ if ( m_xGenericUICommands.is() )
+ {
+ // Create concat list of supported user interface commands of the module
+ Sequence< ::rtl::OUString > aGenericNameSeq = m_xGenericUICommands->getElementNames();
+ sal_uInt32 nCount1 = aNameSeq.getLength();
+ sal_uInt32 nCount2 = aGenericNameSeq.getLength();
+
+ aNameSeq.realloc( nCount1 + nCount2 );
+ ::rtl::OUString* pNameSeq = aNameSeq.getArray();
+ const ::rtl::OUString* pGenericSeq = aGenericNameSeq.getConstArray();
+ for ( sal_uInt32 i = 0; i < nCount2; i++ )
+ pNameSeq[nCount1+i] = pGenericSeq[i];
+ }
+
+ return aNameSeq;
+ }
+ catch( com::sun::star::container::NoSuchElementException& )
+ {
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ }
+ }
+
+ return Sequence< rtl::OUString >();
+}
+
+sal_Bool ConfigurationAccess_UICommand::initializeConfigAccess()
+{
+ Sequence< Any > aArgs( 1 );
+ PropertyValue aPropValue;
+
+ try
+ {
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
+ aPropValue.Value <<= m_aConfigCmdAccess;
+ aArgs[0] <<= aPropValue;
+
+ m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ),UNO_QUERY );
+ if ( m_xConfigAccess.is() )
+ {
+ // Add as container listener
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ {
+ m_xConfigListener = new WeakContainerListener(this);
+ xContainer->addContainerListener(m_xConfigListener);
+ }
+ }
+
+ aPropValue.Value <<= m_aConfigPopupAccess;
+ aArgs[0] <<= aPropValue;
+ m_xConfigAccessPopups = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ),UNO_QUERY );
+ if ( m_xConfigAccessPopups.is() )
+ {
+ // Add as container listener
+ Reference< XContainer > xContainer( m_xConfigAccessPopups, UNO_QUERY );
+ if ( xContainer.is() )
+ {
+ m_xConfigAccessListener = new WeakContainerListener(this);
+ xContainer->addContainerListener(m_xConfigAccessListener);
+ }
+ }
+
+ return sal_True;
+ }
+ catch ( WrappedTargetException& )
+ {
+ }
+ catch ( Exception& )
+ {
+ }
+
+ return sal_False;
+}
+
+// container.XContainerListener
+void SAL_CALL ConfigurationAccess_UICommand::elementInserted( const ContainerEvent& ) throw(RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+ m_bCacheFilled = sal_False;
+ fillCache();
+}
+
+void SAL_CALL ConfigurationAccess_UICommand::elementRemoved( const ContainerEvent& ) throw(RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+ m_bCacheFilled = sal_False;
+ fillCache();
+}
+
+void SAL_CALL ConfigurationAccess_UICommand::elementReplaced( const ContainerEvent& ) throw(RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+ m_bCacheFilled = sal_False;
+ fillCache();
+}
+
+// lang.XEventListener
+void SAL_CALL ConfigurationAccess_UICommand::disposing( const EventObject& aEvent ) throw(RuntimeException)
+{
+ // SAFE
+ // remove our reference to the config access
+ ResetableGuard aLock( m_aLock );
+
+ Reference< XInterface > xIfac1( aEvent.Source, UNO_QUERY );
+ Reference< XInterface > xIfac2( m_xConfigAccess, UNO_QUERY );
+ if ( xIfac1 == xIfac2 )
+ m_xConfigAccess.clear();
+ else
+ {
+ xIfac2 = Reference< XInterface >( m_xConfigAccessPopups, UNO_QUERY );
+ if ( xIfac1 == xIfac2 )
+ m_xConfigAccessPopups.clear();
+ }
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( UICommandDescription ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_UICOMMANDDESCRIPTION ,
+ IMPLEMENTATIONNAME_UICOMMANDDESCRIPTION
+ )
+
+DEFINE_INIT_SERVICE ( UICommandDescription, {} )
+
+UICommandDescription::UICommandDescription( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase(),
+ m_aPrivateResourceURL( RTL_CONSTASCII_USTRINGPARAM( PRIVATE_RESOURCE_URL )),
+ m_xServiceManager( xServiceManager )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::UICommandDescription" );
+ Reference< XNameAccess > xEmpty;
+ rtl::OUString aGenericUICommand( RTL_CONSTASCII_USTRINGPARAM("GenericCommands") );
+ m_xGenericUICommands = new ConfigurationAccess_UICommand( aGenericUICommand, xEmpty, xServiceManager );
+
+ impl_fillElements("ooSetupFactoryCommandConfigRef");
+
+ // insert generic commands
+ UICommandsHashMap::iterator pIter = m_aUICommandsHashMap.find( aGenericUICommand );
+ if ( pIter != m_aUICommandsHashMap.end() )
+ pIter->second = m_xGenericUICommands;
+}
+UICommandDescription::UICommandDescription( const Reference< XMultiServiceFactory >& xServiceManager,bool ) :
+ ThreadHelpBase(),
+ m_xServiceManager( xServiceManager )
+{
+}
+UICommandDescription::~UICommandDescription()
+{
+ ResetableGuard aLock( m_aLock );
+ m_aModuleToCommandFileMap.clear();
+ m_aUICommandsHashMap.clear();
+ m_xGenericUICommands.clear();
+}
+void UICommandDescription::impl_fillElements(const sal_Char* _pName)
+{
+ m_xModuleManager.set( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ),UNO_QUERY );
+ Reference< XNameAccess > xNameAccess( m_xModuleManager, UNO_QUERY_THROW );
+ Sequence< rtl::OUString > aElementNames = xNameAccess->getElementNames();
+ Sequence< PropertyValue > aSeq;
+ ::rtl::OUString aModuleIdentifier;
+
+ for ( sal_Int32 i = 0; i < aElementNames.getLength(); i++ )
+ {
+ aModuleIdentifier = aElementNames[i];
+ if ( xNameAccess->getByName( aModuleIdentifier ) >>= aSeq )
+ {
+ ::rtl::OUString aCommandStr;
+ for ( sal_Int32 y = 0; y < aSeq.getLength(); y++ )
+ {
+ if ( aSeq[y].Name.equalsAscii(_pName) )
+ {
+ aSeq[y].Value >>= aCommandStr;
+ break;
+ }
+ }
+
+ // Create first mapping ModuleIdentifier ==> Command File
+ m_aModuleToCommandFileMap.insert( ModuleToCommandFileMap::value_type( aModuleIdentifier, aCommandStr ));
+
+ // Create second mapping Command File ==> commands instance
+ UICommandsHashMap::iterator pIter = m_aUICommandsHashMap.find( aCommandStr );
+ if ( pIter == m_aUICommandsHashMap.end() )
+ m_aUICommandsHashMap.insert( UICommandsHashMap::value_type( aCommandStr, Reference< XNameAccess >() ));
+ }
+ } // for ( sal_Int32 i = 0; i < aElementNames.getLength(); i++ )
+}
+Reference< XNameAccess > UICommandDescription::impl_createConfigAccess(const ::rtl::OUString& _sName)
+{
+ return new ConfigurationAccess_UICommand( _sName,m_xGenericUICommands,m_xServiceManager );
+}
+
+Any SAL_CALL UICommandDescription::getByName( const ::rtl::OUString& aName )
+throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::getByName" );
+ Any a;
+
+ ResetableGuard aLock( m_aLock );
+
+ ModuleToCommandFileMap::const_iterator pM2CIter = m_aModuleToCommandFileMap.find( aName );
+ if ( pM2CIter != m_aModuleToCommandFileMap.end() )
+ {
+ ::rtl::OUString aCommandFile( pM2CIter->second );
+ UICommandsHashMap::iterator pIter = m_aUICommandsHashMap.find( aCommandFile );
+ if ( pIter != m_aUICommandsHashMap.end() )
+ {
+ if ( pIter->second.is() )
+ a <<= pIter->second;
+ else
+ {
+ Reference< XNameAccess > xUICommands;
+ ConfigurationAccess_UICommand* pUICommands = new ConfigurationAccess_UICommand( aCommandFile,
+ m_xGenericUICommands,
+ m_xServiceManager );
+ xUICommands = Reference< XNameAccess >( static_cast< cppu::OWeakObject* >( pUICommands ),UNO_QUERY );
+ pIter->second = xUICommands;
+ a <<= xUICommands;
+ }
+ }
+ }
+ else if ( m_aPrivateResourceURL.getLength() && aName.indexOf( m_aPrivateResourceURL ) == 0 )
+ {
+ // special keys to retrieve information about a set of commands
+ return m_xGenericUICommands->getByName( aName );
+ }
+ else
+ {
+ throw NoSuchElementException();
+ }
+
+ return a;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL UICommandDescription::getElementNames()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::getElementNames" );
+ ResetableGuard aLock( m_aLock );
+
+ Sequence< rtl::OUString > aSeq( m_aModuleToCommandFileMap.size() );
+
+ sal_Int32 n = 0;
+ ModuleToCommandFileMap::const_iterator pIter = m_aModuleToCommandFileMap.begin();
+ while ( pIter != m_aModuleToCommandFileMap.end() )
+ {
+ aSeq[n] = pIter->first;
+ ++pIter;
+ }
+
+ return aSeq;
+}
+
+sal_Bool SAL_CALL UICommandDescription::hasByName( const ::rtl::OUString& aName )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::hasByName" );
+ ResetableGuard aLock( m_aLock );
+
+ ModuleToCommandFileMap::const_iterator pIter = m_aModuleToCommandFileMap.find( aName );
+ return ( pIter != m_aModuleToCommandFileMap.end() );
+}
+
+// XElementAccess
+Type SAL_CALL UICommandDescription::getElementType()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::getElementType" );
+ return( ::getCppuType( (const Reference< XNameAccess >*)NULL ) );
+}
+
+sal_Bool SAL_CALL UICommandDescription::hasElements()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::hasElements" );
+ // generic UI commands are always available!
+ return sal_True;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/addonstoolboxfactory.cxx b/framework/source/uifactory/addonstoolboxfactory.cxx
new file mode 100644
index 000000000000..5340cc6bd65b
--- /dev/null
+++ b/framework/source/uifactory/addonstoolboxfactory.cxx
@@ -0,0 +1,220 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uifactory/addonstoolboxfactory.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uielement/addonstoolbarwrapper.hxx>
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( AddonsToolBoxFactory ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_TOOLBARFACTORY ,
+ IMPLEMENTATIONNAME_ADDONSTOOLBARFACTORY
+ )
+
+DEFINE_INIT_SERVICE ( AddonsToolBoxFactory, {} )
+
+AddonsToolBoxFactory::AddonsToolBoxFactory(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_xServiceManager( xServiceManager )
+ , m_xModuleManager( xServiceManager->createInstance(SERVICENAME_MODULEMANAGER),UNO_QUERY )
+{
+}
+
+AddonsToolBoxFactory::~AddonsToolBoxFactory()
+{
+}
+
+static sal_Bool IsCorrectContext( const ::rtl::OUString& rModuleIdentifier, const rtl::OUString& aContextList )
+{
+ if ( aContextList.getLength() == 0 )
+ return sal_True;
+
+ if ( rModuleIdentifier.getLength() > 0 )
+ {
+ sal_Int32 nIndex = aContextList.indexOf( rModuleIdentifier );
+ return ( nIndex >= 0 );
+ }
+
+ return sal_False;
+}
+
+sal_Bool AddonsToolBoxFactory::hasButtonsInContext(
+ const Sequence< Sequence< PropertyValue > >& rPropSeqSeq,
+ const Reference< XFrame >& rFrame )
+{
+ ::rtl::OUString aModuleIdentifier;
+ try
+ {
+ aModuleIdentifier = m_xModuleManager->identify( rFrame );
+ }
+ catch ( RuntimeException& )
+ {
+ throw;
+ }
+ catch ( Exception& )
+ {
+ }
+
+ // Check before we create a toolbar that we have at least one button in
+ // the current frame context.
+ for ( sal_uInt32 i = 0; i < (sal_uInt32)rPropSeqSeq.getLength(); i++ )
+ {
+ sal_Bool bIsButton( sal_True );
+ sal_Bool bIsCorrectContext( sal_False );
+ sal_uInt32 nPropChecked( 0 );
+
+ const Sequence< PropertyValue >& rPropSeq = rPropSeqSeq[i];
+ for ( sal_uInt32 j = 0; j < (sal_uInt32)rPropSeq.getLength(); j++ )
+ {
+ if ( rPropSeq[j].Name.equalsAsciiL( "Context", 7 ))
+ {
+ ::rtl::OUString aContextList;
+ if ( rPropSeq[j].Value >>= aContextList )
+ bIsCorrectContext = IsCorrectContext( aModuleIdentifier, aContextList );
+ nPropChecked++;
+ }
+ else if ( rPropSeq[j].Name.equalsAsciiL( "URL", 3 ))
+ {
+ ::rtl::OUString aURL;
+ rPropSeq[j].Value >>= aURL;
+ bIsButton = !aURL.equalsAsciiL( "private:separator", 17 );
+ nPropChecked++;
+ }
+
+ if ( nPropChecked == 2 )
+ break;
+ }
+
+ if ( bIsButton && bIsCorrectContext )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+// XUIElementFactory
+Reference< XUIElement > SAL_CALL AddonsToolBoxFactory::createUIElement(
+ const ::rtl::OUString& ResourceURL,
+ const Sequence< PropertyValue >& Args )
+throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException )
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ Sequence< Sequence< PropertyValue > > aConfigData;
+ Reference< XFrame > xFrame;
+ rtl::OUString aResourceURL( ResourceURL );
+
+ for ( sal_Int32 n = 0; n < Args.getLength(); n++ )
+ {
+ if ( Args[n].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ConfigurationData" ) ))
+ Args[n].Value >>= aConfigData;
+ else if ( Args[n].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Frame" ) ))
+ Args[n].Value >>= xFrame;
+ else if ( Args[n].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ResourceURL" ) ))
+ Args[n].Value >>= aResourceURL;
+ }
+
+ if ( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" ))) != 0 )
+ throw IllegalArgumentException();
+
+ // Identify frame and determine module identifier to look for context based buttons
+ Reference< ::com::sun::star::ui::XUIElement > xToolBar;
+ if ( xFrame.is() &&
+ ( aConfigData.getLength()> 0 ) &&
+ hasButtonsInContext( aConfigData, xFrame ))
+ {
+ PropertyValue aPropValue;
+ Sequence< Any > aPropSeq( 3 );
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropValue.Value <<= xFrame;
+ aPropSeq[0] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationData" ));
+ aPropValue.Value <<= aConfigData;
+ aPropSeq[1] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ));
+ aPropValue.Value <<= aResourceURL;
+ aPropSeq[2] <<= aPropValue;
+
+ SolarMutexGuard aGuard;
+ AddonsToolBarWrapper* pToolBarWrapper = new AddonsToolBarWrapper( m_xServiceManager );
+ xToolBar = Reference< ::com::sun::star::ui::XUIElement >( (OWeakObject *)pToolBarWrapper, UNO_QUERY );
+ Reference< XInitialization > xInit( xToolBar, UNO_QUERY );
+ xInit->initialize( aPropSeq );
+ }
+
+ return xToolBar;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/factoryconfiguration.cxx b/framework/source/uifactory/factoryconfiguration.cxx
new file mode 100644
index 000000000000..b324d071ed20
--- /dev/null
+++ b/framework/source/uifactory/factoryconfiguration.cxx
@@ -0,0 +1,347 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "uifactory/factoryconfiguration.hxx"
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+#include "helper/mischelper.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/weak.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::frame;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+rtl::OUString getHashKeyFromStrings( const rtl::OUString& aCommandURL, const rtl::OUString& aModuleName )
+{
+ rtl::OUStringBuffer aKey( aCommandURL );
+ aKey.appendAscii( "-" );
+ aKey.append( aModuleName );
+ return aKey.makeStringAndClear();
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider
+//*****************************************************************************************************************
+ConfigurationAccess_ControllerFactory::ConfigurationAccess_ControllerFactory( Reference< XMultiServiceFactory >& rServiceManager,const ::rtl::OUString& _sRoot,bool _bAskValue ) :
+ ThreadHelpBase(),
+ m_aPropCommand( RTL_CONSTASCII_USTRINGPARAM( "Command" )),
+ m_aPropModule( RTL_CONSTASCII_USTRINGPARAM( "Module" )),
+ m_aPropController( RTL_CONSTASCII_USTRINGPARAM( "Controller" )),
+ m_aPropValue( RTL_CONSTASCII_USTRINGPARAM( "Value" )),
+ m_sRoot(_sRoot),
+ m_xServiceManager( rServiceManager ),
+ m_bConfigAccessInitialized( sal_False ),
+ m_bAskValue(_bAskValue)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::ConfigurationAccess_ControllerFactory" );
+ m_xConfigProvider = Reference< XMultiServiceFactory >( rServiceManager->createInstance( SERVICENAME_CFGPROVIDER),UNO_QUERY );
+}
+
+ConfigurationAccess_ControllerFactory::~ConfigurationAccess_ControllerFactory()
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ xContainer->removeContainerListener(m_xConfigAccessListener);
+}
+
+rtl::OUString ConfigurationAccess_ControllerFactory::getServiceFromCommandModule( const rtl::OUString& rCommandURL, const rtl::OUString& rModule ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::getServiceFromCommandModule" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+ MenuControllerMap::const_iterator pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, rModule ));
+
+ if ( pIter != m_aMenuControllerMap.end() )
+ return pIter->second.m_aImplementationName;
+ else if ( rModule.getLength() )
+ {
+ // Try to detect if we have a generic popup menu controller
+ pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, rtl::OUString() ));
+
+ if ( pIter != m_aMenuControllerMap.end() )
+ return pIter->second.m_aImplementationName;
+ }
+
+ return rtl::OUString();
+}
+rtl::OUString ConfigurationAccess_ControllerFactory::getValueFromCommandModule( const rtl::OUString& rCommandURL, const rtl::OUString& rModule ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::getValueFromCommandModule" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ MenuControllerMap::const_iterator pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, rModule ));
+
+ if ( pIter != m_aMenuControllerMap.end() )
+ return pIter->second.m_aValue;
+ else if ( rModule.getLength() )
+ {
+ // Try to detect if we have a generic popup menu controller
+ pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, rtl::OUString() ));
+
+ if ( pIter != m_aMenuControllerMap.end() )
+ return pIter->second.m_aValue;
+ }
+
+ return rtl::OUString();
+}
+
+
+void ConfigurationAccess_ControllerFactory::addServiceToCommandModule(
+ const rtl::OUString& rCommandURL,
+ const rtl::OUString& rModule,
+ const rtl::OUString& rServiceSpecifier )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::addServiceToCommandModule" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ rtl::OUString aHashKey = getHashKeyFromStrings( rCommandURL, rModule );
+ m_aMenuControllerMap.insert( MenuControllerMap::value_type( aHashKey,ControllerInfo(rServiceSpecifier,::rtl::OUString()) ));
+}
+
+void ConfigurationAccess_ControllerFactory::removeServiceFromCommandModule(
+ const rtl::OUString& rCommandURL,
+ const rtl::OUString& rModule )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::removeServiceFromCommandModule" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ rtl::OUString aHashKey = getHashKeyFromStrings( rCommandURL, rModule );
+ m_aMenuControllerMap.erase( aHashKey );
+}
+
+// container.XContainerListener
+void SAL_CALL ConfigurationAccess_ControllerFactory::elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::elementInserted" );
+ rtl::OUString aCommand;
+ rtl::OUString aModule;
+ rtl::OUString aService;
+ rtl::OUString aValue;
+
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( impl_getElementProps( aEvent.Element, aCommand, aModule, aService, aValue ))
+ {
+ // Create hash key from command and module as they are together a primary key to
+ // the UNO service that implements the popup menu controller.
+ rtl::OUString aHashKey( getHashKeyFromStrings( aCommand, aModule ));
+ ControllerInfo& rControllerInfo = m_aMenuControllerMap[ aHashKey ];
+ rControllerInfo.m_aImplementationName = aService;
+ rControllerInfo.m_aValue = aValue;
+ }
+}
+
+void SAL_CALL ConfigurationAccess_ControllerFactory::elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::elementRemoved" );
+ rtl::OUString aCommand;
+ rtl::OUString aModule;
+ rtl::OUString aService;
+ rtl::OUString aValue;
+
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( impl_getElementProps( aEvent.Element, aCommand, aModule, aService, aValue ))
+ {
+ // Create hash key from command and module as they are together a primary key to
+ // the UNO service that implements the popup menu controller.
+ rtl::OUString aHashKey( getHashKeyFromStrings( aCommand, aModule ));
+ m_aMenuControllerMap.erase( aHashKey );
+ }
+}
+
+void SAL_CALL ConfigurationAccess_ControllerFactory::elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::elementReplaced" );
+ elementInserted(aEvent);
+}
+
+// lang.XEventListener
+void SAL_CALL ConfigurationAccess_ControllerFactory::disposing( const EventObject& ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::disposing" );
+ // SAFE
+ // remove our reference to the config access
+ ResetableGuard aLock( m_aLock );
+ m_xConfigAccess.clear();
+}
+
+void ConfigurationAccess_ControllerFactory::readConfigurationData()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::readConfigurationData" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigAccessInitialized )
+ {
+ Sequence< Any > aArgs( 1 );
+ PropertyValue aPropValue;
+
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
+ aPropValue.Value <<= m_sRoot;
+ aArgs[0] <<= aPropValue;
+
+ try
+ {
+ m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ), UNO_QUERY );
+ }
+ catch ( WrappedTargetException& )
+ {
+ }
+
+ m_bConfigAccessInitialized = sal_True;
+ }
+
+ if ( m_xConfigAccess.is() )
+ {
+ // Read and update configuration data
+ updateConfigurationData();
+
+ uno::Reference< container::XContainer > xContainer( m_xConfigAccess, uno::UNO_QUERY );
+ // UNSAFE
+ aLock.unlock();
+
+ if ( xContainer.is() )
+ {
+ m_xConfigAccessListener = new WeakContainerListener(this);
+ xContainer->addContainerListener(m_xConfigAccessListener);
+ }
+ }
+}
+
+void ConfigurationAccess_ControllerFactory::updateConfigurationData()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::updateConfigurationData" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+ if ( m_xConfigAccess.is() )
+ {
+ Sequence< rtl::OUString > aPopupMenuControllers = m_xConfigAccess->getElementNames();
+
+ rtl::OUString aCommand;
+ rtl::OUString aModule;
+ rtl::OUString aService;
+ rtl::OUString aHashKey;
+ rtl::OUString aValue;
+
+ m_aMenuControllerMap.clear();
+ for ( sal_Int32 i = 0; i < aPopupMenuControllers.getLength(); i++ )
+ {
+ try
+ {
+ if ( impl_getElementProps( m_xConfigAccess->getByName( aPopupMenuControllers[i] ), aCommand, aModule, aService,aValue ))
+ {
+ // Create hash key from command and module as they are together a primary key to
+ // the UNO service that implements the popup menu controller.
+ aHashKey = getHashKeyFromStrings( aCommand, aModule );
+ m_aMenuControllerMap.insert( MenuControllerMap::value_type( aHashKey, ControllerInfo(aService,aValue) ));
+ }
+ }
+ catch ( NoSuchElementException& )
+ {
+ }
+ catch ( WrappedTargetException& )
+ {
+ }
+ }
+ }
+}
+
+sal_Bool ConfigurationAccess_ControllerFactory::impl_getElementProps( const Any& aElement, rtl::OUString& aCommand, rtl::OUString& aModule, rtl::OUString& aServiceSpecifier,rtl::OUString& aValue ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::impl_getElementProps" );
+ Reference< XPropertySet > xPropertySet;
+ aElement >>= xPropertySet;
+
+ if ( xPropertySet.is() )
+ {
+ try
+ {
+ xPropertySet->getPropertyValue( m_aPropCommand ) >>= aCommand;
+ xPropertySet->getPropertyValue( m_aPropModule ) >>= aModule;
+ xPropertySet->getPropertyValue( m_aPropController ) >>= aServiceSpecifier;
+ if ( m_bAskValue )
+ xPropertySet->getPropertyValue( m_aPropValue ) >>= aValue;
+ }
+ catch ( com::sun::star::beans::UnknownPropertyException& )
+ {
+ return sal_False;
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ return sal_False;
+ }
+ }
+
+ return sal_True;
+}
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/menubarfactory.cxx b/framework/source/uifactory/menubarfactory.cxx
new file mode 100644
index 000000000000..2fef7db68f44
--- /dev/null
+++ b/framework/source/uifactory/menubarfactory.cxx
@@ -0,0 +1,210 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uifactory/menubarfactory.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+#include <uielement/menubarwrapper.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#include <vcl/menu.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( MenuBarFactory ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_MENUBARFACTORY ,
+ IMPLEMENTATIONNAME_MENUBARFACTORY
+ )
+
+DEFINE_INIT_SERVICE ( MenuBarFactory, {} )
+
+MenuBarFactory::MenuBarFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase()
+ , m_xServiceManager( xServiceManager )
+ , m_xModuleManager( xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY )
+{
+}
+MenuBarFactory::MenuBarFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager,bool ) :
+ ThreadHelpBase(&Application::GetSolarMutex())
+ , m_xServiceManager( xServiceManager )
+ , m_xModuleManager( xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY )
+{
+}
+
+MenuBarFactory::~MenuBarFactory()
+{
+}
+
+// XUIElementFactory
+Reference< XUIElement > SAL_CALL MenuBarFactory::createUIElement(
+ const ::rtl::OUString& ResourceURL,
+ const Sequence< PropertyValue >& Args )
+throw ( ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException )
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+ MenuBarWrapper* pMenuBarWrapper = new MenuBarWrapper( m_xServiceManager );
+ Reference< ::com::sun::star::ui::XUIElement > xMenuBar( (OWeakObject *)pMenuBarWrapper, UNO_QUERY );
+ Reference< ::com::sun::star::frame::XModuleManager > xModuleManager = m_xModuleManager;
+ aLock.unlock();
+ CreateUIElement(ResourceURL,Args,"MenuOnly","private:resource/menubar/",xMenuBar,xModuleManager,m_xServiceManager);
+ return xMenuBar;
+}
+void MenuBarFactory::CreateUIElement(const ::rtl::OUString& ResourceURL
+ , const Sequence< PropertyValue >& Args
+ ,const char* _pExtraMode
+ ,const char* _pAsciiName
+ ,const Reference< ::com::sun::star::ui::XUIElement >& _xMenuBar
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager >& _xModuleManager
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceManager)
+{
+ Reference< XUIConfigurationManager > xCfgMgr;
+ Reference< XUIConfigurationManager > xConfigSource;
+ Reference< XFrame > xFrame;
+ rtl::OUString aResourceURL( ResourceURL );
+ sal_Bool bPersistent( sal_True );
+ sal_Bool bExtraMode( sal_False );
+
+ for ( sal_Int32 n = 0; n < Args.getLength(); n++ )
+ {
+ if ( Args[n].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ConfigurationSource")) )
+ Args[n].Value >>= xConfigSource;
+ else if ( Args[n].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Frame")) )
+ Args[n].Value >>= xFrame;
+ else if ( Args[n].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ResourceURL")) )
+ Args[n].Value >>= aResourceURL;
+ else if ( Args[n].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Persistent")) )
+ Args[n].Value >>= bPersistent;
+ else if ( _pExtraMode && Args[n].Name.equalsAscii( _pExtraMode ))
+ Args[n].Value >>= bExtraMode;
+ }
+ if ( aResourceURL.indexOf( rtl::OUString::createFromAscii(_pAsciiName)) != 0 )
+ throw IllegalArgumentException();
+
+ // Identify frame and determine document based ui configuration manager/module ui configuration manager
+ if ( xFrame.is() && !xConfigSource.is() )
+ {
+ bool bHasSettings( false );
+ Reference< XModel > xModel;
+
+ Reference< XController > xController = xFrame->getController();
+ if ( xController.is() )
+ xModel = xController->getModel();
+
+ if ( xModel.is() )
+ {
+ Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY );
+ if ( xUIConfigurationManagerSupplier.is() )
+ {
+ xCfgMgr = xUIConfigurationManagerSupplier->getUIConfigurationManager();
+ bHasSettings = xCfgMgr->hasSettings( aResourceURL );
+ }
+ }
+
+ if ( !bHasSettings )
+ {
+ rtl::OUString aModuleIdentifier = _xModuleManager->identify( Reference< XInterface >( xFrame, UNO_QUERY ));
+ if ( aModuleIdentifier.getLength() )
+ {
+ Reference< ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier(
+ _xServiceManager->createInstance( SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), UNO_QUERY );
+ xCfgMgr = xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier );
+ bHasSettings = xCfgMgr->hasSettings( aResourceURL );
+ }
+ }
+ }
+
+ PropertyValue aPropValue;
+ Sequence< Any > aPropSeq( _pExtraMode ? 5 : 4);
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+ aPropValue.Value <<= xFrame;
+ aPropSeq[0] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" ));
+ aPropValue.Value <<= xCfgMgr;
+ aPropSeq[1] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ));
+ aPropValue.Value <<= aResourceURL;
+ aPropSeq[2] <<= aPropValue;
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" ));
+ aPropValue.Value <<= bPersistent;
+ aPropSeq[3] <<= aPropValue;
+ if ( _pExtraMode )
+ {
+ aPropValue.Name = rtl::OUString::createFromAscii(_pExtraMode);
+ aPropValue.Value <<= bExtraMode;
+ aPropSeq[4] <<= aPropValue;
+ }
+
+ SolarMutexGuard aGuard;
+ Reference< XInitialization > xInit( _xMenuBar, UNO_QUERY );
+ xInit->initialize( aPropSeq );
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/popupmenucontrollerfactory.cxx b/framework/source/uifactory/popupmenucontrollerfactory.cxx
new file mode 100644
index 000000000000..fa8641bcaef0
--- /dev/null
+++ b/framework/source/uifactory/popupmenucontrollerfactory.cxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "uifactory/popupmenucontrollerfactory.hxx"
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+#include "uifactory/factoryconfiguration.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/weak.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::frame;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( PopupMenuControllerFactory ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_POPUPMENUCONTROLLERFACTORY ,
+ IMPLEMENTATIONNAME_POPUPMENUCONTROLLERFACTORY
+ )
+
+DEFINE_INIT_SERVICE ( PopupMenuControllerFactory, {} )
+
+PopupMenuControllerFactory::PopupMenuControllerFactory( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ToolbarControllerFactory(xServiceManager,true)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PopupMenuControllerFactory::PopupMenuControllerFactory" );
+ m_pConfigAccess = new ConfigurationAccess_ControllerFactory( m_xServiceManager,rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Controller/Registered/PopupMenu" )) );
+ m_pConfigAccess->acquire();
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/statusbarcontrollerfactory.cxx b/framework/source/uifactory/statusbarcontrollerfactory.cxx
new file mode 100644
index 000000000000..b1f1d7463b0e
--- /dev/null
+++ b/framework/source/uifactory/statusbarcontrollerfactory.cxx
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "uifactory/statusbarcontrollerfactory.hxx"
+#include "uifactory/factoryconfiguration.hxx"
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/weak.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::frame;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( StatusbarControllerFactory ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_STATUSBARCONTROLLERFACTORY ,
+ IMPLEMENTATIONNAME_STATUSBARCONTROLLERFACTORY
+ )
+
+DEFINE_INIT_SERVICE ( StatusbarControllerFactory, {} )
+
+StatusbarControllerFactory::StatusbarControllerFactory( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ToolbarControllerFactory(xServiceManager,true)
+{
+ m_pConfigAccess = new ConfigurationAccess_ControllerFactory( m_xServiceManager,rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Controller/Registered/StatusBar" )),true );
+ m_pConfigAccess->acquire();
+}
+
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/statusbarfactory.cxx b/framework/source/uifactory/statusbarfactory.cxx
new file mode 100644
index 000000000000..dc523dc3dfd5
--- /dev/null
+++ b/framework/source/uifactory/statusbarfactory.cxx
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uifactory/statusbarfactory.hxx>
+#include <uifactory/menubarfactory.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uielement/statusbarwrapper.hxx>
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( StatusBarFactory ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_STATUSBARFACTORY ,
+ IMPLEMENTATIONNAME_STATUSBARFACTORY
+ )
+
+DEFINE_INIT_SERVICE ( StatusBarFactory, {} )
+
+StatusBarFactory::StatusBarFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ MenuBarFactory( xServiceManager,true )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarFactory::StatusBarFactory" );
+}
+
+// XUIElementFactory
+Reference< XUIElement > SAL_CALL StatusBarFactory::createUIElement(
+ const ::rtl::OUString& ResourceURL,
+ const Sequence< PropertyValue >& Args )
+throw ( ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "StatusBarFactory::createUIElement" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+ StatusBarWrapper* pWrapper = new StatusBarWrapper( m_xServiceManager );
+ Reference< ::com::sun::star::ui::XUIElement > xMenuBar( (OWeakObject *)pWrapper, UNO_QUERY );
+ Reference< ::com::sun::star::frame::XModuleManager > xModuleManager = m_xModuleManager;
+ aLock.unlock();
+ MenuBarFactory::CreateUIElement(ResourceURL,Args,NULL,"private:resource/statusbar/",xMenuBar,xModuleManager,m_xServiceManager);
+ return xMenuBar;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/toolbarcontrollerfactory.cxx b/framework/source/uifactory/toolbarcontrollerfactory.cxx
new file mode 100644
index 000000000000..7bea7c329172
--- /dev/null
+++ b/framework/source/uifactory/toolbarcontrollerfactory.cxx
@@ -0,0 +1,263 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "uifactory/toolbarcontrollerfactory.hxx"
+#include "uifactory/factoryconfiguration.hxx"
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/weak.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::frame;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( ToolbarControllerFactory ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_TOOLBARCONTROLLERFACTORY ,
+ IMPLEMENTATIONNAME_TOOLBARCONTROLLERFACTORY
+ )
+
+DEFINE_INIT_SERVICE ( ToolbarControllerFactory, {} )
+
+ToolbarControllerFactory::ToolbarControllerFactory( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase(),
+ m_bConfigRead( sal_False ),
+ m_xServiceManager( xServiceManager )
+{
+ m_pConfigAccess = new ConfigurationAccess_ControllerFactory( m_xServiceManager,rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Controller/Registered/ToolBar" )) );
+ m_pConfigAccess->acquire();
+}
+
+ToolbarControllerFactory::ToolbarControllerFactory( const Reference< XMultiServiceFactory >& xServiceManager,bool ) :
+ ThreadHelpBase(),
+ m_bConfigRead( sal_False ),
+ m_xServiceManager( xServiceManager )
+{
+ m_pConfigAccess = NULL;
+}
+
+ToolbarControllerFactory::~ToolbarControllerFactory()
+{
+ ResetableGuard aLock( m_aLock );
+
+ // reduce reference count
+ m_pConfigAccess->release();
+}
+
+// XMultiComponentFactory
+Reference< XInterface > SAL_CALL ToolbarControllerFactory::createInstanceWithContext(
+ const ::rtl::OUString& aServiceSpecifier,
+ const Reference< XComponentContext >& )
+throw (Exception, RuntimeException)
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ rtl::OUString aServiceName = m_pConfigAccess->getServiceFromCommandModule( aServiceSpecifier, rtl::OUString() );
+ if ( aServiceName.getLength() > 0 )
+ return m_xServiceManager->createInstance( aServiceName );
+ else
+ return Reference< XInterface >();
+ // SAFE
+}
+
+Reference< XInterface > SAL_CALL ToolbarControllerFactory::createInstanceWithArgumentsAndContext(
+ const ::rtl::OUString& ServiceSpecifier,
+ const Sequence< Any >& Arguments,
+ const Reference< XComponentContext >& )
+throw (Exception, RuntimeException)
+{
+ const rtl::OUString aPropModuleName( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
+ const rtl::OUString aPropValueName( RTL_CONSTASCII_USTRINGPARAM( "Value" ));
+
+ rtl::OUString aPropName;
+ PropertyValue aPropValue;
+
+ // Retrieve the optional module name form the Arguments sequence. It is used as a part of
+ // the hash map key to support different controller implementation for the same URL but different
+ // module!!
+ for ( int i = 0; i < Arguments.getLength(); i++ )
+ {
+ if (( Arguments[i] >>= aPropValue ) && ( aPropValue.Name.equals( aPropModuleName )))
+ {
+ aPropValue.Value >>= aPropName;
+ break;
+ }
+ }
+
+ Sequence< Any > aNewArgs( Arguments );
+
+ sal_Int32 nAppendIndex = aNewArgs.getLength();
+ bool bHasValue = m_pConfigAccess->hasValue();
+ aNewArgs.realloc( aNewArgs.getLength() + (bHasValue ? 2 : 1) );
+
+ // Append the command URL to the Arguments sequence so that one controller can be
+ // used for more than one command URL.
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
+ aPropValue.Value <<= ServiceSpecifier;
+ aNewArgs[nAppendIndex] <<= aPropValue;
+
+ if ( bHasValue )
+ {
+ // Append the optional value argument. It's an empty string if no additional info
+ // is provided to the controller.
+ rtl::OUString aValue = m_pConfigAccess->getValueFromCommandModule( ServiceSpecifier, aPropName );
+ aPropValue.Name = aPropValueName;
+ aPropValue.Value <<= aValue;
+ aNewArgs[nAppendIndex+1] <<= aPropValue;
+ }
+
+ {
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ rtl::OUString aServiceName = m_pConfigAccess->getServiceFromCommandModule( ServiceSpecifier, aPropName );
+ Reference< XMultiServiceFactory > xServiceManager( m_xServiceManager );
+
+ aLock.unlock();
+ // SAFE
+
+
+ if ( aServiceName.getLength() > 0 )
+ return xServiceManager->createInstanceWithArguments( aServiceName, aNewArgs );
+ else
+ return Reference< XInterface >();
+ }
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ToolbarControllerFactory::getAvailableServiceNames()
+throw (RuntimeException)
+{
+ return Sequence< ::rtl::OUString >();
+}
+
+// XUIControllerRegistration
+sal_Bool SAL_CALL ToolbarControllerFactory::hasController(
+ const ::rtl::OUString& aCommandURL,
+ const rtl::OUString& aModuleName )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ return ( m_pConfigAccess->getServiceFromCommandModule( aCommandURL, aModuleName ).getLength() > 0 );
+}
+
+void SAL_CALL ToolbarControllerFactory::registerController(
+ const ::rtl::OUString& aCommandURL,
+ const ::rtl::OUString& aModuleName,
+ const ::rtl::OUString& aControllerImplementationName )
+throw (RuntimeException)
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ m_pConfigAccess->addServiceToCommandModule( aCommandURL, aModuleName, aControllerImplementationName );
+ // SAFE
+}
+
+void SAL_CALL ToolbarControllerFactory::deregisterController(
+ const ::rtl::OUString& aCommandURL,
+ const rtl::OUString& aModuleName )
+throw (RuntimeException)
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ m_pConfigAccess->removeServiceFromCommandModule( aCommandURL, aModuleName );
+ // SAFE
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/toolboxfactory.cxx b/framework/source/uifactory/toolboxfactory.cxx
new file mode 100644
index 000000000000..f8af5372018b
--- /dev/null
+++ b/framework/source/uifactory/toolboxfactory.cxx
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <uifactory/toolboxfactory.hxx>
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uielement/toolbarwrapper.hxx>
+#include <threadhelp/resetableguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
+
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( ToolBoxFactory ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_TOOLBARFACTORY ,
+ IMPLEMENTATIONNAME_TOOLBARFACTORY
+ )
+
+DEFINE_INIT_SERVICE ( ToolBoxFactory, {} )
+
+ToolBoxFactory::ToolBoxFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
+ MenuBarFactory( xServiceManager,true )
+{
+}
+
+// XUIElementFactory
+Reference< XUIElement > SAL_CALL ToolBoxFactory::createUIElement(
+ const ::rtl::OUString& ResourceURL,
+ const Sequence< PropertyValue >& Args )
+throw ( ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException )
+{
+ ResetableGuard aLock( m_aLock );
+ ToolBarWrapper* pWrapper = new ToolBarWrapper( m_xServiceManager );
+ Reference< ::com::sun::star::ui::XUIElement > xMenuBar( (OWeakObject *)pWrapper, UNO_QUERY );
+ Reference< ::com::sun::star::frame::XModuleManager > xModuleManager = m_xModuleManager;
+ aLock.unlock();
+ CreateUIElement(ResourceURL,Args,"PopupMode","private:resource/toolbar/",xMenuBar,xModuleManager,m_xServiceManager);
+ return xMenuBar;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/uielementfactorymanager.cxx b/framework/source/uifactory/uielementfactorymanager.cxx
new file mode 100644
index 000000000000..34ed345bb257
--- /dev/null
+++ b/framework/source/uifactory/uielementfactorymanager.cxx
@@ -0,0 +1,554 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uifactory/uielementfactorymanager.hxx>
+#include <uifactory/windowcontentfactorymanager.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+#include "helper/mischelper.hxx"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/weak.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::ui;
+using namespace ::com::sun::star::frame;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+
+// global function needed by both implementations
+rtl::OUString getHashKeyFromStrings( const rtl::OUString& aType, const rtl::OUString& aName, const rtl::OUString& aModuleName )
+{
+ rtl::OUStringBuffer aKey( aType );
+ aKey.appendAscii( "^" );
+ aKey.append( aName );
+ aKey.appendAscii( "^" );
+ aKey.append( aModuleName );
+ return aKey.makeStringAndClear();
+}
+
+
+//*****************************************************************************************************************
+// Configuration access class for UIElementFactoryManager implementation
+//*****************************************************************************************************************
+
+
+ConfigurationAccess_FactoryManager::ConfigurationAccess_FactoryManager( Reference< XMultiServiceFactory >& rServiceManager,const ::rtl::OUString& _sRoot ) :
+ ThreadHelpBase(),
+ m_aPropType( RTL_CONSTASCII_USTRINGPARAM( "Type" )),
+ m_aPropName( RTL_CONSTASCII_USTRINGPARAM( "Name" )),
+ m_aPropModule( RTL_CONSTASCII_USTRINGPARAM( "Module" )),
+ m_aPropFactory( RTL_CONSTASCII_USTRINGPARAM( "FactoryImplementation" )),
+ m_sRoot(_sRoot),
+ m_xServiceManager( rServiceManager ),
+ m_bConfigAccessInitialized( sal_False ),
+ m_bConfigDirty(true)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::ConfigurationAccess_FactoryManager" );
+ m_xConfigProvider = Reference< XMultiServiceFactory >( rServiceManager->createInstance( SERVICENAME_CFGPROVIDER),UNO_QUERY );
+}
+
+ConfigurationAccess_FactoryManager::~ConfigurationAccess_FactoryManager()
+{
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ xContainer->removeContainerListener(m_xConfigListener);
+}
+
+rtl::OUString ConfigurationAccess_FactoryManager::getFactorySpecifierFromTypeNameModule( const rtl::OUString& rType, const rtl::OUString& rName, const rtl::OUString& rModule ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::getFactorySpecifierFromTypeNameModule" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ FactoryManagerMap::const_iterator pIter =
+ m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, rName, rModule ));
+ if ( pIter != m_aFactoryManagerMap.end() )
+ return pIter->second;
+ else
+ {
+ pIter = m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, rName, rtl::OUString() ));
+ if ( pIter != m_aFactoryManagerMap.end() )
+ return pIter->second;
+ else
+ {
+ // Support factories which uses a defined prefix before the ui name.
+ sal_Int32 nIndex = rName.indexOf( '_' );
+ if ( nIndex > 0 )
+ {
+ rtl::OUString aName = rName.copy( 0, nIndex+1 );
+ pIter = m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, aName, rtl::OUString() ));
+ if ( pIter != m_aFactoryManagerMap.end() )
+ return pIter->second;
+ }
+
+ pIter = m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, rtl::OUString(), rtl::OUString() ));
+ if ( pIter != m_aFactoryManagerMap.end() )
+ return pIter->second;
+ }
+ }
+
+ return rtl::OUString();
+}
+
+void ConfigurationAccess_FactoryManager::addFactorySpecifierToTypeNameModule( const rtl::OUString& rType, const rtl::OUString& rName, const rtl::OUString& rModule, const rtl::OUString& rServiceSpecifier )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::addFactorySpecifierToTypeNameModule" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ rtl::OUString aHashKey = getHashKeyFromStrings( rType, rName, rModule );
+
+ FactoryManagerMap::const_iterator pIter = m_aFactoryManagerMap.find( aHashKey );
+
+ if ( pIter != m_aFactoryManagerMap.end() )
+ throw ElementExistException();
+ else
+ m_aFactoryManagerMap.insert( FactoryManagerMap::value_type( aHashKey, rServiceSpecifier ));
+}
+
+
+void ConfigurationAccess_FactoryManager::removeFactorySpecifierFromTypeNameModule( const rtl::OUString& rType, const rtl::OUString& rName, const rtl::OUString& rModule )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::removeFactorySpecifierFromTypeNameModule" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ rtl::OUString aHashKey = getHashKeyFromStrings( rType, rName, rModule );
+
+ FactoryManagerMap::const_iterator pIter = m_aFactoryManagerMap.find( aHashKey );
+
+ if ( pIter == m_aFactoryManagerMap.end() )
+ throw NoSuchElementException();
+ else
+ m_aFactoryManagerMap.erase( aHashKey );
+}
+
+Sequence< Sequence< PropertyValue > > ConfigurationAccess_FactoryManager::getFactoriesDescription() const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::getFactoriesDescription" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ Sequence< Sequence< PropertyValue > > aSeqSeq;
+
+ sal_Int32 nIndex( 0 );
+ FactoryManagerMap::const_iterator pIter = m_aFactoryManagerMap.begin();
+ while ( pIter != m_aFactoryManagerMap.end() )
+ {
+ rtl::OUString aFactory = pIter->first;
+ if ( aFactory.getLength() > 0 )
+ {
+ sal_Int32 nToken = 0;
+ Sequence< PropertyValue > aSeq( 1 );
+
+ aSeqSeq.realloc( aSeqSeq.getLength() + 1 );
+ aSeq[0].Name = m_aPropType;
+ aSeq[0].Value = makeAny( aFactory.getToken( 0, '^', nToken ));
+ if ( nToken > 0 )
+ {
+ aSeq.realloc( 2 );
+ aSeq[1].Name = m_aPropName;
+ aSeq[1].Value = makeAny( aFactory.getToken( 0, '^', nToken ));
+ if ( nToken > 0 )
+ {
+ aSeq.realloc( 3 );
+ aSeq[2].Name = m_aPropModule;
+ aSeq[2].Value = makeAny( aFactory.getToken( 0, '^', nToken ));
+ }
+ }
+
+ aSeqSeq[nIndex++] = aSeq;
+ }
+
+ ++pIter;
+ }
+
+ return aSeqSeq;
+}
+
+// container.XContainerListener
+void SAL_CALL ConfigurationAccess_FactoryManager::elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::elementInserted" );
+ rtl::OUString aType;
+ rtl::OUString aName;
+ rtl::OUString aModule;
+ rtl::OUString aService;
+
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( impl_getElementProps( aEvent.Element, aType, aName, aModule, aService ))
+ {
+ // Create hash key from type, name and module as they are together a primary key to
+ // the UNO service that implements a user interface factory.
+ rtl::OUString aHashKey( getHashKeyFromStrings( aType, aName, aModule ));
+ m_aFactoryManagerMap.insert( FactoryManagerMap::value_type( aHashKey, aService ));
+ }
+}
+
+void SAL_CALL ConfigurationAccess_FactoryManager::elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::elementRemoved " );
+ rtl::OUString aType;
+ rtl::OUString aName;
+ rtl::OUString aModule;
+ rtl::OUString aService;
+
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( impl_getElementProps( aEvent.Element, aType, aName, aModule, aService ))
+ {
+ // Create hash key from command and model as they are together a primary key to
+ // the UNO service that implements the popup menu controller.
+ rtl::OUString aHashKey( getHashKeyFromStrings( aType, aName, aModule ));
+ m_aFactoryManagerMap.erase( aHashKey );
+ }
+}
+
+void SAL_CALL ConfigurationAccess_FactoryManager::elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::elementReplaced" );
+ rtl::OUString aType;
+ rtl::OUString aName;
+ rtl::OUString aModule;
+ rtl::OUString aService;
+
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( impl_getElementProps( aEvent.Element, aType, aName, aModule, aService ))
+ {
+ // Create hash key from command and model as they are together a primary key to
+ // the UNO service that implements the popup menu controller.
+ rtl::OUString aHashKey( getHashKeyFromStrings( aType, aName, aModule ));
+ m_aFactoryManagerMap.erase( aHashKey );
+ m_aFactoryManagerMap.insert( FactoryManagerMap::value_type( aHashKey, aService ));
+ }
+}
+
+// lang.XEventListener
+void SAL_CALL ConfigurationAccess_FactoryManager::disposing( const EventObject& ) throw(RuntimeException)
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::disposing" );
+ // SAFE
+ // remove our reference to the config access
+ ResetableGuard aLock( m_aLock );
+ m_xConfigAccess.clear();
+}
+
+void ConfigurationAccess_FactoryManager::readConfigurationData()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::readConfigurationData" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigAccessInitialized )
+ {
+ Sequence< Any > aArgs( 1 );
+ PropertyValue aPropValue;
+
+ aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
+ aPropValue.Value <<= m_sRoot;
+ aArgs[0] <<= aPropValue;
+
+ try
+ {
+ m_xConfigAccess.set( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ), UNO_QUERY );
+ }
+ catch ( WrappedTargetException& )
+ {
+ }
+
+ m_bConfigAccessInitialized = sal_True;
+ }
+
+ if ( m_xConfigAccess.is() )
+ {
+ Sequence< rtl::OUString > aUIElementFactories = m_xConfigAccess->getElementNames();
+
+ rtl::OUString aType;
+ rtl::OUString aName;
+ rtl::OUString aModule;
+ rtl::OUString aService;
+ rtl::OUString aHashKey;
+ Reference< XPropertySet > xPropertySet;
+ for ( sal_Int32 i = 0; i < aUIElementFactories.getLength(); i++ )
+ {
+ if ( impl_getElementProps( m_xConfigAccess->getByName( aUIElementFactories[i] ), aType, aName, aModule, aService ))
+ {
+ // Create hash key from type, name and module as they are together a primary key to
+ // the UNO service that implements the user interface element factory.
+ aHashKey = getHashKeyFromStrings( aType, aName, aModule );
+ m_aFactoryManagerMap.insert( FactoryManagerMap::value_type( aHashKey, aService ));
+ }
+ }
+
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ aLock.unlock();
+ // UNSAFE
+ if ( xContainer.is() )
+ {
+ m_xConfigListener = new WeakContainerListener(this);
+ xContainer->addContainerListener(m_xConfigListener);
+ }
+ }
+}
+
+sal_Bool ConfigurationAccess_FactoryManager::impl_getElementProps( const Any& aElement, rtl::OUString& rType, rtl::OUString& rName, rtl::OUString& rModule, rtl::OUString& rServiceSpecifier ) const
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::impl_getElementProps" );
+ Reference< XPropertySet > xPropertySet;
+ aElement >>= xPropertySet;
+
+ if ( xPropertySet.is() )
+ {
+ try
+ {
+ xPropertySet->getPropertyValue( m_aPropType ) >>= rType;
+ xPropertySet->getPropertyValue( m_aPropName ) >>= rName;
+ xPropertySet->getPropertyValue( m_aPropModule ) >>= rModule;
+ xPropertySet->getPropertyValue( m_aPropFactory ) >>= rServiceSpecifier;
+ }
+ catch ( com::sun::star::beans::UnknownPropertyException& )
+ {
+ return sal_False;
+ }
+ catch ( com::sun::star::lang::WrappedTargetException& )
+ {
+ return sal_False;
+ }
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( UIElementFactoryManager ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_UIELEMENTFACTORYMANAGER ,
+ IMPLEMENTATIONNAME_UIELEMENTFACTORYMANAGER
+ )
+
+DEFINE_INIT_SERVICE ( UIElementFactoryManager, {} )
+
+UIElementFactoryManager::UIElementFactoryManager( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_bConfigRead( sal_False ),
+ m_xServiceManager( xServiceManager )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::UIElementFactoryManager" );
+ m_pConfigAccess = new ConfigurationAccess_FactoryManager( m_xServiceManager,rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Factories/Registered/UIElementFactories" )) );
+ m_pConfigAccess->acquire();
+ m_xModuleManager = Reference< XModuleManager >( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY );
+}
+
+UIElementFactoryManager::~UIElementFactoryManager()
+{
+ ResetableGuard aLock( m_aLock );
+
+ // reduce reference count
+ m_pConfigAccess->release();
+}
+
+// XUIElementFactory
+Reference< XUIElement > SAL_CALL UIElementFactoryManager::createUIElement(
+ const ::rtl::OUString& ResourceURL,
+ const Sequence< PropertyValue >& Args )
+throw ( ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::createUIElement" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ const rtl::OUString aPropFrame( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
+
+ rtl::OUString aModuleId;
+ PropertyValue aPropValue;
+ Reference< XFrame > xFrame;
+
+ // Retrieve the frame instance from the arguments to determine the module identifier. This must be provided
+ // to the search function. An empty module identifier is provided if the frame is missing or the module id cannot
+ // retrieve from it.
+ for ( int i = 0; i < Args.getLength(); i++ )
+ {
+ if ( Args[i].Name.equals( aPropFrame ))
+ Args[i].Value >>= xFrame;
+ }
+
+ Reference< XModuleManager > xManager( m_xModuleManager );
+ aLock.unlock();
+
+ // Determine the module identifier
+ try
+ {
+ if ( xFrame.is() && xManager.is() )
+ aModuleId = xManager->identify( Reference< XInterface >( xFrame, UNO_QUERY ) );
+
+ Reference< XUIElementFactory > xUIElementFactory = getFactory( ResourceURL, aModuleId );
+ if ( xUIElementFactory.is() )
+ return xUIElementFactory->createUIElement( ResourceURL, Args );
+ }
+ catch ( UnknownModuleException& )
+ {
+ }
+
+ throw NoSuchElementException();
+}
+
+// XUIElementFactoryRegistration
+Sequence< Sequence< PropertyValue > > SAL_CALL UIElementFactoryManager::getRegisteredFactories()
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::getRegisteredFactories" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ return m_pConfigAccess->getFactoriesDescription();
+}
+
+Reference< XUIElementFactory > SAL_CALL UIElementFactoryManager::getFactory( const ::rtl::OUString& aResourceURL, const ::rtl::OUString& aModuleId )
+throw ( RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::getFactory" );
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ rtl::OUString aType;
+ rtl::OUString aName;
+
+ WindowContentFactoryManager::RetrieveTypeNameFromResourceURL( aResourceURL, aType, aName );
+
+ Reference< XMultiServiceFactory > xSManager( m_xServiceManager );
+
+ rtl::OUString aServiceSpecifier = m_pConfigAccess->getFactorySpecifierFromTypeNameModule( aType, aName, aModuleId );
+
+ aLock.unlock();
+ if ( aServiceSpecifier.getLength() )
+ return Reference< XUIElementFactory >( xSManager->createInstance( aServiceSpecifier ), UNO_QUERY );
+ else
+ return Reference< XUIElementFactory >();
+}
+
+void SAL_CALL UIElementFactoryManager::registerFactory( const ::rtl::OUString& aType, const ::rtl::OUString& aName, const ::rtl::OUString& aModuleId, const ::rtl::OUString& aFactoryImplementationName )
+throw ( ElementExistException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::registerFactory" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ m_pConfigAccess->addFactorySpecifierToTypeNameModule( aType, aName, aModuleId, aFactoryImplementationName );
+ // SAFE
+}
+
+void SAL_CALL UIElementFactoryManager::deregisterFactory( const ::rtl::OUString& aType, const ::rtl::OUString& aName, const ::rtl::OUString& aModuleId )
+throw ( NoSuchElementException, RuntimeException )
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::deregisterFactory" );
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ m_pConfigAccess->removeFactorySpecifierFromTypeNameModule( aType, aName, aModuleId );
+ // SAFE
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/windowcontentfactorymanager.cxx b/framework/source/uifactory/windowcontentfactorymanager.cxx
new file mode 100644
index 000000000000..df02b00e3bd7
--- /dev/null
+++ b/framework/source/uifactory/windowcontentfactorymanager.cxx
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <uifactory/windowcontentfactorymanager.hxx>
+#include <uifactory/uielementfactorymanager.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include "services.h"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/awt/XToolkit.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/weak.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star;
+
+//_________________________________________________________________________________________________________________
+// Namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+
+//*****************************************************************************************************************
+// XInterface, XTypeProvider, XServiceInfo
+//*****************************************************************************************************************
+DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( WindowContentFactoryManager ,
+ ::cppu::OWeakObject ,
+ SERVICENAME_WINDOWCONTENTFACTORYMANAGER ,
+ IMPLEMENTATIONNAME_WINDOWCONTENTFACTORYMANAGER
+ )
+
+DEFINE_INIT_SERVICE ( WindowContentFactoryManager, {} )
+
+WindowContentFactoryManager::WindowContentFactoryManager( const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) :
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ m_bConfigRead( sal_False ),
+ m_xServiceManager( xServiceManager )
+{
+ m_pConfigAccess = new ConfigurationAccess_FactoryManager( m_xServiceManager,rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.WindowContentFactories/Registered/ContentFactories" )) );
+ m_pConfigAccess->acquire();
+ m_xModuleManager = uno::Reference< frame::XModuleManager >( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), uno::UNO_QUERY );
+}
+
+WindowContentFactoryManager::~WindowContentFactoryManager()
+{
+ ResetableGuard aLock( m_aLock );
+
+ // reduce reference count
+ m_pConfigAccess->release();
+}
+
+void WindowContentFactoryManager::RetrieveTypeNameFromResourceURL( const rtl::OUString& aResourceURL, rtl::OUString& aType, rtl::OUString& aName )
+{
+ const sal_Int32 RESOURCEURL_PREFIX_SIZE = 17;
+ const char RESOURCEURL_PREFIX[] = "private:resource/";
+
+ if (( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) &&
+ ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
+ {
+ rtl::OUString aTmpStr( aResourceURL.copy( RESOURCEURL_PREFIX_SIZE ));
+ sal_Int32 nToken = 0;
+ sal_Int32 nPart = 0;
+ do
+ {
+ ::rtl::OUString sToken = aTmpStr.getToken( 0, '/', nToken);
+ if ( sToken.getLength() )
+ {
+ if ( nPart == 0 )
+ aType = sToken;
+ else if ( nPart == 1 )
+ aName = sToken;
+ else
+ break;
+ nPart++;
+ }
+ }
+ while( nToken >=0 );
+ }
+}
+
+// XSingleComponentFactory
+uno::Reference< uno::XInterface > SAL_CALL WindowContentFactoryManager::createInstanceWithContext(
+ const uno::Reference< uno::XComponentContext >& /*xContext*/ )
+throw (uno::Exception, uno::RuntimeException)
+{
+ uno::Reference< uno::XInterface > xWindow;
+ return xWindow;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL WindowContentFactoryManager::createInstanceWithArgumentsAndContext(
+ const uno::Sequence< uno::Any >& Arguments, const uno::Reference< uno::XComponentContext >& Context )
+throw (uno::Exception, uno::RuntimeException)
+{
+ uno::Reference< uno::XInterface > xWindow;
+ uno::Reference< frame::XFrame > xFrame;
+ ::rtl::OUString aResourceURL;
+
+ for (sal_Int32 i=0; i < Arguments.getLength(); i++ )
+ {
+ beans::PropertyValue aPropValue;
+ if ( Arguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Frame" ) ))
+ aPropValue.Value >>= xFrame;
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ResourceURL" ) ))
+ aPropValue.Value >>= aResourceURL;
+ }
+ }
+
+ uno::Reference< frame::XModuleManager > xModuleManager;
+ // SAFE
+ {
+ ResetableGuard aLock( m_aLock );
+ xModuleManager = m_xModuleManager;
+ }
+ // UNSAFE
+
+ // Determine the module identifier
+ ::rtl::OUString aType;
+ ::rtl::OUString aName;
+ ::rtl::OUString aModuleId;
+ try
+ {
+ if ( xFrame.is() && xModuleManager.is() )
+ aModuleId = xModuleManager->identify( uno::Reference< uno::XInterface >( xFrame, uno::UNO_QUERY ) );
+ }
+ catch ( frame::UnknownModuleException& )
+ {
+ }
+
+ RetrieveTypeNameFromResourceURL( aResourceURL, aType, aName );
+ if ( aType.getLength() > 0 &&
+ aName.getLength() > 0 &&
+ aModuleId.getLength() > 0 )
+ {
+ ::rtl::OUString aImplementationName;
+ uno::Reference< uno::XInterface > xHolder( static_cast<cppu::OWeakObject*>(this), uno::UNO_QUERY );
+
+ // Detetmine the implementation name of the window content factory dependent on the
+ // module identifier, user interface element type and name
+ // SAFE
+ ResetableGuard aLock( m_aLock );
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = sal_True;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ aImplementationName = m_pConfigAccess->getFactorySpecifierFromTypeNameModule( aType, aName, aModuleId );
+ if ( aImplementationName.getLength() > 0 )
+ {
+ aLock.unlock();
+ // UNSAFE
+
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager( Context->getServiceManager(), uno::UNO_QUERY );
+ if ( xServiceManager.is() )
+ {
+ uno::Reference< lang::XSingleComponentFactory > xFactory(
+ xServiceManager->createInstance( aImplementationName ), uno::UNO_QUERY );
+ if ( xFactory.is() )
+ {
+ // Be careful: We call external code. Therefore here we have to catch all exceptions
+ try
+ {
+ xWindow = xFactory->createInstanceWithArgumentsAndContext( Arguments, Context );
+ }
+ catch ( uno::RuntimeException& )
+ {
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+
+ // UNSAFE
+ if ( !xWindow.is())
+ {
+ // Fallback: Use internal factory code to create a toolkit dialog as a content window
+ xWindow = createInstanceWithContext(Context);
+ }
+
+ return xWindow;
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/unotypes/fwk.xml b/framework/source/unotypes/fwk.xml
new file mode 100755
index 000000000000..069979e7c968
--- /dev/null
+++ b/framework/source/unotypes/fwk.xml
@@ -0,0 +1,457 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name> fwk </module-name>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.Frame </name>
+ <description>
+ A frame support influencing of his subtree, find of subframes, activate- and deactivate-mechanism as well as
+ set/get of a frame window, component or controller.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.Frame </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.Desktop </name>
+ <description>
+ A desktop environment contains tasks with one or more frames in which components can be loaded.
+ The desktop himself is the root of the frame hierarchy.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.Desktop </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.URLTransformer </name>
+ <description>
+ Helps to split up a string containing a URL into its
+ structural parts and assembles the parts into a single string.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.util.URLTransformer </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.JobExecutor </name>
+ <description>
+ It implements a generic job execution service, which can start
+ registered uno services on triggered events, control her lifetime
+ and handle there own configuration.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.task.JobExecutor </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.DispatchRecorderSupplier </name>
+ <description>
+ This supplier is available on the servcice Frame as property "DispatchRecorderSupplier".
+ It provides access on the currently set DispatchRecorder of this Frame
+ and some additional functionality to make macro recording easy.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.DispatchRecorderSupplier </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.DispatchRecorder </name>
+ <description>
+ Implements a recorder object which can record XDIspatch::dispatch() calls
+ and generate basic script code from that.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.DispatchRecorder </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.MailToDispatcher </name>
+ <description>
+ It's a dispatch object which can handle "mailto:" URLs.
+ This service is registered in configuration for this protocol
+ and wil be used automaticly by the generic dispatch implementation
+ of a Frame. It should start an external mail application and forward
+ this request to it.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.ProtocolHandler </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.ServiceHandler </name>
+ <description>
+ It's a special dispatch object which is registered for "service:*" URL pattern
+ and will be automaticly used by the framework dispatch mechanism if such URL occurred.
+ His job is to create any registered uno components which must be coded inside
+ dispatched URL (may with some optional given parameters). After that such created
+ service must be hold his self alive. Such mechanism can be usefull for UI components
+ (e.g. Dialogs, Wizards) only.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.ProtocolHandler </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.JobHandler </name>
+ <description>
+ It's a special dispatch object which is registered for "vnd.sun.star.job:*" URL pattern
+ and will be automaticly used by the framework dispatch mechanism if such URL occurred.
+ It binds the dispatch mechanism to the generic job execution of this framework module.
+ That can be used for e.g. addon purposes.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.ProtocolHandler </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.LayoutManager </name>
+ <description>
+ Controls the layout of user interface elements which are part of a frame.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.LayoutManager </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.PopupMenuControllerFactory </name>
+ <description>
+ A factory manager that creates instances of registered popup menu controller.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.PopupMenuControllerFactory </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.FontMenuController </name>
+ <description>
+ A popup menu controller which controls the font popup menu.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.PopupMenuController </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.FontSizeMenuController </name>
+ <description>
+ A popup menu controller which controls the font size popup menu.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.PopupMenuController </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.ObjectMenuController </name>
+ <description>
+ A popup menu controller which controls the object popup menu.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.PopupMenuController </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.HeaderMenuController </name>
+ <description>
+ A popup menu controller which controls the header popup menu.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.PopupMenuController </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.FooterMenuController </name>
+ <description>
+ A popup menu controller which controls the footer popup menu.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.PopupMenuController </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.ControlMenuController </name>
+ <description>
+ A popup menu controller which controls the control popup menu.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.PopupMenuController </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.ToolBarsMenuController </name>
+ <description>
+ A popup menu controller which makes certain toolbars available to
+ the user. It supports to show/hide toolbars.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.PopupMenuController </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Duncan Foster </author>
+ <name> com.sun.star.comp.framework.MacrosMenuController </name>
+ <description>
+ A popup menu controller which controls the scripts/macros popup menu.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.PopupMenuController </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.UICommandDescription </name>
+ <description>
+ A manager that holds all user interface commands and their description, the menu label
+ of every registered OpenOffice.org module.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.ui.UICommandDescription </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.UIElementFactoryManager </name>
+ <description>
+ A user interface factory manager that controls all registered user interface element factories.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.ui.UIElementFactoryManager </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.ModuleManager </name>
+ <description>
+ Manages the access to OpenOffice.org module specific informations.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.ModuleManager </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.UIConfigurationManager </name>
+ <description>
+ Manages the user interface element settings of a single storage element, like documents or
+ a single user interface configuration file.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.ui.UIConfigurationManager </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.ModuleUIConfigurationManagerSupplier </name>
+ <description>
+ Central manager that provides access to the OpenOffice.org module user interface
+ configuration managers.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.ui.ModuleUIConfigurationManagerSupplier </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.ModuleUIConfigurationManager </name>
+ <description>
+ A single OpenOffice.org module user interface configuration manager. It is responsible to provide
+ access to the user interface element settings of an OpenOffice.org module. Must be obtained from
+ the ModuleUIConfigurationManagerSupplier otherwise it is not correctly initialized.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.ui.ModuleUIConfigurationManager </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.MenuBarFactory </name>
+ <description>
+ Creates menu bars that can be used the user interface configuration API.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.ui.UIElementFactory </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.UIConfigurationManager </name>
+ <description>
+ Manages the user interface element settings of a single storage element, like documents or
+ a single user interface configuration file.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.ui.UIConfigurationManager </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.BackingComp </name>
+ <description>
+ The start module component.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.StartModule </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.UICategoryDescription </name>
+ <description>
+ Description about categories of user interface commands.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.ui.UICategoryDescription </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.ToolBarFactory </name>
+ <description>
+ A factory to create toolbar instances.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.ui.ToolBarFactory </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.ToolBarControllerFactory </name>
+ <description>
+ A factory to create registered toolbar bar controller.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.ToolBarControllerFactory </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.StatusbarFactory </name>
+ <description>
+ A factory to create registered status bar controller.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.ui.StatusbarFactory </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.StatusbarControllerFactory </name>
+ <description>
+ A factory to create registered status bar controller.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.StatusbarControllerFactory </supported-service>
+ </component-description>
+
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> tools </project-build-dependency>
+ <project-build-dependency> svtools </project-build-dependency>
+ <project-build-dependency> toolkit </project-build-dependency>
+ <project-build-dependency> sv </project-build-dependency>
+ <project-build-dependency> comphelper </project-build-dependency>
+ <project-build-dependency> unotools </project-build-dependency>
+ <project-build-dependency> ucbhelper </project-build-dependency>
+ <project-build-dependency> svl </project-build-dependency>
+ <project-build-dependency> sot </project-build-dependency>
+
+ <runtime-module-dependency> cppu2 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper </runtime-module-dependency>
+ <runtime-module-dependency> sal2 </runtime-module-dependency>
+ <runtime-module-dependency> tl </runtime-module-dependency>
+ <runtime-module-dependency> svt </runtime-module-dependency>
+ <runtime-module-dependency> svl </runtime-module-dependency>
+ <runtime-module-dependency> tk </runtime-module-dependency>
+ <runtime-module-dependency> sv </runtime-module-dependency>
+ <runtime-module-dependency> comphelp2 </runtime-module-dependency>
+ <runtime-module-dependency> utl </runtime-module-dependency>
+ <runtime-module-dependency> ucb </runtime-module-dependency>
+ <runtime-module-dependency> sot </runtime-module-dependency>
+
+</module-description>
diff --git a/framework/source/unotypes/fwl.xml b/framework/source/unotypes/fwl.xml
new file mode 100755
index 000000000000..a9693de6854d
--- /dev/null
+++ b/framework/source/unotypes/fwl.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name> fwl </module-name>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.TypeDetection </name>
+ <description>
+ Supports a type detection of a specified ressource (document).
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.document.TypeDetection </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.FilterFactory </name>
+ <description>
+ Supports creation and getting informations about registered filter services.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.document.FilterFactory </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.FrameLoaderFactory </name>
+ <description>
+ Supports creation and getting informations about registered frame loader services.
+ These services could load a component into a frame.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.FrameLoaderFactory </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.ContentHandlerFactory </name>
+ <description>
+ Supports creation and getting informations about registered content handler services.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.frame.ContentHandlerFactory </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.SubstituteVariables </name>
+ <description>
+ Supports the substitution and resubstitution of path and language variables.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.util.PathSubstitution </supported-service>
+ </component-description>
+
+ <component-description>
+ <author> Carsten Driesner </author>
+ <name> com.sun.star.comp.framework.PathSettings </name>
+ <description>
+ Supports the access to the Office internal path settings.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.util.PathSettings </supported-service>
+ </component-description>
+
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> comphelper </project-build-dependency>
+ <project-build-dependency> tools </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> svl </project-build-dependency>
+
+ <runtime-module-dependency> cppu2 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper </runtime-module-dependency>
+ <runtime-module-dependency> comphelp2 </runtime-module-dependency>
+ <runtime-module-dependency> tl </runtime-module-dependency>
+ <runtime-module-dependency> sal2 </runtime-module-dependency>
+ <runtime-module-dependency> svl </runtime-module-dependency>
+
+</module-description>
diff --git a/framework/source/unotypes/lgd.xml b/framework/source/unotypes/lgd.xml
new file mode 100755
index 000000000000..3a7e69718cba
--- /dev/null
+++ b/framework/source/unotypes/lgd.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <module-name> lgd </module-name>
+
+ <component-description>
+ <author> Andreas Schluens </author>
+ <name> com.sun.star.comp.framework.LoginDialog </name>
+ <description>
+ Implement a dialog for login to a sun one webtop server.
+ </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.comp.framework.LoginDialog </supported-service>
+ </component-description>
+
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> sv </project-build-dependency>
+ <project-build-dependency> tools </project-build-dependency>
+
+ <runtime-module-dependency> cppu2 </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper </runtime-module-dependency>
+ <runtime-module-dependency> sal2 </runtime-module-dependency>
+ <runtime-module-dependency> tl </runtime-module-dependency>
+ <runtime-module-dependency> sv </runtime-module-dependency>
+
+</module-description>
diff --git a/framework/source/xml/acceleratorconfigurationreader.cxx b/framework/source/xml/acceleratorconfigurationreader.cxx
new file mode 100644
index 000000000000..acdb7fa66320
--- /dev/null
+++ b/framework/source/xml/acceleratorconfigurationreader.cxx
@@ -0,0 +1,339 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <xml/acceleratorconfigurationreader.hxx>
+
+//_______________________________________________
+// own includes
+
+#include <acceleratorconst.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/awt/Key.hpp>
+#include <com/sun/star/container/ElementExistException.hpp>
+
+//_______________________________________________
+// other includes
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//-----------------------------------------------
+/* Throws a SaxException in case a wrong formated XML
+ structure was detected.
+
+ This macro combined the given comment with a generic
+ way to find out the XML line (where the error occurred)
+ to format a suitable message.
+
+ @param COMMENT
+ an ascii string, which describe the problem.
+ */
+#define THROW_PARSEEXCEPTION(COMMENT) \
+ { \
+ ::rtl::OUStringBuffer sMessage(256); \
+ sMessage.append (implts_getErrorLineString()); \
+ sMessage.appendAscii(COMMENT ); \
+ \
+ throw css::xml::sax::SAXException( \
+ sMessage.makeStringAndClear(), \
+ static_cast< css::xml::sax::XDocumentHandler* >(this), \
+ css::uno::Any()); \
+ }
+
+//-----------------------------------------------
+// XInterface
+DEFINE_XINTERFACE_1(AcceleratorConfigurationReader ,
+ OWeakObject ,
+ DIRECT_INTERFACE(css::xml::sax::XDocumentHandler))
+
+//-----------------------------------------------
+AcceleratorConfigurationReader::AcceleratorConfigurationReader(AcceleratorCache& rContainer)
+ : ThreadHelpBase (&Application::GetSolarMutex())
+ , OWeakObject ( )
+ , m_rContainer (rContainer )
+ , m_bInsideAcceleratorList(sal_False )
+ , m_bInsideAcceleratorItem(sal_False )
+{
+}
+
+//-----------------------------------------------
+AcceleratorConfigurationReader::~AcceleratorConfigurationReader()
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL AcceleratorConfigurationReader::startDocument()
+ throw(css::xml::sax::SAXException,
+ css::uno::RuntimeException )
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL AcceleratorConfigurationReader::endDocument()
+ throw(css::xml::sax::SAXException,
+ css::uno::RuntimeException )
+{
+ // The xml file seems to be corrupted.
+ // Because we found no end-tags ... at least for
+ // one list or item.
+ if (
+ (m_bInsideAcceleratorList) ||
+ (m_bInsideAcceleratorItem)
+ )
+ {
+ THROW_PARSEEXCEPTION("No matching start or end element 'acceleratorlist' found!")
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL AcceleratorConfigurationReader::startElement(const ::rtl::OUString& sElement ,
+ const css::uno::Reference< css::xml::sax::XAttributeList >& xAttributeList)
+ throw(css::xml::sax::SAXException,
+ css::uno::RuntimeException )
+{
+ EXMLElement eElement = AcceleratorConfigurationReader::implst_classifyElement(sElement);
+
+ // Note: We handle "accel:item" before "accel:acceleratorlist" to perform this operation.
+ // Because an item occures very often ... a list should occure one times only!
+ if (eElement == E_ELEMENT_ITEM)
+ {
+ if (!m_bInsideAcceleratorList)
+ THROW_PARSEEXCEPTION("An element \"accel:item\" must be embeded into 'accel:acceleratorlist'.")
+ if (m_bInsideAcceleratorItem)
+ THROW_PARSEEXCEPTION("An element \"accel:item\" is not a container.")
+ m_bInsideAcceleratorItem = sal_True;
+
+ ::rtl::OUString sCommand;
+ css::awt::KeyEvent aEvent ;
+
+ sal_Int16 c = xAttributeList->getLength();
+ sal_Int16 i = 0;
+ for (i=0; i<c; ++i)
+ {
+ ::rtl::OUString sAttribute = xAttributeList->getNameByIndex(i);
+ ::rtl::OUString sValue = xAttributeList->getValueByIndex(i);
+ EXMLAttribute eAttribute = AcceleratorConfigurationReader::implst_classifyAttribute(sAttribute);
+ switch(eAttribute)
+ {
+ case E_ATTRIBUTE_URL :
+ sCommand = sValue.intern();
+ break;
+
+ case E_ATTRIBUTE_KEYCODE :
+ aEvent.KeyCode = m_rKeyMapping->mapIdentifierToCode(sValue);
+ break;
+
+ case E_ATTRIBUTE_MOD_SHIFT :
+ aEvent.Modifiers |= css::awt::KeyModifier::SHIFT;
+ break;
+
+ case E_ATTRIBUTE_MOD_MOD1 :
+ aEvent.Modifiers |= css::awt::KeyModifier::MOD1;
+ break;
+
+ case E_ATTRIBUTE_MOD_MOD2 :
+ aEvent.Modifiers |= css::awt::KeyModifier::MOD2;
+ break;
+
+ case E_ATTRIBUTE_MOD_MOD3 :
+ aEvent.Modifiers |= css::awt::KeyModifier::MOD3;
+ }
+ }
+
+ // validate command and key event.
+ if (
+ (!sCommand.getLength()) ||
+ (aEvent.KeyCode == 0 )
+ )
+ {
+ THROW_PARSEEXCEPTION("XML element does not describe a valid accelerator nor a valid command.")
+ }
+
+ // register key event + command inside cache ...
+ // Check for already existing items there.
+ if (!m_rContainer.hasKey(aEvent))
+ m_rContainer.setKeyCommandPair(aEvent, sCommand);
+ #ifdef ENABLE_WARNINGS
+ else
+ {
+ // Attention: Its not realy a reason to throw an exception and kill the office, if the configuration contains
+ // multiple registrations for the same key :-) Show a warning ... and ignore the second item.
+ // THROW_PARSEEXCEPTION("Command is registered for the same key more then once.")
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("Double registration detected.\nCommand = \"");
+ sMsg.append (sCommand );
+ sMsg.appendAscii("\"\nKeyCode = " );
+ sMsg.append ((sal_Int32)aEvent.KeyCode );
+ sMsg.appendAscii("\nModifiers = " );
+ sMsg.append ((sal_Int32)aEvent.Modifiers );
+ sMsg.appendAscii("\nIgnore this item!" );
+ LOG_WARNING("AcceleratorConfigurationReader::startElement()", U2B(sMsg.makeStringAndClear()))
+ }
+ #endif // ENABLE_WARNINGS
+ }
+
+ if (eElement == E_ELEMENT_ACCELERATORLIST)
+ {
+ if (m_bInsideAcceleratorList)
+ THROW_PARSEEXCEPTION("An element \"accel:acceleratorlist\" cannot be used recursive.")
+ m_bInsideAcceleratorList = sal_True;
+ return;
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL AcceleratorConfigurationReader::endElement(const ::rtl::OUString& sElement)
+ throw(css::xml::sax::SAXException,
+ css::uno::RuntimeException )
+{
+ EXMLElement eElement = AcceleratorConfigurationReader::implst_classifyElement(sElement);
+
+ // Note: We handle "accel:item" before "accel:acceleratorlist" to perform this operation.
+ // Because an item occures very often ... a list should occure one times only!
+ if (eElement == E_ELEMENT_ITEM)
+ {
+ if (!m_bInsideAcceleratorItem)
+ THROW_PARSEEXCEPTION("Found end element 'accel:item', but no start element.")
+ m_bInsideAcceleratorItem = sal_False;
+ }
+
+ if (eElement == E_ELEMENT_ACCELERATORLIST)
+ {
+ if (!m_bInsideAcceleratorList)
+ THROW_PARSEEXCEPTION("Found end element 'accel:acceleratorlist', but no start element.")
+ m_bInsideAcceleratorList = sal_False;
+ }
+}
+
+//-----------------------------------------------
+void SAL_CALL AcceleratorConfigurationReader::characters(const ::rtl::OUString&)
+ throw(css::xml::sax::SAXException,
+ css::uno::RuntimeException )
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL AcceleratorConfigurationReader::ignorableWhitespace(const ::rtl::OUString&)
+ throw(css::xml::sax::SAXException,
+ css::uno::RuntimeException )
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL AcceleratorConfigurationReader::processingInstruction(const ::rtl::OUString& /*sTarget*/,
+ const ::rtl::OUString& /*sData*/ )
+ throw(css::xml::sax::SAXException,
+ css::uno::RuntimeException )
+{
+}
+
+//-----------------------------------------------
+void SAL_CALL AcceleratorConfigurationReader::setDocumentLocator(const css::uno::Reference< css::xml::sax::XLocator >& xLocator)
+ throw(css::xml::sax::SAXException,
+ css::uno::RuntimeException )
+{
+ m_xLocator = xLocator;
+}
+
+//-----------------------------------------------
+AcceleratorConfigurationReader::EXMLElement AcceleratorConfigurationReader::implst_classifyElement(const ::rtl::OUString& sElement)
+{
+ AcceleratorConfigurationReader::EXMLElement eElement;
+
+ if (sElement.equals(NS_ELEMENT_ACCELERATORLIST))
+ eElement = E_ELEMENT_ACCELERATORLIST;
+ else
+ if (sElement.equals(NS_ELEMENT_ITEM))
+ eElement = E_ELEMENT_ITEM;
+ else
+ throw css::uno::RuntimeException(
+ DECLARE_ASCII("Unknown XML element detected!"),
+ css::uno::Reference< css::xml::sax::XDocumentHandler >());
+
+ return eElement;
+}
+
+//-----------------------------------------------
+AcceleratorConfigurationReader::EXMLAttribute AcceleratorConfigurationReader::implst_classifyAttribute(const ::rtl::OUString& sAttribute)
+{
+ AcceleratorConfigurationReader::EXMLAttribute eAttribute;
+
+ if (sAttribute.equals(NS_ATTRIBUTE_KEYCODE))
+ eAttribute = E_ATTRIBUTE_KEYCODE;
+ else
+ if (sAttribute.equals(NS_ATTRIBUTE_MOD_SHIFT))
+ eAttribute = E_ATTRIBUTE_MOD_SHIFT;
+ else
+ if (sAttribute.equals(NS_ATTRIBUTE_MOD_MOD1))
+ eAttribute = E_ATTRIBUTE_MOD_MOD1;
+ else
+ if (sAttribute.equals(NS_ATTRIBUTE_MOD_MOD2))
+ eAttribute = E_ATTRIBUTE_MOD_MOD2;
+ else
+ if (sAttribute.equals(NS_ATTRIBUTE_MOD_MOD3))
+ eAttribute = E_ATTRIBUTE_MOD_MOD3;
+ else
+ if (sAttribute.equals(NS_ATTRIBUTE_URL))
+ eAttribute = E_ATTRIBUTE_URL;
+ else
+ throw css::uno::RuntimeException(
+ DECLARE_ASCII("Unknown XML attribute detected!"),
+ css::uno::Reference< css::xml::sax::XDocumentHandler >());
+
+ return eAttribute;
+}
+
+//-----------------------------------------------
+::rtl::OUString AcceleratorConfigurationReader::implts_getErrorLineString()
+{
+ if (!m_xLocator.is())
+ return DECLARE_ASCII("Error during parsing XML. (No further info available ...)");
+
+ ::rtl::OUStringBuffer sMsg(256);
+ sMsg.appendAscii("Error during parsing XML in\nline = ");
+ sMsg.append (m_xLocator->getLineNumber() );
+ sMsg.appendAscii("\ncolumn = " );
+ sMsg.append (m_xLocator->getColumnNumber() );
+ sMsg.appendAscii("." );
+ return sMsg.makeStringAndClear();
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/xml/acceleratorconfigurationwriter.cxx b/framework/source/xml/acceleratorconfigurationwriter.cxx
new file mode 100644
index 000000000000..be48788fa3db
--- /dev/null
+++ b/framework/source/xml/acceleratorconfigurationwriter.cxx
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <xml/acceleratorconfigurationwriter.hxx>
+
+//_______________________________________________
+// own includes
+#include <acceleratorconst.h>
+#include <threadhelp/readguard.hxx>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+
+//_______________________________________________
+// other includes
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <comphelper/attributelist.hxx>
+
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+
+//-----------------------------------------------
+AcceleratorConfigurationWriter::AcceleratorConfigurationWriter(const AcceleratorCache& rContainer,
+ const css::uno::Reference< css::xml::sax::XDocumentHandler >& xConfig )
+ : ThreadHelpBase(&Application::GetSolarMutex())
+ , m_xConfig (xConfig )
+ , m_rContainer (rContainer )
+{
+}
+
+//-----------------------------------------------
+AcceleratorConfigurationWriter::~AcceleratorConfigurationWriter()
+{
+}
+
+//-----------------------------------------------
+void AcceleratorConfigurationWriter::flush()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+
+ css::uno::Reference< css::xml::sax::XDocumentHandler > xCFG = m_xConfig;
+ css::uno::Reference< css::xml::sax::XExtendedDocumentHandler > xExtendedCFG(m_xConfig, css::uno::UNO_QUERY_THROW);
+
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // prepare attribute list
+ ::comphelper::AttributeList* pAttribs = new ::comphelper::AttributeList;
+ css::uno::Reference< css::xml::sax::XAttributeList > xAttribs(static_cast< css::xml::sax::XAttributeList* >(pAttribs), css::uno::UNO_QUERY);
+
+ pAttribs->AddAttribute(AL_XMLNS_ACCEL, ATTRIBUTE_TYPE_CDATA, NS_XMLNS_ACCEL);
+ pAttribs->AddAttribute(AL_XMLNS_XLINK, ATTRIBUTE_TYPE_CDATA, NS_XMLNS_XLINK);
+
+ // generate xml
+ xCFG->startDocument();
+
+ xExtendedCFG->unknown(DOCTYPE_ACCELERATORS);
+ xCFG->ignorableWhitespace(::rtl::OUString());
+
+ xCFG->startElement(AL_ELEMENT_ACCELERATORLIST, xAttribs);
+ xCFG->ignorableWhitespace(::rtl::OUString());
+
+ // TODO think about threadsafe using of cache
+ AcceleratorCache::TKeyList lKeys = m_rContainer.getAllKeys();
+ AcceleratorCache::TKeyList::const_iterator pKey ;
+ for ( pKey = lKeys.begin();
+ pKey != lKeys.end() ;
+ ++pKey )
+ {
+ const css::awt::KeyEvent& rKey = *pKey;
+ const ::rtl::OUString& rCommand = m_rContainer.getCommandByKey(rKey);
+ impl_ts_writeKeyCommandPair(rKey, rCommand, xCFG);
+ }
+
+ /* TODO write key-command list
+ std::vector< SfxAcceleratorConfigItem>::const_iterator p;
+ for ( p = m_aWriteAcceleratorList.begin(); p != m_aWriteAcceleratorList.end(); p++ )
+ WriteAcceleratorItem( *p );
+ */
+
+ xCFG->ignorableWhitespace(::rtl::OUString());
+ xCFG->endElement(AL_ELEMENT_ACCELERATORLIST);
+ xCFG->ignorableWhitespace(::rtl::OUString());
+ xCFG->endDocument();
+}
+
+//-----------------------------------------------
+void AcceleratorConfigurationWriter::impl_ts_writeKeyCommandPair(const css::awt::KeyEvent& aKey ,
+ const ::rtl::OUString& sCommand,
+ const css::uno::Reference< css::xml::sax::XDocumentHandler >& xConfig )
+{
+ ::comphelper::AttributeList* pAttribs = new ::comphelper::AttributeList;
+ css::uno::Reference< css::xml::sax::XAttributeList > xAttribs (static_cast< css::xml::sax::XAttributeList* >(pAttribs) , css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString sKey = m_rKeyMapping->mapCodeToIdentifier(aKey.KeyCode);
+ // TODO check if key is empty!
+
+ pAttribs->AddAttribute(AL_ATTRIBUTE_KEYCODE, ATTRIBUTE_TYPE_CDATA, sKey );
+ pAttribs->AddAttribute(AL_ATTRIBUTE_URL , ATTRIBUTE_TYPE_CDATA, sCommand);
+
+ if ((aKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT)
+ pAttribs->AddAttribute(AL_ATTRIBUTE_MOD_SHIFT, ATTRIBUTE_TYPE_CDATA, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true")));
+
+ if ((aKey.Modifiers & css::awt::KeyModifier::MOD1) == css::awt::KeyModifier::MOD1)
+ pAttribs->AddAttribute(AL_ATTRIBUTE_MOD_MOD1, ATTRIBUTE_TYPE_CDATA, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true")));
+
+ if ((aKey.Modifiers & css::awt::KeyModifier::MOD2) == css::awt::KeyModifier::MOD2)
+ pAttribs->AddAttribute(AL_ATTRIBUTE_MOD_MOD2, ATTRIBUTE_TYPE_CDATA, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true")));
+
+ if ((aKey.Modifiers & css::awt::KeyModifier::MOD3) == css::awt::KeyModifier::MOD3)
+ pAttribs->AddAttribute(AL_ATTRIBUTE_MOD_MOD3, ATTRIBUTE_TYPE_CDATA, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true")));
+
+ xConfig->ignorableWhitespace(::rtl::OUString());
+ xConfig->startElement(AL_ELEMENT_ITEM, xAttribs);
+ xConfig->ignorableWhitespace(::rtl::OUString());
+ xConfig->endElement(AL_ELEMENT_ITEM);
+ xConfig->ignorableWhitespace(::rtl::OUString());
+}
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */