QRegion OSD::Draw(MythPainter* painter, QPaintDevice *device, QSize size, QRegion &changed, int alignx, int aligny) { bool redraw = m_Refresh; QRegion visible = QRegion(); QRegion dirty = m_Refresh ? QRegion(QRect(QPoint(0,0), m_Rect.size())) : QRegion(); m_Refresh = false; if (!painter || !device) return visible; QTime now = MythDate::current().time(); CheckExpiry(); // first update for alpha pulse and fade QMap<QString,MythScreenType*>::const_iterator it; for (it = m_Children.begin(); it != m_Children.end(); ++it) { if ((*it)->IsVisible()) { QRect vis = (*it)->GetArea().toQRect(); if (visible.isEmpty()) visible = QRegion(vis); else visible = visible.united(vis); (*it)->Pulse(); if (m_Effects && m_ExpireTimes.contains((*it))) { QTime expires = m_ExpireTimes.value((*it)).time(); int left = now.msecsTo(expires); if (left < m_FadeTime) (*it)->SetAlpha((255 * left) / m_FadeTime); } } if ((*it)->NeedsRedraw()) { QRegion area = (*it)->GetDirtyArea(); dirty = dirty.united(area); redraw = true; } } MythNotificationCenter *nc = GetNotificationCenter(); QList<MythScreenType*> notifications; nc->GetNotificationScreens(notifications); QList<MythScreenType*>::iterator it2 = notifications.begin(); while (it2 != notifications.end()) { if (!GetNotificationCenter()->ScreenCreated(*it2)) { if (!m_UIScaleOverride) { OverrideUIScale(false); } (*it2)->SetPainter(m_CurrentPainter); if (!(*it2)->Create()) { it2 = notifications.erase(it2); continue; } } if ((*it2)->IsVisible()) { if (!m_UIScaleOverride) { OverrideUIScale(false); } nc->UpdateScreen(*it2); QRect vis = (*it2)->GetArea().toQRect(); if (visible.isEmpty()) visible = QRegion(vis); else visible = visible.united(vis); (*it2)->Pulse(); if (m_Effects) { QTime expires = nc->ScreenExpiryTime(*it2).time(); int left = now.msecsTo(expires); if (expires.isValid() && left < m_FadeTime) (*it2)->SetAlpha((255 * left) / m_FadeTime); } } if ((*it2)->NeedsRedraw()) { QRegion area = (*it2)->GetDirtyArea(); dirty = dirty.united(area); redraw = true; } ++it2; } RevertUIScale(); if (redraw) { // clear the dirty area painter->Clear(device, dirty); // set redraw for any widgets that may now need a partial repaint for (it = m_Children.begin(); it != m_Children.end(); ++it) { if ((*it)->IsVisible() && !(*it)->NeedsRedraw() && dirty.intersects((*it)->GetArea().toQRect())) { (*it)->SetRedraw(); } } for (it2 = notifications.begin(); it2 != notifications.end(); ++it2) { if ((*it2)->IsVisible() && !(*it2)->NeedsRedraw() && dirty.intersects((*it2)->GetArea().toQRect())) { (*it2)->SetRedraw(); } } // and finally draw QRect cliprect = dirty.boundingRect(); painter->Begin(device); painter->SetClipRegion(dirty); // TODO painting in reverse may be more efficient... for (it = m_Children.begin(); it != m_Children.end(); ++it) { if ((*it)->NeedsRedraw()) { if ((*it)->IsVisible()) (*it)->Draw(painter, 0, 0, 255, cliprect); (*it)->SetAlpha(255); (*it)->ResetNeedsRedraw(); } } for (it2 = notifications.begin(); it2 != notifications.end(); ++it2) { if ((*it2)->NeedsRedraw()) { if ((*it2)->IsVisible()) (*it2)->Draw(painter, 0, 0, 255, cliprect); (*it2)->SetAlpha(255); (*it2)->ResetNeedsRedraw(); } } painter->End(); } changed = dirty; if (visible.isEmpty() || (!alignx && !aligny)) return visible; // assist yuv blending with some friendly alignments QRegion aligned; QVector<QRect> rects = visible.rects(); for (int i = 0; i < rects.size(); i++) { QRect r = rects[i]; int left = r.left() & ~(alignx - 1); int top = r.top() & ~(aligny - 1); int right = (r.left() + r.width()); int bot = (r.top() + r.height()); if (right & (alignx - 1)) right += alignx - (right & (alignx - 1)); if (bot % aligny) bot += aligny - (bot % aligny); aligned = aligned.united(QRegion(left, top, right - left, bot - top)); } return aligned.intersected(QRect(QPoint(0,0), size)); }
/* Update our model of the wallet incrementally, to synchronize our model of the wallet with that of the core. Call with transaction that was added, removed or changed. */ void updateWallet(const uint256 &hash, int status) { qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status); { LOCK2(cs_main, wallet->cs_wallet); // Find transaction in wallet std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash); bool inWallet = mi != wallet->mapWallet.end(); // Find bounds of this transaction in model QList<TransactionRecord>::iterator lower = qLowerBound( cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); QList<TransactionRecord>::iterator upper = qUpperBound( cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); int lowerIndex = (lower - cachedWallet.begin()); int upperIndex = (upper - cachedWallet.begin()); bool inModel = (lower != upper); // Determine whether to show transaction or not bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second)); if(status == CT_UPDATED) { if(showTransaction && !inModel) status = CT_NEW; /* Not in model, but want to show, treat as new */ if(!showTransaction && inModel) status = CT_DELETED; /* In model, but want to hide, treat as deleted */ } qDebug() << " inWallet=" + QString::number(inWallet) + " inModel=" + QString::number(inModel) + " Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) + " showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status); switch(status) { case CT_NEW: if(inModel) { qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model"; break; } if(!inWallet) { qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet"; break; } if(showTransaction) { // Added -- insert at the right position QList<TransactionRecord> toInsert = TransactionRecord::decomposeTransaction(wallet, mi->second); if(!toInsert.isEmpty()) /* only if something to insert */ { parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); int insert_idx = lowerIndex; foreach(const TransactionRecord &rec, toInsert) { cachedWallet.insert(insert_idx, rec); insert_idx += 1; } parent->endInsertRows(); } } break; case CT_DELETED: if(!inModel) { qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model"; break; } // Removed -- remove entire transaction from table parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); cachedWallet.erase(lower, upper); parent->endRemoveRows(); break; case CT_UPDATED: // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for // visible transactions. break; }
QList<MCharsetMatch> MCharsetDetector::detectAll() { Q_D(MCharsetDetector); clearError(); // get list of matches from ICU: qint32 matchesFound; const UCharsetMatch **uCharsetMatch = ucsdet_detectAll(d->_uCharsetDetector, &matchesFound, &(d->_status)); if(hasError()) { qWarning() << __PRETTY_FUNCTION__ << errorString(); return QList<MCharsetMatch>(); } // sometimes the number of matches found by ucsdet_detectAll() // maybe 0 (matchesFound == 0) but d->_status has no error. Do not // return here with an error if this happens because the fine // tuning below may add more matches. Better check whether no // matches were found at all *after* the fine tuning. // fill list of matches into a QList<MCharsetMatch>: QList<MCharsetMatch> mCharsetMatchList; for (qint32 i = 0; i < matchesFound; ++i) { MCharsetMatch mCharsetMatch; mCharsetMatch.setName( QString::fromLatin1(ucsdet_getName(uCharsetMatch[i], &(d->_status)))); if(hasError()) { qWarning() << __PRETTY_FUNCTION__ << errorString(); return QList<MCharsetMatch>(); } mCharsetMatch.setConfidence( static_cast<qint32>(ucsdet_getConfidence (uCharsetMatch[i], &(d->_status)))); if(hasError()) { qWarning() << __PRETTY_FUNCTION__ << errorString(); return QList<MCharsetMatch>(); } mCharsetMatch.setLanguage( QString::fromLatin1(ucsdet_getLanguage(uCharsetMatch[i], &(d->_status)))); if(hasError()) { qWarning() << __PRETTY_FUNCTION__ << errorString(); return QList<MCharsetMatch>(); } mCharsetMatchList << mCharsetMatch; } if(d->_allDetectableCharsets.isEmpty()) getAllDetectableCharsets(); // libicu sometimes does not detect single byte encodings at all // even if they can encode the input without error. This seems to // contradict the documentation on // http://icu-project.org/apiref/icu4c/ucsdet_8h.html which says: // // A confidence value of ten does have a general meaning - it is // used for charsets that can represent the input data, but for // which there is no other indication that suggests that the // charset is the correct one. Pure 7 bit ASCII data, for example, // is compatible with a great many charsets, most of which will // appear as possible matches with a confidence of 10. // // But if such a single byte encoding has been set as the declared // encoding, it should at least be tried, therefore add it here to // the list of matches with the confidence value of 10. If it // cannot encode the complete input, the iteration over the list // of matches will detect that and remove it again. if(!d->_declaredEncoding.isEmpty() && (d->_declaredEncoding.startsWith(QLatin1String("ISO-8859-")) || d->_declaredEncoding.startsWith(QLatin1String("windows-12")) || d->_declaredEncoding.startsWith(QLatin1String("KOI8")))) mCharsetMatchList << MCharsetMatch(d->_declaredEncoding, "", 10); // Similar as for declaredEncoding, when declaredLocale is used // and it is a locale where the legacy encoding is a single byte // encoding, it should at least be tried, therefore add the legacy // single byte encoding for the declared locale here. If it // cannot encode the complete input, it will be removed again // later. Multibyte encodings like Shift_JIS, EUC-JP, Big5, // etc. ... do not need to be added, contrary to the single byte // encodings I could find no case where the matches returned by // libicu did omit a multibyte encoding when it should have been // included. if(!d->_declaredLocale.isEmpty()) { QString language = d->_declaredLocale.left(2); if(language == QLatin1String("ru")) { mCharsetMatchList << MCharsetMatch("KOI8-R", language, 10); mCharsetMatchList << MCharsetMatch("windows-1251", language, 10); mCharsetMatchList << MCharsetMatch("ISO-8859-5", language, 10); } else if(language == QLatin1String("uk")) { mCharsetMatchList << MCharsetMatch("KOI8-U", language, 10); mCharsetMatchList << MCharsetMatch("windows-1251", language, 10); // ISO 8859-5 encoding is missing the letter ґ needed for // Ukrainian, i.e. ISO 8859-5 should not occur for Ukrainian } else if(language == QLatin1String("tr")) mCharsetMatchList << MCharsetMatch("ISO-8859-9", language, 10); else if(language == QLatin1String("el")) mCharsetMatchList << MCharsetMatch("ISO-8859-7", language, 10); else if(language == QLatin1String("en") || language == QLatin1String("da") || language == QLatin1String("de") || language == QLatin1String("es") || language == QLatin1String("fi") || language == QLatin1String("fr") || language == QLatin1String("it") || language == QLatin1String("nl") || language == QLatin1String("no") || language == QLatin1String("nn") || language == QLatin1String("nb") || language == QLatin1String("pt") || language == QLatin1String("sv")) mCharsetMatchList << MCharsetMatch("ISO-8859-1", language, 10); else if(language == QLatin1String("cs") || language == QLatin1String("hu") || language == QLatin1String("pl") || language == QLatin1String("ro")) mCharsetMatchList << MCharsetMatch("ISO-8859-1", language, 10); else if(language == QLatin1String("ar") || language == QLatin1String("fa") || language == QLatin1String("ur")) mCharsetMatchList << MCharsetMatch("ISO-8859-6", language, 10); else if(language == QLatin1String("he")) mCharsetMatchList << MCharsetMatch("ISO-8859-8", language, 10); } // iterate over the detected matches and do some fine tuning: bool sortNeeded = false; qint32 koi8rConfidence = 0; qint32 koi8uConfidence = 0; qint32 iso88595Confidence = 0; qint32 windows1251Confidence = 0; QList<MCharsetMatch>::iterator it = mCharsetMatchList.begin(); while(it != mCharsetMatchList.end()) { if((*it).name() == QLatin1String("KOI8-R")) koi8rConfidence += (*it).confidence(); if((*it).name() == QLatin1String("KOI8-U")) koi8uConfidence += (*it).confidence(); if((*it).name() == QLatin1String("ISO-8859-5")) iso88595Confidence += (*it).confidence(); if((*it).name() == QLatin1String("windows-1251")) windows1251Confidence += (*it).confidence(); if((*it).name() == QLatin1String("ISO-2022-JP")) { // non-Japanese text in ISO-2022-JP encoding is possible // but very unlikely: (*it).setLanguage("ja"); } if((*it).name() == QLatin1String("UTF-8") && (*it).confidence() >= 80 && (*it).confidence() < 99) { // Actually libicu currently only returns confidence // values of 100, 80, 25, and 10 for UTF-8. A value of 80 // can mean two things: // // 1) (hasBOM && numValid > numInvalid*10) // 2) (numValid > 0 && numInvalid == 0) // // If it is case 1), the match will be removed anyway by // the check below which tests whether the complete input // can be encoded. I.e. we don’t need to care about this. // // If it is case 2) *and* the check below whether the // complete input can be encoded does not remove it, we // have valid UTF-8 and it is very unlikely that it is // anything else, therefore I think the confidence of 80 // is too low and should be increased. // With a confidence of only 80, a longer ASCII text with // less than 4 UTF-8 characters will detect as ISO-8859-1 // which is most certainly wrong. (*it).setConfidence(99); sortNeeded = true; } if(!d->_declaredEncoding.isEmpty() && (*it).name() == d->_declaredEncoding && (*it).confidence() == 10) { // A confidence value of 10 means the charset can // represent the input data, but there is no other // indication that suggests that the charset is the // correct one. But if the user has set this to be the // declared encoding, it should be preferred over the // other encodings which also got confidence 10 (there are // often many with confidence 10). Do not increase the // confidence too much though in order not to override // real evidence that the input does really use something // different than the declared encoding. (*it).setConfidence(40); sortNeeded = true; } if(!d->_declaredLocale.isEmpty() && d->_declaredLocale.startsWith((*it).language()) && (*it).confidence() == 10) { // A confidence value of 10 means the charset can // represent the input data, but there is no other // indication that suggests that the charset is the // correct one. But if the detected language for this // charset matches the language declared by the user, this // charset should be preferred over the others which also // got confidence 10 (there are often many with confidence // 10). Do not increase the confidence too much though in // order not to override real evidence that the input does // really use something different than the declared // encoding. Use a slightly lower value than for the // declared encoding. Setting the declared encoding // is more precise and should have somewhat higher priority if(d->_declaredLocale.startsWith("ru")) { // Treat the Russian setDeclaredLocale("ru") case a // bit different than the single byte encodings for // other languages: Only increase the weight of // Russian encodings if setDeclaredLocale("ru") has // been used if libicu has really detected the same // Russian encoding as well. libicu usually detects // these Russian encodings with very low confidences < // 10 for short input. But if we are already pretty // sure that it is Russian because of // setDeclaredLocale("ru"), then these low confidences // detected by libicu seem to be useful to distinguish // between the different Russian legacy encodings. // // If the setDeclareLocale("ru") has been used, the // accumulated confidence for the Russian single byte // encoding is 10 (because of setDeclaredLocale("ru")) // plus whatever libicu has detected. If libicu has // not detected anything, the accumulated confidence // is exactly 10 here and there is no way to // distinguish between the Russian legacy // encodings. Therefore, don’t increase the confidence // if the accumulated confidence is not > 10. // // But if libicu has detected something with small // confidence, the accumulated confidence is 10 plus // something small. In that case, adding something // around 20 seems to work reasonably well. // // I add 20 to the confidence for KOI8-R and // ISO-8859-5 but 21 to the confidence for // windows-1251 to prefer windows-1251 a little bit // over ISO-8859-5. if((*it).name() == QLatin1String("KOI8-R") && koi8rConfidence > 10 && koi8rConfidence < 30) (*it).setConfidence(20 + koi8rConfidence); else if((*it).name() == QLatin1String("ISO-8859-5") && iso88595Confidence > 10 && iso88595Confidence < 30) (*it).setConfidence(20 + iso88595Confidence); else if((*it).name() == QLatin1String("windows-1251") && windows1251Confidence > 10 && windows1251Confidence < 30) (*it).setConfidence(21 + windows1251Confidence); } else if(d->_declaredLocale.startsWith("uk")) { // Treat the Ukrainian setDeclaredLocale("uk") case a // bit different than the single byte encodings for // Russian. // // If the setDeclareLocale("uk") has been used, the // accumulated confidence for the Ukrainian single byte // encoding is 10 (because of setDeclaredLocale("uk")) // plus whatever libicu has detected. If libicu has // not detected anything, the accumulated confidence // is exactly 10 here and there is no way to // distinguish between the Ukrainian legacy // encodings. Therefore, don’t increase the confidence // if the accumulated confidence is not > 10. // // But if libicu has detected something with small // confidence, the accumulated confidence is 10 plus // something small. In that case, adding something // around 20 seems to work reasonably well. // // I add 20 to the confidence for KOI8-U but 25 to the // confidence for windows-1251 to prefer windows-1251 // over KOI8-U. if((*it).name() == QLatin1String("KOI8-U") && koi8uConfidence > 10 && koi8uConfidence < 30) (*it).setConfidence(20 + koi8uConfidence); else if((*it).name() == QLatin1String("windows-1251") && windows1251Confidence > 10 && windows1251Confidence < 30) (*it).setConfidence(25 + windows1251Confidence); } else if((d->_declaredLocale.contains("TW") || d->_declaredLocale.contains("HK") || d->_declaredLocale.contains("MO")) && (*it).name() == QLatin1String("Big5")) { // Traditional Chinese, Big5 more likely (*it).setConfidence(39); } else if((d->_declaredLocale.contains("CN") || d->_declaredLocale.contains("SG") || d->_declaredLocale == "zh") && (*it).name() == QLatin1String("GB18030")) { // Simplified Chinese, GB18030/GB2312 more likely. // Simplified Chinese is also assumed if only “zh” // is set. If the variant is unknown, simplified // Chinese seems a bit more likely. On top of that, // the settings application sets only “zh” for // simplified Chinese and the translations for // simplified Chinese are also in files like // “foo_zh.qm” which makes simplified Chinese more // likely when only “zh” is set on the device (see // also NB#242154). (*it).setConfidence(39); } else { (*it).setConfidence(38); } sortNeeded = true; } if(!d->_allDetectableCharsets.contains((*it).name())) { // remove matches for charsets not supported by QTextCodec // then it is probably some weird charset we cannot use anyway it = mCharsetMatchList.erase(it); } else { // test whether the complete input text can be encoded // using this match, if not remove the match clearError(); text(*it); if(hasError()) { // qDebug() << __PRETTY_FUNCTION__ // << "removing match" << (*it).name() // << "because it cannot encode the complete input" // << errorString(); it = mCharsetMatchList.erase(it); clearError(); } else ++it; } } // sort the list of matches again if confidences have been changed: if(sortNeeded) qSort(mCharsetMatchList.begin(), mCharsetMatchList.end(), qGreater<MCharsetMatch>()); if(mCharsetMatchList.isEmpty()) { // is there any better status to describe this case? d->_status = U_CE_NOT_FOUND_ERROR; qWarning() << __PRETTY_FUNCTION__ << "number of matches found=0" << errorString(); return QList<MCharsetMatch>(); } return mCharsetMatchList; }
bool OSD::DrawDirect(MythPainter* painter, QSize size, bool repaint) { if (!painter) return false; bool visible = false; bool redraw = m_Refresh; m_Refresh = false; QTime now = MythDate::current().time(); CheckExpiry(); QMap<QString,MythScreenType*>::const_iterator it; for (it = m_Children.begin(); it != m_Children.end(); ++it) { if ((*it)->IsVisible()) { visible = true; (*it)->Pulse(); if (m_Effects && m_ExpireTimes.contains((*it))) { QTime expires = m_ExpireTimes.value((*it)).time(); int left = now.msecsTo(expires); if (left < m_FadeTime) (*it)->SetAlpha((255 * left) / m_FadeTime); } if ((*it)->NeedsRedraw()) redraw = true; } } MythNotificationCenter *nc = GetNotificationCenter(); QList<MythScreenType*> notifications; nc->GetNotificationScreens(notifications); QList<MythScreenType*>::iterator it2 = notifications.begin(); while (it2 != notifications.end()) { if (!nc->ScreenCreated(*it2)) { LOG(VB_GUI, LOG_DEBUG, LOC + "Creating OSD Notification"); if (!m_UIScaleOverride) { OverrideUIScale(false); } (*it2)->SetPainter(m_CurrentPainter); if (!(*it2)->Create()) { it2 = notifications.erase(it2); continue; } } if ((*it2)->IsVisible()) { if (!m_UIScaleOverride) { OverrideUIScale(false); } nc->UpdateScreen(*it2); visible = true; (*it2)->Pulse(); if (m_Effects) { QTime expires = nc->ScreenExpiryTime(*it2).time(); int left = now.msecsTo(expires); if (expires.isValid() && left < m_FadeTime) (*it2)->SetAlpha((255 * left) / m_FadeTime); } if ((*it2)->NeedsRedraw()) redraw = true; } ++it2; } RevertUIScale(); redraw |= repaint; if (redraw && visible) { QRect cliprect = QRect(QPoint(0, 0), size); painter->Begin(NULL); for (it = m_Children.begin(); it != m_Children.end(); ++it) { if ((*it)->IsVisible()) { (*it)->Draw(painter, 0, 0, 255, cliprect); (*it)->SetAlpha(255); (*it)->ResetNeedsRedraw(); } } for (it2 = notifications.begin(); it2 != notifications.end(); ++it2) { if ((*it2)->IsVisible()) { (*it2)->Draw(painter, 0, 0, 255, cliprect); (*it2)->SetAlpha(255); (*it2)->ResetNeedsRedraw(); } } painter->End(); } return visible; }
void QSyntaxHighlighterPrivate::applyFormatChanges() { QTextLayout *layout = currentBlock.layout(); QList<QTextLayout::FormatRange> ranges = layout->additionalFormats(); const int preeditAreaStart = layout->preeditAreaPosition(); const int preeditAreaLength = layout->preeditAreaText().length(); QList<QTextLayout::FormatRange>::Iterator it = ranges.begin(); while (it != ranges.end()) { if (it->start >= preeditAreaStart && it->start + it->length <= preeditAreaStart + preeditAreaLength) ++it; else it = ranges.erase(it); } QTextCharFormat emptyFormat; QTextLayout::FormatRange r; r.start = r.length = -1; int i = 0; while (i < formatChanges.count()) { while (i < formatChanges.count() && formatChanges.at(i) == emptyFormat) ++i; if (i >= formatChanges.count()) break; r.start = i; r.format = formatChanges.at(i); while (i < formatChanges.count() && formatChanges.at(i) == r.format) ++i; if (i >= formatChanges.count()) break; r.length = i - r.start; if (r.start >= preeditAreaStart) { r.start += preeditAreaLength; } else if (r.start + r.length >= preeditAreaStart) { r.length += preeditAreaLength; } ranges << r; r.start = r.length = -1; } if (r.start != -1) { r.length = formatChanges.count() - r.start; if (r.start >= preeditAreaStart) { r.start += preeditAreaLength; } else if (r.start + r.length >= preeditAreaStart) { r.length += preeditAreaLength; } ranges << r; } layout->setAdditionalFormats(ranges); }
void ChainDataModel::getAccountImpl(QString accountIdentifier, Account* const * accountInContainer) { try { ilog("Fetching account ${acct}", ("acct", accountIdentifier.toStdString())); auto result = m_db_api->get_full_accounts([this](const fc::variant& v) { vector<variant> updates = v.as<vector<variant>>(); for (const variant& update : updates) { if (update.is_object()) processUpdatedObject(update); else elog("Handling object deletions is not yet implemented: ${update}", ("update", update)); } // TODO: replace true on the next line with a smarter decision as to whether we need status updates or not }, {accountIdentifier.toStdString()}, true); fc::optional<full_account> accountPackage; if (result.count(accountIdentifier.toStdString())) { accountPackage = result.at(accountIdentifier.toStdString()); // Fetch all necessary assets QList<asset_id_type> assetsToFetch; QList<Asset* const *> assetPlaceholders; assetsToFetch.reserve(accountPackage->balances.size()); // Get list of asset IDs the account has a balance in std::transform(accountPackage->balances.begin(), accountPackage->balances.end(), std::back_inserter(assetsToFetch), [](const account_balance_object& b) { return b.asset_type; }); auto function = [this,&assetsToFetch,&assetPlaceholders] { auto itr = assetsToFetch.begin(); const auto& assets_by_id = m_assets.get<by_id>(); // Filter out assets I already have, create placeholders for the ones I don't. while (itr != assetsToFetch.end()) { if (assets_by_id.count(itr->instance)) itr = assetsToFetch.erase(itr); else { assetPlaceholders.push_back(&*m_assets.insert(new Asset(itr->instance, QString(), 0, this)).first); ++itr; } } }; QMetaObject::invokeMethod(parent(), "execute", Qt::BlockingQueuedConnection, Q_ARG(const std::function<void()>&, function)); assert(assetsToFetch.size() == assetPlaceholders.size()); // Blocking call to fetch and complete initialization for all the assets for (int i = 0; i < assetsToFetch.size(); ++i) getAssetImpl(idToString(assetsToFetch[i]), assetPlaceholders[i]); } // Run in main thread Q_EMIT queueExecute([this,accountPackage,accountInContainer](){ ilog("Processing result ${r}", ("r", accountPackage)); auto itr = m_accounts.iterator_to(*accountInContainer); if (!accountPackage.valid()) { (*itr)->deleteLater(); m_accounts.erase(itr); } else { m_accounts.modify(itr, [this,&accountPackage](Account* a){ a->setProperty("id", ObjectId(accountPackage->account.id.instance())); a->setAccountObject(accountPackage->account); // Set balances QList<Balance*> balances; std::transform(accountPackage->balances.begin(), accountPackage->balances.end(), std::back_inserter(balances), [this](const account_balance_object& b) { Balance* bal = new Balance; bal->setParent(this); bal->setProperty("amount", QVariant::fromValue(b.balance.value)); bal->setProperty("type", QVariant::fromValue(getAsset(ObjectId(b.asset_type.instance)))); return bal; }); a->setBalances(balances); }); } }); }
void AnnotationWorkstationExtensionPlugin::onLoadButtonPressed(const std::string& filePath) { QString fileName; if (filePath.empty()) { fileName = QFileDialog::getOpenFileName(NULL, tr("Load annotations"), _settings->value("lastOpenendPath", QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation)).toString(), tr("Annotation files(*.xml;*.ndpa)")); } else { fileName = QString::fromStdString(filePath); } if (!fileName.isEmpty()) { onClearButtonPressed(); if (!_annotationService->loadRepositoryFromFile(fileName.toStdString())) { int ret = QMessageBox::warning(NULL, tr("ASAP"), tr("The annotations could not be loaded."), QMessageBox::Ok); } // Check if it is an ImageScopeRepository, if so, offer the user the chance to reload with new closing distance std::shared_ptr<ImageScopeRepository> imscRepo = std::dynamic_pointer_cast<ImageScopeRepository>(_annotationService->getRepository()); if (imscRepo) { bool ok = false; float newClosingDistance = QInputDialog::getDouble(_viewer, tr("Enter the annotation closing distance."), tr("Please provide the maximal distance for which annotations are automatically closed by ASAP if they remain open."), 30., 0, 1000, 1, &ok); float closingDistance = imscRepo->getClosingDistance(); if (ok && newClosingDistance != closingDistance) { _annotationService->getList()->removeAllAnnotations(); _annotationService->getList()->removeAllGroups(); imscRepo->setClosingDistance(newClosingDistance); imscRepo->load(); } } // Add loaded groups to treewidget QList<QtAnnotationGroup* > childGroups; std::map<std::shared_ptr<AnnotationGroup>, QTreeWidgetItem*> annotToWidget; std::vector<std::shared_ptr<AnnotationGroup> > grps = _annotationService->getList()->getGroups(); for (std::vector<std::shared_ptr<AnnotationGroup> >::const_iterator it = grps.begin(); it != grps.end(); ++it) { QtAnnotationGroup *grp = new QtAnnotationGroup(*it, this); if ((*it)->getGroup() == NULL) { _qtAnnotationGroups.append(grp); QTreeWidgetItem* newAnnotationGroup = new QTreeWidgetItem(_treeWidget); newAnnotationGroup->setText(1, QString::fromStdString((*it)->getName())); newAnnotationGroup->setText(2, "Group"); newAnnotationGroup->setData(1, Qt::UserRole, QVariant::fromValue<QtAnnotationGroup*>(grp)); newAnnotationGroup->setFlags(newAnnotationGroup->flags() | Qt::ItemIsEditable); int cHeight = _treeWidget->visualItemRect(newAnnotationGroup).height(); QPixmap iconPM(cHeight, cHeight); iconPM.fill(QColor((*it)->getColor().c_str())); QIcon color(iconPM); newAnnotationGroup->setIcon(0, color); newAnnotationGroup->setData(0, Qt::UserRole, QColor((*it)->getColor().c_str())); annotToWidget[grp->getAnnotationGroup()] = newAnnotationGroup; } else { childGroups.append(grp); } } while (!childGroups.empty()) { for (QList<QtAnnotationGroup*>::iterator it = childGroups.begin(); it != childGroups.end();) { if (annotToWidget.find((*it)->getAnnotationGroup()->getGroup()) != annotToWidget.end()) { _qtAnnotationGroups.append((*it)); QTreeWidgetItem* newAnnotationGroup = new QTreeWidgetItem(annotToWidget[(*it)->getAnnotationGroup()->getGroup()]); newAnnotationGroup->setText(1, QString::fromStdString((*it)->getAnnotationGroup()->getName())); newAnnotationGroup->setText(2, "Group"); newAnnotationGroup->setData(1, Qt::UserRole, QVariant::fromValue<QtAnnotationGroup*>((*it))); newAnnotationGroup->setFlags(newAnnotationGroup->flags() | Qt::ItemIsEditable); int cHeight = _treeWidget->visualItemRect(newAnnotationGroup).height(); QPixmap iconPM(cHeight, cHeight); iconPM.fill(QColor((*it)->getAnnotationGroup()->getColor().c_str())); QIcon color(iconPM); newAnnotationGroup->setIcon(0, color); newAnnotationGroup->setData(0, Qt::UserRole, QColor((*it)->getAnnotationGroup()->getColor().c_str())); annotToWidget[(*it)->getAnnotationGroup()] = newAnnotationGroup; it = childGroups.erase(it); } else{ ++it; } } } std::vector<std::shared_ptr<Annotation> > annots = _annotationService->getList()->getAnnotations(); for (std::vector<std::shared_ptr<Annotation> >::const_iterator it = annots.begin(); it != annots.end(); ++it) { QTreeWidgetItem* prnt = _treeWidget->invisibleRootItem(); if ((*it)->getGroup()) { prnt = annotToWidget[(*it)->getGroup()]; } std::string key = "Annotation " + QString::number(_annotationIndex).toStdString() + "_annotation"; // Add QtAnnotation QtAnnotation* annot = NULL; if ((*it)->getType() == Annotation::Type::DOT) { annot = new DotQtAnnotation((*it), this, _viewer->getSceneScale()); } else if ((*it)->getType() == Annotation::Type::POLYGON) { annot = new PolyQtAnnotation((*it), this, _viewer->getSceneScale()); dynamic_cast<PolyQtAnnotation*>(annot)->setInterpolationType("linear"); } else if ((*it)->getType() == Annotation::Type::SPLINE) { annot = new PolyQtAnnotation((*it), this, _viewer->getSceneScale()); dynamic_cast<PolyQtAnnotation*>(annot)->setInterpolationType("spline"); } else if ((*it)->getType() == Annotation::Type::POINTSET) { annot = new PointSetQtAnnotation((*it), this, _viewer->getSceneScale()); } if (annot) { annot->finish(); _qtAnnotations.append(annot); _viewer->scene()->addItem(annot); annot->setZValue(20.); _annotationIndex += 1; QTreeWidgetItem* newAnnotation = new QTreeWidgetItem(prnt); newAnnotation->setText(1, QString::fromStdString((*it)->getName())); newAnnotation->setText(2, QString::fromStdString((*it)->getTypeAsString())); newAnnotation->setFlags(newAnnotation->flags() & ~Qt::ItemIsDropEnabled); newAnnotation->setFlags(newAnnotation->flags() | Qt::ItemIsEditable); newAnnotation->setData(1, Qt::UserRole, QVariant::fromValue<QtAnnotation*>(annot)); int cHeight = _treeWidget->visualItemRect(newAnnotation).height(); if (_treeWidget->topLevelItemCount() > 0) { cHeight = _treeWidget->visualItemRect(_treeWidget->topLevelItem(0)).height(); } QPixmap iconPM(cHeight, cHeight); iconPM.fill(QColor((*it)->getColor().c_str())); QIcon color(iconPM); newAnnotation->setIcon(0, color); newAnnotation->setData(0, Qt::UserRole, QColor((*it)->getColor().c_str())); _annotToItem[annot] = newAnnotation; updateAnnotationToolTip(annot); connect(annot, SIGNAL(coordinatesChanged(QtAnnotation*)), this, SLOT(updateAnnotationToolTip(QtAnnotation*))); } } _treeWidget->resizeColumnToContents(0); _treeWidget->resizeColumnToContents(1); }
void ProgramData::FixProgramList(QList<ProgInfo*> &fixlist) { qStableSort(fixlist.begin(), fixlist.end(), start_time_less_than); QList<ProgInfo*>::iterator it = fixlist.begin(); while (1) { QList<ProgInfo*>::iterator cur = it; ++it; // fill in miss stop times if ((*cur)->endts.isEmpty() || (*cur)->startts > (*cur)->endts) { if (it != fixlist.end()) { (*cur)->endts = (*it)->startts; (*cur)->endtime = (*it)->starttime; } else { (*cur)->endtime = (*cur)->starttime; if ((*cur)->endtime < QDateTime( (*cur)->endtime.date(), QTime(6, 0), Qt::UTC)) { (*cur)->endtime = QDateTime( (*cur)->endtime.date(), QTime(6, 0), Qt::UTC); } else { (*cur)->endtime = QDateTime( (*cur)->endtime.date().addDays(1), QTime(0, 0), Qt::UTC); } (*cur)->endts = MythDate::toString((*cur)->endtime, MythDate::kFilename); } } if (it == fixlist.end()) break; // remove overlapping programs if ((*cur)->HasTimeConflict(**it)) { QList<ProgInfo*>::iterator tokeep, todelete; if ((*cur)->endtime <= (*cur)->starttime) tokeep = it, todelete = cur; else if ((*it)->endtime <= (*it)->starttime) tokeep = cur, todelete = it; else if (!(*cur)->subtitle.isEmpty() && (*it)->subtitle.isEmpty()) tokeep = cur, todelete = it; else if (!(*it)->subtitle.isEmpty() && (*cur)->subtitle.isEmpty()) tokeep = it, todelete = cur; else if (!(*cur)->description.isEmpty() && (*it)->description.isEmpty()) tokeep = cur, todelete = it; else tokeep = it, todelete = cur; LOG(VB_XMLTV, LOG_INFO, QString("Removing conflicting program: %1 - %2 %3 %4") .arg((*todelete)->starttime.toString(Qt::ISODate)) .arg((*todelete)->endtime.toString(Qt::ISODate)) .arg((*todelete)->channel) .arg((*todelete)->title)); LOG(VB_XMLTV, LOG_INFO, QString("Conflicted with : %1 - %2 %3 %4") .arg((*tokeep)->starttime.toString(Qt::ISODate)) .arg((*tokeep)->endtime.toString(Qt::ISODate)) .arg((*tokeep)->channel) .arg((*tokeep)->title)); bool step_back = todelete == it; it = fixlist.erase(todelete); if (step_back) --it; } } }
void updateWallet(const uint256 &hash, int status) { const QList<AdsModelRecord>::iterator lower = qLowerBound( cache.begin(), cache.end(), hash, TxLessThan()); const bool inModel = (lower != cache.end() && (*lower).hash == hash); const int lowerIndex = (lower - cache.begin()); { switch(status) { case CT_NEW: { if(inModel) { break; } CTransaction tx; uint256 hashBlock; if (!GetTransaction(hash, tx, hashBlock)) { break; } const AdsModelRecord toInsert = AdsModelRecord::decomposeTransaction(tx); parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex); cache.insert(lowerIndex, toInsert); parent->endInsertRows(); } break; case CT_DELETED: if(!inModel) { break; } // Removed -- remove entire transaction from table parent->beginRemoveRows(QModelIndex(), lowerIndex, lowerIndex); cache.erase(lower); parent->endRemoveRows(); break; case CT_UPDATED: // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for // visible transactions. break; } } if (cache.size() > MAX_ADS) { // remove records, exceeding limit, beginning from oldest. QList<AdsModelRecord>::iterator i = cache.begin(), iend = cache.end(); QList<AdsModelRecord>::iterator imindate = iend; for(; i != iend; ++ i) { if (imindate == cache.end() || (*i).time < (*imindate).time) { imindate = i; } } if (imindate != iend) { updateWallet((*imindate).hash, CT_DELETED); } } }
void ProgramData::FixProgramList(QList<ProgInfo*> &fixlist) { qStableSort(fixlist.begin(), fixlist.end(), start_time_less_than); QList<ProgInfo*>::iterator it = fixlist.begin(); while (1) { QList<ProgInfo*>::iterator cur = it; ++it; // fill in miss stop times if ((*cur)->endts.isEmpty() || (*cur)->startts > (*cur)->endts) { if (it != fixlist.end()) { (*cur)->endts = (*it)->startts; (*cur)->endtime = (*it)->starttime; } /* if its the last programme in the file then leave its endtime as 0000-00-00 00:00:00 so we can find it easily in fix_end_times() */ } if (it == fixlist.end()) break; // remove overlapping programs if ((*cur)->HasTimeConflict(**it)) { QList<ProgInfo*>::iterator tokeep, todelete; if ((*cur)->endtime <= (*cur)->starttime) tokeep = it, todelete = cur; else if ((*it)->endtime <= (*it)->starttime) tokeep = cur, todelete = it; else if (!(*cur)->subtitle.isEmpty() && (*it)->subtitle.isEmpty()) tokeep = cur, todelete = it; else if (!(*it)->subtitle.isEmpty() && (*cur)->subtitle.isEmpty()) tokeep = it, todelete = cur; else if (!(*cur)->description.isEmpty() && (*it)->description.isEmpty()) tokeep = cur, todelete = it; else tokeep = it, todelete = cur; LOG(VB_XMLTV, LOG_INFO, QString("Removing conflicting program: %1 - %2 %3 %4") .arg((*todelete)->starttime.toString(Qt::ISODate)) .arg((*todelete)->endtime.toString(Qt::ISODate)) .arg((*todelete)->channel) .arg((*todelete)->title)); LOG(VB_XMLTV, LOG_INFO, QString("Conflicted with : %1 - %2 %3 %4") .arg((*tokeep)->starttime.toString(Qt::ISODate)) .arg((*tokeep)->endtime.toString(Qt::ISODate)) .arg((*tokeep)->channel) .arg((*tokeep)->title)); bool step_back = todelete == it; it = fixlist.erase(todelete); if (step_back) --it; } } }
void MainWindow::routeNetwork() { // Storage class for the metadata required by Dijkstra struct MetaData { int distance; EdgeItem* edge; NodeItem* previous; NodeItem* owner; MetaData() : distance(INT_MAX) , edge(nullptr) , previous(nullptr) , owner(nullptr) { } MetaData(NodeItem* owner_) : distance(INT_MAX) , edge(nullptr) , previous(nullptr) , owner(owner_) { } }; QMap<NodeItem*, MetaData> metadata; QList<NodeItem*> nodes; NodeItem* current; // Initialise data-structres postInfoMessage("Preparing to route..."); { QMapIterator<QString, NodeItem*> i(m_graphNodes); while (i.hasNext()) { auto item = i.next(); // Initialise the metadata MetaData md(item.value()); if (item.value() == m_routeStart) { // Need minimal distance for the start node md.distance = 0; } metadata[i.value()] = md; // Initialise the node list nodes.append(i.value()); } } // Dijkstra's algorithm: calculate all the distances while (!nodes.isEmpty()) { // Find node with smallest distance { int d = INT_MAX; auto elem = nodes.end(); for (auto it = nodes.begin(); it != nodes.end(); ++it) { int thisDistance = metadata[*it].distance; if (thisDistance < d) { d = thisDistance; elem = it; } } current = *elem; // If we hit the target, we can stop if (current == m_routeEnd) { postInfoMessage("Search complete; reached target node!"); break; } else { // Emshrinken the list nodes.erase(elem); } } postInfoMessage(QString("Considering node %1...") .arg(current->text())); // Visit the neighbours QListIterator<EdgeItem*> i(current->edges()); while (i.hasNext()) { EdgeItem* edge = i.next(); NodeItem* neighbour = edge->endNode(); int dist = metadata[current].distance + edge->weight(); if (dist < metadata[neighbour].distance) { metadata[neighbour].distance = dist; metadata[neighbour].edge = edge; metadata[neighbour].previous = current; } } } // Walk backwards from the target to the source, building the path postInfoMessage("Back-tracking to construct route..."); for (current = m_routeEnd; current; current = metadata[current].previous) { EdgeItem* edge = metadata[current].edge; if (edge) { m_route.prepend(edge); } } // All done! postSuccessMessage("Routing complete!"); // Update the display setHighlightStartNode(m_controlsDock->highlightStartNode()); setHighlightEndNode(m_controlsDock->highlightEndNode()); setHighlightPath(m_controlsDock->highlightPath()); }
void PathFinder::findShortestPath() { bool only = true; SharedNode start, finish; for (auto node1 : _nodes) if (node1->selectionState() == Node::Selection::First) for (auto node2 : _nodes) if (node2->selectionState() == Node::Selection::Second) { if (!only) { return; } else { start = node1; finish = node2; only = false; } } if (only) return; QList<SharedNode> graph; graph = nodeBranch(start, graph); start->setDistance(0); start->setPathToNode(QList<WeakNode>{start}); while (!graph.empty()) { auto iter = std::min_element(begin(graph), end(graph), [](const SharedNode& left, const SharedNode& right) { return left->distance() < right->distance(); }); auto shortest = *iter; for (auto& link : shortest->childLinks()) { size_t alt_dist = shortest->distance() + link->distance(); auto child = link->childNode().lock(); if (alt_dist < child->distance()) { child->setDistance(alt_dist); auto path = shortest->pathToNode(); path.append(child); child->setPathToNode(std::move(path)); } } graph.erase(iter); } for (auto node : _nodes) if (node->distance() != std::numeric_limits<size_t>::max()) node->setText(QString::number(node->distance())); else node->setText("∞"); QList<Link*> highlitedLinks; for (auto iter = finish->pathToNode().begin(); iter != finish->pathToNode().end(); ++iter) { auto node1 = iter->lock(); auto node2 = ((iter + 1) != finish->pathToNode().end()) ? (iter + 1)->lock() : nullptr; node1->setSelectionState(Node::Selection::Highlighted); if (node2) { auto link = node1->getLinkTo(node2); if (link) { link->highlight(); highlitedLinks.append(link); } } } auto pathStart = finish->pathToNode().begin(); auto pathFinish = (finish->pathToNode().end() - 1); if (pathStart != finish->pathToNode().end() && pathStart != pathFinish) { pathStart->lock()->setSelectionState(Node::Selection::First); pathFinish->lock()->setSelectionState(Node::Selection::Second); } QString distance = finish->distance() != std::numeric_limits<size_t>::max() ? QString::number(finish->distance()) : "Недостижимо"; QMessageBox{QMessageBox::Icon::NoIcon, "Графопостроитель", "Расстояние до конечной вершины: <b>" + distance + "</b>", QMessageBox::Button::Ok, this, Qt::WindowTitleHint}.exec(); for (auto node : _nodes) { node->setDistance(std::numeric_limits<size_t>::max()); node->setText(QString::number(node->id())); node->setSelectionState(Node::Selection::None); node->setPathToNode(QList<WeakNode>()); } for (auto link : highlitedLinks) link->unhighlight(); }
void updateMasternode(interfaces::Node& node, const COutPoint& outpoint, int status) { qDebug() << "MasternodeTablePriv::updateMasternode" + QString::fromStdString(strprintf("%s-%d", outpoint.hash.ToString(), outpoint.n)) + " " + QString::number(status); // Find bounds of this masternode in model QString strOutpoint = QString::fromStdString(outpoint.ToStringShort()); QList<MasternodeTableEntry>::iterator lower = qLowerBound( cachedMasternodeTable.begin(), cachedMasternodeTable.end(), strOutpoint, outpointEntryLessThan()); QList<MasternodeTableEntry>::iterator upper = qUpperBound( cachedMasternodeTable.begin(), cachedMasternodeTable.end(), strOutpoint, outpointEntryLessThan()); int lowerIndex = (lower - cachedMasternodeTable.begin()); int upperIndex = (upper - cachedMasternodeTable.begin()); bool inModel = (lower != upper); switch(status) { case CT_NEW: if(inModel) { //must be our own one and we are just at a clean start -> try to update interfaces::Masternode masternode = node.getMasternode(outpoint); lower->txhash = QString::fromStdString(masternode.outpoint.hash.ToString()); lower->n = masternode.outpoint.n; lower->alias = QString::fromStdString(masternode.alias); lower->address = QString::fromStdString(masternode.address); lower->protocol = masternode.protocol; lower->daemon = masternode.daemon; lower->sentinel = masternode.sentinel; lower->status = QString::fromStdString(masternode.status); lower->active = masternode.active; lower->lastseen = masternode.last_seen; lower->payee = QString::fromStdString(masternode.payee); lower->banscore = masternode.banscore; parent->emitDataChanged(lowerIndex); break; } { // Find masternode on platform interfaces::Masternode masternode = node.getMasternode(outpoint); if(masternode.outpoint == COutPoint()) { qWarning() << "MasternodeTablePriv::updateMasternode: Warning: Got CT_NEW, but masternode is not on platform: " + QString::fromStdString(strprintf("%s-%d", outpoint.hash.ToString(), outpoint.n)) + " " + QString::number(status); break; } // Added -- insert at the right position MasternodeTableEntry::Type addressType = translateMasternodeType( QString::fromStdString(masternode.alias)); MasternodeTableEntry toInsert = MasternodeTableEntry( addressType, QString::fromStdString(masternode.outpoint.hash.ToString()), masternode.outpoint.n, QString::fromStdString(masternode.alias), QString::fromStdString(masternode.address), masternode.protocol, masternode.daemon, masternode.sentinel, QString::fromStdString(masternode.status), masternode.active, masternode.last_seen, QString::fromStdString(masternode.payee), masternode.banscore); parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex); cachedMasternodeTable.insert(lowerIndex, toInsert); parent->endInsertRows(); } break; case CT_DELETED: if(!inModel) { qWarning() << "MasternodeTablePriv::updateMasternode: Warning: Got CT_DELETED, but masternode is not in model: " + QString::fromStdString(strprintf("%s-%d", outpoint.hash.ToString(), outpoint.n)) + " " + QString::number(status); break; } // Removed -- remove entire masternode from table parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); cachedMasternodeTable.erase(lower, upper); parent->endRemoveRows(); break; case CT_UPDATED: if(!inModel) { qWarning() << "MasternodeTablePriv::updateMasternode: Warning: Got CT_UPDATED, but entry is not in model: "+ QString::fromStdString(strprintf("%s-%d", outpoint.hash.ToString(), outpoint.n)) + " " + QString::number(status); break; } { // Find masternode on platform interfaces::Masternode masternode = node.getMasternode(outpoint); //don't remove our own nodes if(lower->alias == "" && masternode.outpoint == COutPoint()) { // did we receive a wrong signal? The node got highes priority, delete the entry qWarning() << "MasternodeTablePriv::updateMasternode: Warning: Got CT_UPDATED, but masternode is not on platform: " + QString::fromStdString(strprintf("%s-%d", outpoint.hash.ToString(), outpoint.n)) + " " + QString::number(status); parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); cachedMasternodeTable.erase(lower, upper); parent->endRemoveRows(); break; } MasternodeTableEntry::Type addressType = translateMasternodeType( QString::fromStdString(masternode.alias)); lower->type = addressType; lower->txhash = QString::fromStdString(masternode.outpoint.hash.ToString()); lower->n = masternode.outpoint.n; lower->alias = QString::fromStdString(masternode.alias); lower->address = QString::fromStdString(masternode.address); lower->protocol = masternode.protocol; lower->daemon = masternode.daemon; lower->sentinel = masternode.sentinel; lower->status = QString::fromStdString(masternode.status); lower->active = masternode.active; lower->lastseen = masternode.last_seen; lower->payee = QString::fromStdString(masternode.payee); lower->banscore = masternode.banscore; parent->emitDataChanged(lowerIndex); } break; } }
QList<QRect> OpenCVFaceDetector::mergeFaces(const cv::Mat& inputImage, const QList< QList<QRect> >& combo) const { Q_UNUSED(inputImage); QList<QRect> results; // Make one long vector of all faces foreach (const QList<QRect>& list, combo) { results += list; } // used only one cascade? No need to merge then int primaryCascades = 0; foreach (const Cascade& cascade, d->cascades) { if (cascade.primaryCascade) primaryCascades++; } if (primaryCascades <= 1) { return results; } /* * Now, starting from the left, take a face and compare with rest. If distance is less than a threshold, * consider them to be "overlapping" face frames and delete the "duplicate" from the vector. * Remember that only faces to the RIGHT of the reference face will be deleted. */ QList<int> genuineness; int ctr = 0; QList<QRect>::iterator first, second; for (first = results.begin(); first != results.end(); ) { int duplicates = 0; for (second = first + 1; second != results.end(); ) // Compare with the faces to the right { ctr++; if (distanceOfCenters(*first, *second) < d->maxDistance) { second = results.erase(second); duplicates++; } else { ++second; } } if (duplicates < d->minDuplicates) // Less duplicates, probably not genuine, kick it out { first = results.erase(first); } else { // Face passed both tests, will be in final results ++first; } } qCDebug(DIGIKAM_FACESENGINE_LOG) << "Faces parsed: " << ctr << " number of final faces: " << results.size(); return results; }
bool standardize::dofunc(const QString & func_name, const V3DPluginArgList & input, V3DPluginArgList & output, V3DPluginCallback2 & callback, QWidget * parent) { vector<char*> infiles, inparas, outfiles; if(input.size() >= 1) infiles = *((vector<char*> *)input.at(0).p); if(input.size() >= 2) inparas = *((vector<char*> *)input.at(1).p); if(output.size() >= 1) outfiles = *((vector<char*> *)output.at(0).p); if (func_name == tr("standardize")) { cout<<"This is standardize_swc plugin"<<endl; if(infiles.size() <2) { cerr<<"Need both the reference swc file ( to seed the soma) and the input swc file."<<endl; cerr<<"You can use the input swc file as the reference swc file, if no particular soma location is required." <<endl; return false; } QString ref_swc_file = infiles[0]; QString inputswc_file = infiles[1]; if(inputswc_file.isEmpty() || ref_swc_file.isEmpty()) { cerr<<"please check both input swc files"<<endl; return false; } if (inparas.size() <1) { printf("Please specify two parameters - 1)the gap size for bridging during the sorting step; 2) the type to be assgined.\n"); return false; } double dis_th = atof(inparas.at(0)); int type = -1;//use the old type if (inparas.size() ==2) type = atof(inparas.at(1)); double sort_th = dis_th ; //the parameter in sort_neuron_swc plugin, specifying the length threshold to bridge the gap QString outswc_file = outfiles[0]; cout<<"ref_swc_file = "<<ref_swc_file.toStdString().c_str()<<endl; cout<<"inswc_file = "<<inputswc_file.toStdString().c_str()<<endl; cout<<"gap threshold = "<<dis_th<<endl; cout<<"outswc_file = "<<outswc_file.toStdString().c_str()<<endl; cout<<"new type code = "<<type<<endl; NeuronTree nt_input = readSWC_file(inputswc_file); // cout<<" Standardize: 1) resample"<<endl; // NeuronTree nt_input_rs = resample(nt_input, dis_th); NeuronTree nt_ref = readSWC_file(ref_swc_file); double soma_x, soma_y, soma_z, soma_r; for (V3DLONG i = 0; i < nt_ref.listNeuron.size(); i++) { if(nt_ref.listNeuron[i].pn<0) { soma_x = nt_ref.listNeuron.at(i).x; soma_y = nt_ref.listNeuron.at(i).y; soma_z = nt_ref.listNeuron.at(i).z; soma_r = nt_ref.listNeuron.at(i).r; break; } } V3DLONG neuronNum = nt_input.listNeuron.size(); QVector<QVector<V3DLONG> > children_list = QVector< QVector<V3DLONG> >(neuronNum, QVector<V3DLONG>() ); for (V3DLONG i = 0; i < neuronNum; i++) { V3DLONG parent = nt_input.listNeuron[i].pn; if (parent < 0) continue; children_list[nt_input.hashNeuron.value(parent)].push_back(i); } double Dist = INT_MAX; double Dist_inrange = INT_MAX; V3DLONG soma_ID = -1; V3DLONG dist_ID = -1; int child_num = 0; cout<<" standardize: 1) matching soma roots"<<endl; // set the distance threshold to searching for matching soma node QList<NeuronSWC> list_neurons = nt_input.listNeuron; double search_distance_th = soma_r * 5 ;// choose the bigger value between soma_r*5 and search_distance_th*5 if (search_distance_th < sort_th *5) { search_distance_th = sort_th *5; } for (V3DLONG i=0;i<list_neurons.size();i++) { NeuronSWC curr = list_neurons.at(i); double nodedist = sqrt(pow2(curr.x - soma_x) + pow2(curr.y - soma_y) + pow2(curr.z - soma_z)); if(nodedist <= search_distance_th && curr.pn <0) { soma_ID = curr.n; child_num = 1; break; } if(nodedist <= search_distance_th && children_list[i].size() > child_num) { soma_ID = curr.n; child_num = children_list[i].size(); Dist_inrange = nodedist; } if(nodedist <= search_distance_th && children_list[i].size() == child_num && nodedist < Dist_inrange) { soma_ID = curr.n; Dist_inrange = nodedist; } if(nodedist < Dist) { dist_ID = curr.n; Dist = nodedist; } } if(child_num < 1 || soma_ID == -1) soma_ID = dist_ID; cout<<" Standardize: 2) sort"<<endl; QList<NeuronSWC> result; if (!SortSWC(nt_input.listNeuron, result ,soma_ID, sort_th)) { v3d_msg("fail to call swc sorting function.",0); return false; } cout<<" Standardize: 3) only keep the first tree(identified by the soma from the reference."<<endl; //skip the first root for (V3DLONG i = 1;i<result.size();i++) { if (result[i].pn == -1) {//remove other trees, only keep the first one cout<< "remove "<<result.size()-i<<" nodes"<<endl; result.erase(result.begin()+i, result.end()); } } cout<<" Standardize: 4) reset type for soma and neurites"<<endl; //1-soma //2-axon //3-dendrite //4-apical dendrite export_list2file_retype(result,outswc_file,0,type); } else if (func_name == tr("help")) { cout << "This super-plugin is used to post-processing auto reconstructions for comparisons. "<<endl; cout << "It will identify the soma for each input reconstruction " <<endl; cout << "based on the reference SWC file, and sort SWC nodes based on the soma root while bridging" <<endl; cout << "all disconneted components when the gap is less then the specified gap_threshold. The search range "<<endl; cout << "for the matching soma is 5*soma_radius." <<endl; cout << "Usage : <vaa3d> -x standardize -f standardize -i <reference_swc_file> <inswc_file> -o <outswc_file> -p <gap_threshold> <new_neurite_type> "<<endl; } else return false; return true; }