Example #1
0
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;
            }
Example #3
0
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;
}
Example #4
0
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);
}
Example #6
0
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);
  }
Example #8
0
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;
        }
    }
}
Example #9
0
      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);
          }
        }
      }
Example #10
0
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;
        }
    }
}
Example #11
0
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());
}
Example #12
0
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;
        }
    }
Example #14
0
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;
}