| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | /****************************************************************************
 | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2016-01-15 14:59:14 +01:00
										 |  |  | ** Copyright (C) 2016 The Qt Company Ltd. | 
					
						
							|  |  |  | ** Contact: https://www.qt.io/licensing/
 | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** This file is part of Qt Creator. | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Commercial License Usage | 
					
						
							|  |  |  | ** Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							| 
									
										
										
										
											2016-01-15 14:59:14 +01:00
										 |  |  | ** a written agreement between you and The Qt Company. For licensing terms | 
					
						
							|  |  |  | ** and conditions see https://www.qt.io/terms-conditions. For further
 | 
					
						
							|  |  |  | ** information use the contact form at https://www.qt.io/contact-us.
 | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2015-09-18 11:34:48 +02:00
										 |  |  | ** GNU General Public License Usage | 
					
						
							|  |  |  | ** Alternatively, this file may be used under the terms of the GNU | 
					
						
							| 
									
										
										
										
											2016-01-15 14:59:14 +01:00
										 |  |  | ** General Public License version 3 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
					
						
							|  |  |  | ** included in the packaging of this file. Please review the following | 
					
						
							|  |  |  | ** information to ensure the GNU General Public License requirements will | 
					
						
							|  |  |  | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
 | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2011-02-22 12:08:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | #include "valueschangedcommand.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-31 16:45:21 +02:00
										 |  |  | #include "sharedmemory.h"
 | 
					
						
							| 
									
										
										
										
											2020-10-08 12:55:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | #include <QCache>
 | 
					
						
							| 
									
										
										
										
											2013-07-16 17:00:07 +02:00
										 |  |  | #include <QDebug>
 | 
					
						
							| 
									
										
										
										
											2020-10-08 12:55:35 +02:00
										 |  |  | #include <QIODevice>
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-20 14:25:01 +02:00
										 |  |  | #include <cstring>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-03 23:29:58 +03:00
										 |  |  | #include <algorithm>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | namespace QmlDesigner { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-05 14:00:21 +02:00
										 |  |  | // using cache as a container which deletes sharedmemory pointers at process exit
 | 
					
						
							| 
									
										
										
										
											2018-07-24 23:56:45 +02:00
										 |  |  | using GlobalSharedMemoryContainer = QCache<qint32, SharedMemory>; | 
					
						
							| 
									
										
										
										
											2014-08-05 14:00:21 +02:00
										 |  |  | Q_GLOBAL_STATIC_WITH_ARGS(GlobalSharedMemoryContainer, globalSharedMemoryContainer, (10000)) | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | ValuesChangedCommand::ValuesChangedCommand() | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     : m_keyNumber(0) | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ValuesChangedCommand::ValuesChangedCommand(const QVector<PropertyValueContainer> &valueChangeVector) | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     : m_valueChangeVector (valueChangeVector), | 
					
						
							|  |  |  |       m_keyNumber(0) | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-18 16:55:08 +02:00
										 |  |  | const QVector<PropertyValueContainer> ValuesChangedCommand::valueChanges() const | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return m_valueChangeVector; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | quint32 ValuesChangedCommand::keyNumber() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_keyNumber; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ValuesChangedCommand::removeSharedMemorys(const QVector<qint32> &keyNumberVector) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-07-25 16:58:50 +02:00
										 |  |  |     for (qint32 keyNumber : keyNumberVector) { | 
					
						
							| 
									
										
										
										
											2014-08-05 14:00:21 +02:00
										 |  |  |         SharedMemory *sharedMemory = globalSharedMemoryContainer()->take(keyNumber); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |         delete sharedMemory; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-04 17:06:31 +02:00
										 |  |  | void ValuesChangedCommand::sort() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-08-03 23:29:58 +03:00
										 |  |  |     std::sort(m_valueChangeVector.begin(), m_valueChangeVector.end()); | 
					
						
							| 
									
										
										
										
											2013-07-04 17:06:31 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | static const QLatin1String valueKeyTemplateString("Values-%1"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-31 16:45:21 +02:00
										 |  |  | static SharedMemory *createSharedMemory(qint32 key, int byteCount) | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-31 16:45:21 +02:00
										 |  |  |     SharedMemory *sharedMemory = new SharedMemory(QString(valueKeyTemplateString).arg(key)); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     bool sharedMemoryIsCreated = sharedMemory->create(byteCount); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (sharedMemoryIsCreated) { | 
					
						
							| 
									
										
										
										
											2014-08-05 14:00:21 +02:00
										 |  |  |         globalSharedMemoryContainer()->insert(key, sharedMemory); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |         return sharedMemory; | 
					
						
							| 
									
										
										
										
											2014-08-05 14:00:21 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         delete sharedMemory; | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-24 23:56:45 +02:00
										 |  |  |     return nullptr; | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | QDataStream &operator<<(QDataStream &out, const ValuesChangedCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-04-14 09:48:25 +02:00
										 |  |  |     static const bool dontUseSharedMemory = qEnvironmentVariableIsSet("DESIGNER_DONT_USE_SHARED_MEMORY"); | 
					
						
							| 
									
										
										
										
											2012-09-11 17:25:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-25 15:47:43 +02:00
										 |  |  |     QVector<PropertyValueContainer> propertyValueContainer = command.valueChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (command.transactionOption != ValuesChangedCommand::TransactionOption::None) { | 
					
						
							|  |  |  |         PropertyValueContainer optionContainer(command.transactionOption); | 
					
						
							|  |  |  |         propertyValueContainer.append(optionContainer); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!dontUseSharedMemory && propertyValueContainer.count() > 5) { | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |         static quint32 keyCounter = 0; | 
					
						
							|  |  |  |         ++keyCounter; | 
					
						
							|  |  |  |         command.m_keyNumber = keyCounter; | 
					
						
							|  |  |  |         QByteArray outDataStreamByteArray; | 
					
						
							| 
									
										
										
										
											2020-10-08 10:50:15 +03:00
										 |  |  | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |         QDataStream temporaryOutDataStream(&outDataStreamByteArray, QIODevice::WriteOnly); | 
					
						
							| 
									
										
										
										
											2020-10-08 10:50:15 +03:00
										 |  |  | #else
 | 
					
						
							|  |  |  |         QDataStream temporaryOutDataStream(&outDataStreamByteArray, QDataStream::WriteOnly); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-09-20 11:30:11 +02:00
										 |  |  |         temporaryOutDataStream.setVersion(QDataStream::Qt_4_8); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-25 15:47:43 +02:00
										 |  |  |         temporaryOutDataStream << propertyValueContainer; | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-31 16:45:21 +02:00
										 |  |  |         SharedMemory *sharedMemory = createSharedMemory(keyCounter, outDataStreamByteArray.size()); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (sharedMemory) { | 
					
						
							| 
									
										
										
										
											2014-07-17 15:57:09 +02:00
										 |  |  |             sharedMemory->lock(); | 
					
						
							| 
									
										
										
										
											2012-09-20 14:25:01 +02:00
										 |  |  |             std::memcpy(sharedMemory->data(), outDataStreamByteArray.constData(), sharedMemory->size()); | 
					
						
							| 
									
										
										
										
											2014-07-17 15:57:09 +02:00
										 |  |  |             sharedMemory->unlock(); | 
					
						
							| 
									
										
										
										
											2014-07-31 16:45:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |             out << command.keyNumber(); | 
					
						
							|  |  |  |             return out; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     out << qint32(0); | 
					
						
							| 
									
										
										
										
											2019-10-25 15:47:43 +02:00
										 |  |  |     out << propertyValueContainer; | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return out; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  | void readSharedMemory(qint32 key, QVector<PropertyValueContainer> *valueChangeVector) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-31 16:45:21 +02:00
										 |  |  |     SharedMemory sharedMemory(QString(valueKeyTemplateString).arg(key)); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     bool canAttach = sharedMemory.attach(QSharedMemory::ReadOnly); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (canAttach) { | 
					
						
							| 
									
										
										
										
											2014-07-31 16:45:21 +02:00
										 |  |  |         sharedMemory.lock(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |         QDataStream in(QByteArray::fromRawData(static_cast<const char*>(sharedMemory.constData()), sharedMemory.size())); | 
					
						
							| 
									
										
										
										
											2012-09-20 11:30:11 +02:00
										 |  |  |         in.setVersion(QDataStream::Qt_4_8); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |         in >> *valueChangeVector; | 
					
						
							| 
									
										
										
										
											2014-07-31 16:45:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         sharedMemory.unlock(); | 
					
						
							|  |  |  |         sharedMemory.detach(); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | QDataStream &operator>>(QDataStream &in, ValuesChangedCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     in >> command.m_keyNumber; | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-25 15:47:43 +02:00
										 |  |  |     QVector<PropertyValueContainer> valueChangeVector; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (command.keyNumber() > 0) | 
					
						
							|  |  |  |         readSharedMemory(command.keyNumber(), &valueChangeVector); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         in >> valueChangeVector; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // '-option-' is not a valid property name and indicates that we store the transaction option.
 | 
					
						
							|  |  |  |     if (!valueChangeVector.isEmpty() && valueChangeVector.last().name() == "-option-") { | 
					
						
							|  |  |  |         command.transactionOption = | 
					
						
							|  |  |  |             static_cast<ValuesChangedCommand::TransactionOption>(valueChangeVector.last().instanceId()); | 
					
						
							|  |  |  |         valueChangeVector.removeLast(); | 
					
						
							| 
									
										
										
										
											2012-09-11 15:11:34 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-25 15:47:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     command.m_valueChangeVector = valueChangeVector; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  |     return in; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-04 17:06:31 +02:00
										 |  |  | bool operator ==(const ValuesChangedCommand &first, const ValuesChangedCommand &second) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-25 15:47:43 +02:00
										 |  |  |     return first.m_valueChangeVector == second.m_valueChangeVector | 
					
						
							|  |  |  |         && first.transactionOption == second.transactionOption; | 
					
						
							| 
									
										
										
										
											2013-07-04 17:06:31 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-16 17:00:07 +02:00
										 |  |  | QDebug operator <<(QDebug debug, const ValuesChangedCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return debug.nospace() << "ValuesChangedCommand(" | 
					
						
							|  |  |  |                     << "keyNumber: " << command.keyNumber() << ", " | 
					
						
							|  |  |  |                     << command.valueChanges() << ")"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-12 14:39:55 -08:00
										 |  |  | QDataStream &operator<<(QDataStream &out, const ValuesModifiedCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return out << static_cast<const ValuesChangedCommand &>(command); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QDataStream &operator>>(QDataStream &in, ValuesModifiedCommand &command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return in >> static_cast<ValuesChangedCommand &>(command); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-24 14:52:06 +01:00
										 |  |  | } // namespace QmlDesigner
 |