ScriptItem::ScriptItem(const openstudio::path& path, OSItem::Type type, QWidget * parent) : OSItem(scriptToItemId(path), type, parent), m_removed(false), m_scriptInfo(path, true, false) { setText(openstudio::toQString(path.filename())); setLeftPixmap(QPixmap(":/images/icon_scripts.png")); if (boost::regex_search(toString(itemId().sourceId()),boost::regex("resource"))) { m_scriptInfo.isUserScript = false; } else { try { m_scriptInfo = runmanager::RubyJobBuilder::updateArgumentsFromDb(m_scriptInfo); } catch (const runmanager::ScriptDetectionError &e) { // Nothing to display here in the constructor m_scriptInfo = e.scriptInfo; } } boost::shared_ptr<OSDocument> osDoc = OSAppBase::instance()->currentDocument(); connect(this,SIGNAL(argChanged()),osDoc.get(),SLOT(markAsModified())); }
// NOTE(jda) - can't do default member initializers due to MSVC... Node::Node() { properties.name = "NULL"; properties.type = "Node"; // MSVC 2013 is buggy and ignores {}-initialization of anonymous structs #ifdef _WIN32 # if _MSC_VER <= 1800 properties.parent = nullptr; properties.valid = false; # endif #endif properties.flags = sg::NodeFlags::none; markAsModified(); }
bool Database::changeKdf(const QSharedPointer<Kdf>& kdf) { Q_ASSERT(!m_data.isReadOnly); kdf->randomizeSeed(); QByteArray transformedMasterKey; if (!m_data.key) { m_data.key = QSharedPointer<CompositeKey>::create(); } if (!m_data.key->transform(*kdf, transformedMasterKey)) { return false; } setKdf(kdf); m_data.transformedMasterKey = transformedMasterKey; markAsModified(); return true; }
Database::Database() : m_metadata(new Metadata(this)) , m_data() , m_rootGroup(nullptr) , m_timer(new QTimer(this)) , m_emitModified(false) , m_uuid(QUuid::createUuid()) { setRootGroup(new Group()); rootGroup()->setUuid(QUuid::createUuid()); rootGroup()->setName(tr("Root", "Root group name")); m_timer->setSingleShot(true); s_uuidMap.insert(m_uuid, this); connect(m_metadata, SIGNAL(metadataModified()), this, SLOT(markAsModified())); connect(m_timer, SIGNAL(timeout()), SIGNAL(databaseModified())); m_modified = false; m_emitModified = true; }
/** * Set and transform a new encryption key. * * @param key key to set and transform or nullptr to reset the key * @param updateChangedTime true to update database change time * @param updateTransformSalt true to update the transform salt * @param transformKey trigger the KDF after setting the key * @return true on success */ bool Database::setKey(const QSharedPointer<const CompositeKey>& key, bool updateChangedTime, bool updateTransformSalt, bool transformKey) { Q_ASSERT(!m_data.isReadOnly); if (!key) { m_data.key.reset(); m_data.transformedMasterKey = {}; m_data.hasKey = false; return true; } if (updateTransformSalt) { m_data.kdf->randomizeSeed(); Q_ASSERT(!m_data.kdf->seed().isEmpty()); } QByteArray oldTransformedMasterKey = m_data.transformedMasterKey; QByteArray transformedMasterKey; if (!transformKey) { transformedMasterKey = oldTransformedMasterKey; } else if (!key->transform(*m_data.kdf, transformedMasterKey)) { return false; } m_data.key = key; m_data.transformedMasterKey = transformedMasterKey; m_data.hasKey = true; if (updateChangedTime) { m_metadata->setMasterKeyChanged(Clock::currentDateTimeUtc()); } if (oldTransformedMasterKey != m_data.transformedMasterKey) { markAsModified(); } return true; }
/** * Save the database to a file. * * This function uses QTemporaryFile instead of QSaveFile due to a bug * in Qt (https://bugreports.qt.io/browse/QTBUG-57299) that may prevent * the QSaveFile from renaming itself when using Dropbox, Drive, or OneDrive. * * The risk in using QTemporaryFile is that the rename function is not atomic * and may result in loss of data if there is a crash or power loss at the * wrong moment. * * @param filePath Absolute path of the file to save * @param atomic Use atomic file transactions * @param backup Backup the existing database file, if exists * @param error error message in case of failure * @return true on success */ bool Database::save(const QString& filePath, QString* error, bool atomic, bool backup) { Q_ASSERT(!m_data.isReadOnly); if (m_data.isReadOnly) { return false; } if (atomic) { QSaveFile saveFile(filePath); if (saveFile.open(QIODevice::WriteOnly)) { // write the database to the file if (!writeDatabase(&saveFile, error)) { return false; } if (backup) { backupDatabase(filePath); } if (saveFile.commit()) { // successfully saved database file setFilePath(filePath); return true; } } if (error) { *error = saveFile.errorString(); } } else { QTemporaryFile tempFile; if (tempFile.open()) { // write the database to the file if (!writeDatabase(&tempFile, error)) { return false; } tempFile.close(); // flush to disk if (backup) { backupDatabase(filePath); } // Delete the original db and move the temp file in place QFile::remove(filePath); // Note: call into the QFile rename instead of QTemporaryFile // due to an undocumented difference in how the function handles // errors. This prevents errors when saving across file systems. if (tempFile.QFile::rename(filePath)) { // successfully saved the database tempFile.setAutoRemove(false); setFilePath(filePath); return true; } else if (!backup || !restoreDatabase(filePath)) { // Failed to copy new database in place, and // failed to restore from backup or backups disabled tempFile.setAutoRemove(false); if (error) { *error = tr("%1\nBackup database located at %2").arg(tempFile.errorString(), tempFile.fileName()); } markAsModified(); return false; } } if (error) { *error = tempFile.errorString(); } } // Saving failed markAsModified(); return false; }