1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "precompiled_sd.hxx" 29 30 #include "ChangeRequestQueueProcessor.hxx" 31 #include "ConfigurationTracer.hxx" 32 33 #include "framework/ConfigurationController.hxx" 34 #include "ConfigurationUpdater.hxx" 35 36 #include <vcl/svapp.hxx> 37 #include <com/sun/star/container/XNamed.hpp> 38 #include <com/sun/star/drawing/framework/XConfiguration.hpp> 39 #include <com/sun/star/drawing/framework/ConfigurationChangeEvent.hpp> 40 41 using namespace ::com::sun::star; 42 using namespace ::com::sun::star::uno; 43 using namespace ::com::sun::star::drawing::framework; 44 45 #undef VERBOSE 46 //#define VERBOSE 1 47 48 namespace { 49 50 #ifdef VERBOSE 51 52 void TraceRequest (const Reference<XConfigurationChangeRequest>& rxRequest) 53 { 54 Reference<container::XNamed> xNamed (rxRequest, UNO_QUERY); 55 if (xNamed.is()) 56 OSL_TRACE(" %s\n", 57 ::rtl::OUStringToOString(xNamed->getName(), RTL_TEXTENCODING_UTF8).getStr()); 58 } 59 60 #endif 61 62 } // end of anonymous namespace 63 64 65 namespace sd { namespace framework { 66 67 ChangeRequestQueueProcessor::ChangeRequestQueueProcessor ( 68 const ::rtl::Reference<ConfigurationController>& rpConfigurationController, 69 const ::boost::shared_ptr<ConfigurationUpdater>& rpConfigurationUpdater) 70 : maMutex(), 71 maQueue(), 72 mnUserEventId(0), 73 mxConfiguration(), 74 mpConfigurationController(rpConfigurationController), 75 mpConfigurationUpdater(rpConfigurationUpdater) 76 { 77 } 78 79 80 81 82 ChangeRequestQueueProcessor::~ChangeRequestQueueProcessor (void) 83 { 84 if (mnUserEventId != 0) 85 Application::RemoveUserEvent(mnUserEventId); 86 } 87 88 89 90 91 void ChangeRequestQueueProcessor::SetConfiguration ( 92 const Reference<XConfiguration>& rxConfiguration) 93 { 94 ::osl::MutexGuard aGuard (maMutex); 95 96 mxConfiguration = rxConfiguration; 97 StartProcessing(); 98 } 99 100 101 102 103 void ChangeRequestQueueProcessor::AddRequest ( 104 const Reference<XConfigurationChangeRequest>& rxRequest) 105 { 106 ::osl::MutexGuard aGuard (maMutex); 107 108 #ifdef VERBOSE 109 if (maQueue.empty()) 110 { 111 OSL_TRACE("Adding requests to empty queue\n"); 112 ConfigurationTracer::TraceConfiguration( 113 mxConfiguration, "current configuration of queue processor"); 114 } 115 OSL_TRACE("Adding request\n"); 116 TraceRequest(rxRequest); 117 #endif 118 119 maQueue.push_back(rxRequest); 120 StartProcessing(); 121 } 122 123 124 125 126 void ChangeRequestQueueProcessor::StartProcessing (void) 127 { 128 ::osl::MutexGuard aGuard (maMutex); 129 130 if (mnUserEventId == 0 131 && mxConfiguration.is() 132 && ! maQueue.empty()) 133 { 134 #ifdef VERBOSE 135 OSL_TRACE("ChangeRequestQueueProcessor scheduling processing\n"); 136 #endif 137 mnUserEventId = Application::PostUserEvent( 138 LINK(this,ChangeRequestQueueProcessor,ProcessEvent)); 139 } 140 } 141 142 143 144 145 IMPL_LINK(ChangeRequestQueueProcessor, ProcessEvent, void*, pUnused) 146 { 147 (void)pUnused; 148 149 ::osl::MutexGuard aGuard (maMutex); 150 151 mnUserEventId = 0; 152 153 ProcessOneEvent(); 154 155 if ( ! maQueue.empty()) 156 { 157 // Schedule the processing of the next event. 158 StartProcessing(); 159 } 160 161 return 0; 162 } 163 164 165 166 167 void ChangeRequestQueueProcessor::ProcessOneEvent (void) 168 { 169 ::osl::MutexGuard aGuard (maMutex); 170 171 #ifdef VERBOSE 172 OSL_TRACE("ProcessOneEvent\n"); 173 #endif 174 175 if (mxConfiguration.is() 176 && ! maQueue.empty()) 177 { 178 // Get and remove the first entry from the queue. 179 Reference<XConfigurationChangeRequest> xRequest (maQueue.front()); 180 maQueue.pop_front(); 181 182 // Execute the change request. 183 if (xRequest.is()) 184 { 185 #ifdef VERBOSE 186 TraceRequest(xRequest); 187 #endif 188 xRequest->execute(mxConfiguration); 189 } 190 191 if (maQueue.empty()) 192 { 193 #ifdef VERBOSE 194 OSL_TRACE("All requests are processed\n"); 195 #endif 196 // The queue is empty so tell the ConfigurationManager to update 197 // its state. 198 if (mpConfigurationUpdater.get() != NULL) 199 { 200 #ifdef VERBOSE 201 ConfigurationTracer::TraceConfiguration ( 202 mxConfiguration, "updating to configuration"); 203 #endif 204 mpConfigurationUpdater->RequestUpdate(mxConfiguration); 205 } 206 } 207 } 208 } 209 210 211 212 213 bool ChangeRequestQueueProcessor::IsEmpty (void) const 214 { 215 return maQueue.empty(); 216 } 217 218 219 220 221 void ChangeRequestQueueProcessor::ProcessUntilEmpty (void) 222 { 223 while ( ! IsEmpty()) 224 ProcessOneEvent(); 225 } 226 227 228 229 230 void ChangeRequestQueueProcessor::Clear (void) 231 { 232 ::osl::MutexGuard aGuard (maMutex); 233 maQueue.clear(); 234 } 235 236 237 } } // end of namespace sd::framework::configuration 238