Warning, file /utilities/okteta/kasten/gui/system/bytearrayviewprofilemanager.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 This file is part of the Okteta Kasten module, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2010, 2012 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "bytearrayviewprofilemanager.hpp" 0010 0011 // library 0012 #include "bytearrayviewprofilelock.hpp" 0013 #include <oktetakastengui.hpp> 0014 // KF 0015 #include <KConfigGroup> 0016 #include <KConfig> 0017 #include <KDirWatch> 0018 // Qt 0019 #include <QFileInfo> 0020 #include <QDir> 0021 #include <QUuid> 0022 0023 namespace Kasten { 0024 QStringList viewProfileFileNameFilter() { return QStringList { QStringLiteral("*.obavp"), QStringLiteral("*.olock") }; } 0025 inline QLatin1String viewProfileFileSuffix() { return QLatin1String(".obavp"); } 0026 inline QLatin1String viewProfileDirSubPath() { return QLatin1String("/okteta/viewprofiles"); } 0027 inline QLatin1String defaultViewProfileFileSubPath() { return QLatin1String("/okteta/defaultviewprofile"); } 0028 static constexpr int DefaultNoOfBytesPerLine = 16; 0029 static constexpr int DefaultNoOfBytesPerGroup = 4; 0030 static constexpr int DefaultLayoutStyle = 0; 0031 static constexpr int DefaultViewModus = 0; 0032 static constexpr int DefaultVisibleByteArrayCodings = 3; 0033 static constexpr int DefaultOffsetCoding = 0; 0034 static constexpr int DefaultValueCoding = 0; 0035 QString DefaultCharCoding() { return {}; } 0036 0037 static QVector<ByteArrayViewProfile::Id> 0038 lockedViewProfileIds(const ByteArrayViewProfileFileInfoLookup& viewProfileFileInfoLookup) 0039 { 0040 QVector<ByteArrayViewProfile::Id> result; 0041 0042 ByteArrayViewProfileFileInfoLookup::ConstIterator end = 0043 viewProfileFileInfoLookup.constEnd(); 0044 for (ByteArrayViewProfileFileInfoLookup::ConstIterator it = 0045 viewProfileFileInfoLookup.constBegin(); 0046 it != end; 0047 ++it) { 0048 if (it.value().isLocked()) { 0049 result.append(it.key()); 0050 } 0051 } 0052 0053 return result; 0054 } 0055 0056 static void 0057 updateLockStatus(ByteArrayViewProfileFileInfoLookup& viewProfileFileInfoLookup, 0058 const QVector<ByteArrayViewProfile::Id>& lockedViewProfileIds, 0059 const QVector<ByteArrayViewProfile::Id>& unlockedViewProfileIds) 0060 { 0061 if (lockedViewProfileIds.isEmpty() && unlockedViewProfileIds.isEmpty()) { 0062 return; 0063 } 0064 0065 ByteArrayViewProfileFileInfoLookup::Iterator end = 0066 viewProfileFileInfoLookup.end(); 0067 for (ByteArrayViewProfileFileInfoLookup::Iterator it = viewProfileFileInfoLookup.begin(); 0068 it != end; 0069 ++it) { 0070 bool isLocked; 0071 0072 if (lockedViewProfileIds.contains(it.key())) { 0073 isLocked = true; 0074 } else if (unlockedViewProfileIds.contains(it.key())) { 0075 isLocked = false; 0076 } else { 0077 continue; 0078 } 0079 0080 it.value().setLocked(isLocked); 0081 } 0082 } 0083 0084 static QString 0085 defaultViewProfileFilePath() 0086 { 0087 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + defaultViewProfileFileSubPath(); 0088 } 0089 0090 static QString 0091 viewProfileFilePath(const ByteArrayViewProfile::Id& viewProfileId) 0092 { 0093 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) 0094 + viewProfileDirSubPath() + QLatin1Char('/') + viewProfileId + viewProfileFileSuffix(); 0095 } 0096 0097 static QString 0098 viewProfileFileName(const ByteArrayViewProfile::Id& viewProfileId) 0099 { 0100 return viewProfileId + viewProfileFileSuffix(); 0101 } 0102 0103 // TODO: add global lock 0104 // TODO: make calls async 0105 // TODO: only load view profiles on demand 0106 ByteArrayViewProfileManager::ByteArrayViewProfileManager() 0107 { 0108 mViewProfileFileWatcher = new KDirWatch(this); 0109 connect(mViewProfileFileWatcher, &KDirWatch::dirty, 0110 this, &ByteArrayViewProfileManager::onViewProfilesFolderChanged); 0111 0112 // get all folder where viewProfiles could be stored 0113 const QStringList dataFolderPaths = 0114 QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); 0115 0116 for (const QString& dataFolderPath : dataFolderPaths) { 0117 const QString viewProfileFolderPath = dataFolderPath + viewProfileDirSubPath(); 0118 // watch folder for changes 0119 mViewProfileFileWatcher->addDir(viewProfileFolderPath, KDirWatch::WatchDirOnly); 0120 0121 // read current files 0122 onViewProfilesFolderChanged(viewProfileFolderPath); 0123 } 0124 0125 // default view profile 0126 // While there is no proper config syncing offer in the used frameworks, use a 0127 // single file with the id as content as workaround and watch for it changing 0128 auto* defaultViewProfileWatcher = new KDirWatch(this); 0129 connect(defaultViewProfileWatcher, &KDirWatch::created, 0130 this, &ByteArrayViewProfileManager::onDefaultViewProfileChanged); 0131 connect(defaultViewProfileWatcher, &KDirWatch::dirty, 0132 this, &ByteArrayViewProfileManager::onDefaultViewProfileChanged); 0133 const QString _defaultViewProfileFilePath = defaultViewProfileFilePath(); 0134 0135 defaultViewProfileWatcher->addFile(_defaultViewProfileFilePath); 0136 0137 onDefaultViewProfileChanged(_defaultViewProfileFilePath); 0138 0139 // report any problems with existing view profiles? 0140 } 0141 0142 ByteArrayViewProfileManager::~ByteArrayViewProfileManager() = default; 0143 0144 int 0145 ByteArrayViewProfileManager::viewProfilesCount() const 0146 { 0147 return mViewProfiles.count(); 0148 } 0149 0150 QVector<ByteArrayViewProfile> 0151 ByteArrayViewProfileManager::viewProfiles() const 0152 { 0153 return mViewProfiles; 0154 } 0155 0156 ByteArrayViewProfile 0157 ByteArrayViewProfileManager::viewProfile(const ByteArrayViewProfile::Id& viewProfileId) const 0158 { 0159 ByteArrayViewProfile result; 0160 0161 for (const ByteArrayViewProfile& viewProfile : mViewProfiles) { 0162 if (viewProfile.id() == viewProfileId) { 0163 result = viewProfile; 0164 break; 0165 } 0166 } 0167 0168 return result; 0169 } 0170 0171 ByteArrayViewProfile::Id 0172 ByteArrayViewProfileManager::defaultViewProfileId() const 0173 { 0174 return mDefaultViewProfileId; 0175 } 0176 0177 ByteArrayViewProfile 0178 ByteArrayViewProfileManager::defaultViewProfile() const 0179 { 0180 return viewProfile(mDefaultViewProfileId); 0181 } 0182 0183 bool 0184 ByteArrayViewProfileManager::isViewProfileLocked(const ByteArrayViewProfile::Id& viewProfileId) const 0185 { 0186 bool result = false; 0187 0188 // search in all folders for the info 0189 for (const ByteArrayViewProfileFileInfoLookup& viewProfileFileInfoLookup : mViewProfileFileInfoLookupPerFolder) { 0190 ByteArrayViewProfileFileInfoLookup::ConstIterator it = 0191 viewProfileFileInfoLookup.find(viewProfileId); 0192 if (it != viewProfileFileInfoLookup.constEnd()) { 0193 result = it->isLocked(); 0194 break; 0195 } 0196 } 0197 0198 return result; 0199 } 0200 0201 void ByteArrayViewProfileManager::saveViewProfiles(QVector<ByteArrayViewProfile>& viewProfiles) 0202 { 0203 // TODO: do not save if locked by someone else -> needs passing of our lock? or just registering our own and check? 0204 // create and set unique id 0205 std::for_each(viewProfiles.begin(), viewProfiles.end(), [this](ByteArrayViewProfile& viewProfile) { 0206 const ByteArrayViewProfile::Id viewProfileId = viewProfile.id(); 0207 0208 bool needsId = true; 0209 if (!viewProfileId.isEmpty()) { 0210 // already existing? 0211 auto hasViewProfileId = [&viewProfileId] (const ByteArrayViewProfile& existingProfile) { 0212 return (viewProfileId == existingProfile.id()); 0213 }; 0214 if (std::any_of(mViewProfiles.constBegin(), mViewProfiles.constEnd(), hasViewProfileId)) { 0215 needsId = false; 0216 } 0217 } 0218 0219 // set new uuid for non-existing 0220 if (needsId) { 0221 viewProfile.setId(QUuid::createUuid().toString()); 0222 } 0223 0224 saveViewProfile(viewProfile); 0225 }); 0226 } 0227 0228 void 0229 ByteArrayViewProfileManager::removeViewProfiles(const QVector<ByteArrayViewProfile::Id>& viewProfileIds) 0230 { 0231 for (const ByteArrayViewProfile::Id& viewProfileId : viewProfileIds) { 0232 removeViewProfile(viewProfileId); 0233 } 0234 } 0235 0236 void 0237 ByteArrayViewProfileManager::setDefaultViewProfile(const ByteArrayViewProfile::Id& viewProfileId) 0238 { 0239 QFile defaultViewProfileFile(defaultViewProfileFilePath()); 0240 defaultViewProfileFile.open(QIODevice::WriteOnly); 0241 0242 defaultViewProfileFile.write(viewProfileId.toUtf8()); 0243 defaultViewProfileFile.close(); 0244 } 0245 0246 ByteArrayViewProfileLock 0247 ByteArrayViewProfileManager::createLock(const ByteArrayViewProfile::Id& viewProfileId) 0248 { 0249 const QString viewProfileFilePath = filePathOfViewProfile(viewProfileId); 0250 0251 return ByteArrayViewProfileLock(viewProfileFilePath, viewProfileId); 0252 } 0253 0254 /* 0255 bool 0256 ByteArrayViewProfileManager::lockViewProfile( const Kasten::ByteArrayViewProfile::Id& viewProfileId ) 0257 { 0258 bool isSuccessfull; 0259 0260 const QString viewProfileFilePath = filePathOfViewProfile( viewProfileId ); 0261 0262 // viewProfile known 0263 if( not viewProfileFilePath.isEmpty() ) 0264 { 0265 const QString lockFilePath = viewProfileFileLockPath( viewProfileFilePath ); 0266 KLockFile::Ptr lock = new KLockFile( lockFilePath ); 0267 const KLockFile::LockResult lockResult = 0268 lock->lock(KLockFile::NoBlockFlag | KLockFile::ForceFlag); 0269 isSuccessfull = (lockResult == KLockFile::LockOK ); 0270 } 0271 // if found 0272 // try to create lock file 0273 return isSuccessfull; 0274 } 0275 */ 0276 // bool 0277 // ByteArrayViewProfileManager::unlockViewProfile( const Kasten::ByteArrayViewProfile::Id& viewProfileId ) 0278 // { 0279 // const QString filePath = filePathOfViewProfile( viewProfileId ); 0280 // 0281 // if( filePath.isEmpty() ) 0282 // return false; 0283 // } 0284 0285 ByteArrayViewProfile 0286 ByteArrayViewProfileManager::loadViewProfile(const QString& absoluteFilePath) const 0287 { 0288 ByteArrayViewProfile result; 0289 0290 KConfig configFile(absoluteFilePath, KConfig::SimpleConfig); 0291 0292 // check version 0293 KConfigGroup formatConfigGroup = configFile.group("OBAVP"); 0294 const QString formatVersion = formatConfigGroup.readEntry("Version"); 0295 if (!formatVersion.startsWith(QLatin1String("1."))) { 0296 return result; 0297 } 0298 0299 result.setId(QFileInfo(absoluteFilePath).baseName()); 0300 0301 KConfigGroup generalConfigGroup = configFile.group("General"); 0302 result.setViewProfileTitle(generalConfigGroup.readEntry("Title")); 0303 0304 KConfigGroup layoutConfigGroup = configFile.group("Layout"); 0305 result.setNoOfBytesPerLine(layoutConfigGroup.readEntry("NoOfBytesPerLine", DefaultNoOfBytesPerLine)); 0306 result.setNoOfGroupedBytes(layoutConfigGroup.readEntry("NoOfBytesPerGroup", DefaultNoOfBytesPerGroup)); 0307 result.setLayoutStyle(layoutConfigGroup.readEntry("LayoutStyle", DefaultLayoutStyle)); 0308 0309 KConfigGroup displayConfigGroup = configFile.group("Display"); 0310 result.setOffsetColumnVisible(displayConfigGroup.readEntry("OffsetColumnVisible", true)); 0311 result.setOffsetCoding(displayConfigGroup.readEntry("OffsetCoding", DefaultOffsetCoding)); 0312 result.setViewModus(displayConfigGroup.readEntry("ViewModus", DefaultViewModus)); 0313 result.setVisibleByteArrayCodings(displayConfigGroup.readEntry("VisibleByteArrayCodings", DefaultVisibleByteArrayCodings)); 0314 0315 KConfigGroup interpretationConfigGroup = configFile.group("Interpretation"); 0316 0317 KConfigGroup valuesConfigGroup = interpretationConfigGroup.group("Values"); 0318 result.setValueCoding(valuesConfigGroup.readEntry("Coding", DefaultValueCoding)); 0319 0320 KConfigGroup charsConfigGroup = interpretationConfigGroup.group("Chars"); 0321 result.setCharCoding(charsConfigGroup.readEntry("Coding", DefaultCharCoding())); 0322 result.setShowsNonprinting(charsConfigGroup.readEntry("NonprintingShown", false)); 0323 result.setSubstituteChar(charsConfigGroup.readEntry("SubstituteChar", ".").at(0)); 0324 result.setUndefinedChar(charsConfigGroup.readEntry("UndefinedChar", "?").at(0)); 0325 0326 return result; 0327 } 0328 0329 void 0330 ByteArrayViewProfileManager::saveViewProfile(const ByteArrayViewProfile& viewProfile) const 0331 { 0332 const QString fileName = viewProfileFilePath(viewProfile.id()); 0333 KConfig configFile(fileName, KConfig::SimpleConfig); 0334 0335 KConfigGroup formatConfigGroup = configFile.group("OBAVP"); 0336 formatConfigGroup.writeEntry("Version", "1.1"); 0337 0338 KConfigGroup generalConfigGroup = configFile.group("General"); 0339 generalConfigGroup.writeEntry("Title", viewProfile.viewProfileTitle()); 0340 0341 KConfigGroup layoutConfigGroup = configFile.group("Layout"); 0342 layoutConfigGroup.writeEntry("NoOfBytesPerLine", viewProfile.noOfBytesPerLine()); 0343 layoutConfigGroup.writeEntry("NoOfBytesPerGroup", viewProfile.noOfGroupedBytes()); 0344 layoutConfigGroup.writeEntry("LayoutStyle", viewProfile.layoutStyle()); 0345 0346 KConfigGroup displayConfigGroup = configFile.group("Display"); 0347 displayConfigGroup.writeEntry("OffsetColumnVisible", viewProfile.offsetColumnVisible()); 0348 displayConfigGroup.writeEntry("OffsetCoding", viewProfile.offsetCoding()); 0349 displayConfigGroup.writeEntry("ViewModus", viewProfile.viewModus()); 0350 displayConfigGroup.writeEntry("VisibleByteArrayCodings", viewProfile.visibleByteArrayCodings()); 0351 0352 KConfigGroup interpretationConfigGroup = configFile.group("Interpretation"); 0353 0354 KConfigGroup valuesConfigGroup = interpretationConfigGroup.group("Values"); 0355 valuesConfigGroup.writeEntry("Coding", viewProfile.valueCoding()); 0356 0357 KConfigGroup charsConfigGroup = interpretationConfigGroup.group("Chars"); 0358 charsConfigGroup.writeEntry("Coding", viewProfile.charCodingName()); 0359 charsConfigGroup.writeEntry("NonprintingShown", viewProfile.showsNonprinting()); 0360 charsConfigGroup.writeEntry("SubstituteChar", QString(viewProfile.substituteChar())); 0361 charsConfigGroup.writeEntry("UndefinedChar", QString(viewProfile.undefinedChar())); 0362 } 0363 0364 void 0365 ByteArrayViewProfileManager::removeViewProfile(const ByteArrayViewProfile::Id& viewProfileId) 0366 { 0367 const QString filePath = filePathOfViewProfile(viewProfileId); 0368 if (!filePath.isEmpty()) { 0369 QFile::remove(filePath); 0370 } 0371 } 0372 0373 QString 0374 ByteArrayViewProfileManager::filePathOfViewProfile(const ByteArrayViewProfile::Id& viewProfileId) const 0375 { 0376 QString result; 0377 0378 for (QHash<QString, ByteArrayViewProfileFileInfoLookup>::ConstIterator foldersIt = 0379 mViewProfileFileInfoLookupPerFolder.constBegin(); 0380 foldersIt != mViewProfileFileInfoLookupPerFolder.constEnd() && result.isEmpty(); 0381 ++foldersIt) { 0382 const ByteArrayViewProfileFileInfoLookup& fileInfoList = foldersIt.value(); 0383 for (ByteArrayViewProfileFileInfoLookup::ConstIterator folderIt = fileInfoList.constBegin(); 0384 folderIt != fileInfoList.constEnd(); 0385 ++folderIt) { 0386 if (folderIt.key() == viewProfileId) { 0387 result = foldersIt.key() + QLatin1Char('/') + viewProfileFileName(viewProfileId); 0388 break; 0389 } 0390 } 0391 } 0392 0393 return result; 0394 } 0395 0396 void 0397 ByteArrayViewProfileManager::onViewProfilesFolderChanged(const QString& viewProfileFolderPath) 0398 { 0399 ByteArrayViewProfileFileInfoLookup& viewProfileFileInfoLookup = 0400 mViewProfileFileInfoLookupPerFolder[viewProfileFolderPath]; 0401 0402 // TODO: reparse for new, removed and changed files 0403 // assume all are removed and unlocked in the beginning 0404 QVector<ByteArrayViewProfile::Id> removedViewProfileIds = viewProfileFileInfoLookup.keys().toVector(); 0405 QVector<ByteArrayViewProfile> newViewProfiles; 0406 QVector<ByteArrayViewProfile> changedViewProfiles; 0407 0408 QVector<ByteArrayViewProfile::Id> newUnlockedViewProfileIds = lockedViewProfileIds(viewProfileFileInfoLookup); 0409 QVector<ByteArrayViewProfile::Id> newLockedViewProfileIds; 0410 // iterate all files in folder 0411 const QFileInfoList viewProfileFileInfoList = 0412 QDir(viewProfileFolderPath).entryInfoList(viewProfileFileNameFilter(), QDir::Files); 0413 0414 for (const QFileInfo& viewProfileFileInfo : viewProfileFileInfoList) { 0415 // a lock file ? 0416 if (viewProfileFileInfo.suffix() == QLatin1String("olock")) { 0417 const ByteArrayViewProfile::Id lockedViewProfileId = viewProfileFileInfo.baseName(); 0418 // if not in old locks, is a new lock 0419 if (!newUnlockedViewProfileIds.removeOne(lockedViewProfileId)) { 0420 newLockedViewProfileIds.append(lockedViewProfileId); 0421 } 0422 continue; 0423 } 0424 0425 // not a viewprofile file ? 0426 if (viewProfileFileInfo.suffix() != QLatin1String("obavp")) { 0427 continue; 0428 } 0429 0430 // all other files assumed to be viewProfile files 0431 const ByteArrayViewProfile::Id viewProfileId = viewProfileFileInfo.baseName(); 0432 // load file 0433 const ByteArrayViewProfile viewProfile = loadViewProfile(viewProfileFileInfo.absoluteFilePath()); 0434 // loading failed? Treat as not existing 0435 if (viewProfile.id().isEmpty()) { 0436 continue; 0437 } 0438 0439 const ByteArrayViewProfileFileInfoLookup::Iterator infoIt = 0440 viewProfileFileInfoLookup.find(viewProfileId); 0441 const bool isKnown = (infoIt != viewProfileFileInfoLookup.end()); 0442 const QDateTime fileInfoLastModified = viewProfileFileInfo.lastModified(); 0443 // is known? 0444 if (isKnown) { 0445 removedViewProfileIds.removeOne(viewProfileId); 0446 0447 // check timestamp 0448 if (fileInfoLastModified == infoIt->lastModified()) { 0449 continue; 0450 } 0451 0452 // update timestamp 0453 infoIt->setLastModified(fileInfoLastModified); 0454 } else { 0455 ByteArrayViewProfileFileInfo info(fileInfoLastModified, false); 0456 viewProfileFileInfoLookup.insert(viewProfileId, info); 0457 } 0458 0459 if (isKnown) { 0460 auto it = std::find_if(mViewProfiles.begin(), mViewProfiles.end(), 0461 [&viewProfileId](const ByteArrayViewProfile& existingProfile) { 0462 return (existingProfile.id() == viewProfileId); 0463 }); 0464 if (it != mViewProfiles.end()) { 0465 *it = viewProfile; 0466 } 0467 } else { 0468 newViewProfiles.append(viewProfile); 0469 } 0470 changedViewProfiles.append(viewProfile); 0471 } 0472 0473 // remove all removed viewprofiles 0474 { 0475 auto isProfileToRemove = [&removedViewProfileIds](const ByteArrayViewProfile& profile) { 0476 return removedViewProfileIds.contains(profile.id()); 0477 }; 0478 mViewProfiles.erase(std::remove_if(mViewProfiles.begin(), mViewProfiles.end(), isProfileToRemove), 0479 mViewProfiles.end()); 0480 } 0481 0482 for (const ByteArrayViewProfile::Id& viewProfileId : qAsConst(removedViewProfileIds)) { 0483 viewProfileFileInfoLookup.remove(viewProfileId); 0484 if (viewProfileId == mDefaultViewProfileId) { 0485 mDefaultViewProfileId.clear(); 0486 } 0487 // TODO: how to select new one? 0488 } 0489 0490 // add new viewprofiles 0491 mViewProfiles.append(newViewProfiles); 0492 // if there was no default viewprofile before, set default to first 0493 const bool isDefaultViewProfileChanged = (mDefaultViewProfileId.isEmpty() && !mViewProfiles.isEmpty()); 0494 if (isDefaultViewProfileChanged) { 0495 mDefaultViewProfileId = mViewProfiles.at(0).id(); 0496 } 0497 0498 // update lock info 0499 updateLockStatus(viewProfileFileInfoLookup, newLockedViewProfileIds, newUnlockedViewProfileIds); 0500 0501 // signal changes 0502 if (!changedViewProfiles.isEmpty()) { 0503 emit viewProfilesChanged(changedViewProfiles); 0504 } 0505 if (!removedViewProfileIds.isEmpty()) { 0506 emit viewProfilesRemoved(removedViewProfileIds); 0507 } 0508 0509 if (!newUnlockedViewProfileIds.isEmpty()) { 0510 emit viewProfilesUnlocked(newUnlockedViewProfileIds); 0511 } 0512 if (!newLockedViewProfileIds.isEmpty()) { 0513 emit viewProfilesLocked(newLockedViewProfileIds); 0514 } 0515 if (isDefaultViewProfileChanged) { 0516 emit defaultViewProfileChanged(mDefaultViewProfileId); 0517 } 0518 } 0519 0520 void ByteArrayViewProfileManager::onDefaultViewProfileChanged(const QString& path) 0521 { 0522 QFile defaultViewProfileFile(path); 0523 if (!defaultViewProfileFile.open(QIODevice::ReadOnly)) { 0524 qCDebug(LOG_KASTEN_OKTETA_GUI) << "Failed to open view profiles file " << path; 0525 return; 0526 } 0527 0528 const QByteArray fileContent = defaultViewProfileFile.readAll(); 0529 const QString viewProfileId = QString::fromUtf8(fileContent); 0530 defaultViewProfileFile.close(); 0531 0532 // no id set? 0533 if (viewProfileId.isEmpty()) { 0534 return; 0535 } 0536 0537 // no change? 0538 if (mDefaultViewProfileId == viewProfileId) { 0539 return; 0540 } 0541 0542 bool isExisting = false; 0543 for (const ByteArrayViewProfile& viewProfile : qAsConst(mViewProfiles)) { 0544 if (viewProfile.id() == viewProfileId) { 0545 isExisting = true; 0546 break; 0547 } 0548 } 0549 0550 if (isExisting) { 0551 mDefaultViewProfileId = viewProfileId; 0552 emit defaultViewProfileChanged(mDefaultViewProfileId); 0553 } 0554 } 0555 0556 } 0557 0558 #include "moc_bytearrayviewprofilemanager.cpp"