예제 #1
0
void StartPage::handle_focusChanged(QWidget * old, QWidget * now)
{
    QAbstractItemView * old_area = qobject_cast<QAbstractItemView *>(old);
    if ( old_area && isAncestorOf(old_area) && isAncestorOf(now) && !old->parentWidget()->isAncestorOf(now) ) {
        QModelIndex none;
        Q_ASSERT( !none.isValid() );
        old_area->setCurrentIndex( none );
    }
}
예제 #2
0
파일: Allocator.c 프로젝트: 0x20c24/cjdns
void Allocator__adopt(struct Allocator* adoptedParent,
                      struct Allocator* childToAdopt,
                      const char* file,
                      int line)
{
    struct Allocator_pvt* parent = Identity_check((struct Allocator_pvt*) adoptedParent);
    struct Allocator_pvt* child = Identity_check((struct Allocator_pvt*) childToAdopt);

    if (isAncestorOf(child, parent)) {
        // The child is a parent of the parent, this means an adoption would be meaningless
        // because if the child is otherwise freed, it will take the parent along with it.
        return;
    }

    if (!parent->adoptions) {
        parent->adoptions =
            Allocator__calloc(adoptedParent, sizeof(struct Allocator_Adoptions), 1, file, line);
    }
    if (!child->adoptions) {
        child->adoptions =
            Allocator__calloc(childToAdopt, sizeof(struct Allocator_Adoptions), 1, file, line);
    }

    struct Allocator_List* pl =
        Allocator__calloc(adoptedParent, sizeof(struct Allocator_List), 1, file, line);
    pl->alloc = child;
    pl->next = parent->adoptions->children;
    parent->adoptions->children = pl;

    struct Allocator_List* cl =
        Allocator__calloc(childToAdopt, sizeof(struct Allocator_List), 1, file, line);
    cl->alloc = parent;
    cl->next = child->adoptions->parents;
    child->adoptions->parents = cl;
}
예제 #3
0
void Allocator__disown(struct Allocator* parentAlloc,
                       struct Allocator* allocToDisown,
                       const char* fileName,
                       int lineNum)
{
    struct Allocator_pvt* parent = Identity_check((struct Allocator_pvt*) parentAlloc);
    struct Allocator_pvt* child = Identity_check((struct Allocator_pvt*) allocToDisown);

    if (parent->pub.isFreeing || child->pub.isFreeing) { return; }

    if (child->parent == parent) {
        // The child's natural parent has been freed and it has pivoted to the adopted parent
        // Do a normal Allocator_free() and it will either pivot once again to another adopter
        // or it will drop from the tree and free.
        Allocator__free(&child->pub, fileName, lineNum);
        return;
    }

    if (isAncestorOf(child, parent)) {
        // Rare but possible way that the child would never have been adopted.
        return;
    }

    disconnectAdopted(parent, child);
}
OOModel::Expression* CompoundObjectDescriptor::create(const QList<OOModel::Expression*>& operands)
{
	Q_ASSERT(operands.size() == 1);
	auto ilit = dynamic_cast<OOModel::IntegerLiteral*> (operands.first());
	Q_ASSERT(ilit);
	auto e = storedExpressions().value(ilit->value());
	SAFE_DELETE(ilit);
	Q_ASSERT(e);

	if (auto model = e->model())
	{
		auto beingModified = model->isBeingModified();
		auto oldModificationTarget = beingModified ? nullptr : model->modificationTarget();
		auto oldParent = e->parent();

		Q_ASSERT(e!=oldModificationTarget && !e->isAncestorOf(oldModificationTarget));

		if (!beingModified) oldParent->beginModification("extract expression");
		else model->changeModificationTarget(oldParent);
		auto replaceSuccessfull = oldParent->replaceChild(e, new OOModel::EmptyExpression());
		Q_ASSERT(replaceSuccessfull);

		if (!beingModified) oldParent->endModification();
		else model->changeModificationTarget(oldModificationTarget);
	}
	else
	{
		auto replaceSuccessfull = e->parent()->replaceChild(e, new OOModel::EmptyExpression());
		Q_ASSERT(replaceSuccessfull);
	}

	return e;
}
예제 #5
0
/*!
 * \brief JsonDbObject::isAncestorOf tests if this JsonDbObject contains an ancestor version
 *        of the passed JsonDbObject. It does NOT take _uuid into account, it works on version()
 *        only.
 *
 *        For this method to return a valid answer, the passed object needs to have an intact
 *        _meta object.
 *
 * \param other the object to check ancestorship
 * \return true if this object is an ancestor version of the passed object
 */
bool JsonDbObject::isAncestorOf(const JsonDbObject &other) const
{
    QJsonArray history = other.value(JsonDbString::kMetaStr).toObject().value(QStringLiteral("history")).toArray();

    int updateCount;
    QString hash = tokenizeVersion(version(), &updateCount);

    return isAncestorOf(history, updateCount, hash);
}
예제 #6
0
FormEditorItem* DragTool::calculateContainer(const QPointF &point, FormEditorItem * currentItem)
{
    QList<QGraphicsItem *> list = scene()->items(point);
    foreach (QGraphicsItem *item, list) {
         FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item);
         if (formEditorItem && formEditorItem != currentItem && formEditorItem->isContainer()
             && !isAncestorOf(currentItem, formEditorItem))
             return formEditorItem;
    }
예제 #7
0
bool ccHObject::isAncestorOf(const ccHObject *anObject) const
{
	assert(anObject);
	ccHObject* parent = anObject->getParent();
	if (!parent)
		return false;

	if (parent == this)
		return true;

	return isAncestorOf(parent);
}
예제 #8
0
/** return 1 if true, otherwise zero. */
static int isAncestorOf(struct Allocator_pvt* maybeParent,
                        struct Allocator_pvt* maybeChild)
{
    if (maybeParent == maybeChild) {
        return 1;
    }
    if (maybeParent == NULL || maybeChild == NULL || maybeChild->parent == maybeChild) {
        return 0;
    }
    if (isAncestorOf(maybeParent, maybeChild->parent)) {
        return 1;
    }
    if (maybeChild->adoptions) {
        struct Allocator_List* al = maybeChild->adoptions->parents;
        while (al) {
            if (isAncestorOf(maybeParent, al->alloc)) {
                return 1;
            }
        }
    }
    return 0;
}
예제 #9
0
void VEditTab::handleFocusChanged(QWidget * /* p_old */, QWidget *p_now)
{
    if (p_now == this) {
        // When VEditTab get focus, it should focus to current widget.
        focusChild();

        emit getFocused();
        updateStatus();
    } else if (isAncestorOf(p_now)) {
        emit getFocused();
        updateStatus();
    }
}
예제 #10
0
JurisdictionMap::Area JurisdictionMap::isMyJurisdiction(const unsigned char* nodeOctalCode, int childIndex) const {
    // to be in our jurisdiction, we must be under the root...

    // if the node is an ancestor of my root, then we return ABOVE
    if (isAncestorOf(nodeOctalCode, _rootOctalCode)) {
        return ABOVE;
    }
    
    // otherwise...
    bool isInJurisdiction = isAncestorOf(_rootOctalCode, nodeOctalCode, childIndex);
    // if we're under the root, then we can't be under any of the endpoints
    if (isInJurisdiction) {
        for (int i = 0; i < _endNodes.size(); i++) {
            bool isUnderEndNode = isAncestorOf(_endNodes[i], nodeOctalCode);
            if (isUnderEndNode) {
                isInJurisdiction = false;
                break;
            }
        }
    }
    return isInJurisdiction ? WITHIN : BELOW;
}
예제 #11
0
파일: RangeImpl.cpp 프로젝트: mydw/mydw
/** This is the master routine invoked to visit the nodes
*   selected by this range.  For each such node, different
*   actions are taken depending on the value of the TraversalType argument.
*/
DOM_DocumentFragment RangeImpl::traverseContents(TraversalType how)
{
    if (fDetached)
        throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null);

    if (fStartContainer == null || fEndContainer == null) {
        return DOM_DocumentFragment(); // REVIST: Throw exception?
    }

    /* Traversal is accomplished by first determining the
       relationship between the endpoints of the range.
       For each of four significant relationships, we will
       delegate the traversal call to a method that
       can make appropriate assumptions.
    */

    // case 1: same container
    if ( fStartContainer == fEndContainer )
        return traverseSameContainer( how );

    // case 2: Child C of start container is ancestor of end container
    for (DOM_Node node = fStartContainer.getFirstChild(); node != null; node=node.getNextSibling()) {
        if (isAncestorOf(node, fEndContainer))
            return traverseCommonStartContainer( node, how );
    }

    // case 3: Child C of end container  is ancestor of start container
    for (DOM_Node nd = fEndContainer.getFirstChild(); nd != null; nd=nd.getNextSibling()) {
        if (isAncestorOf(nd, fStartContainer))
            return traverseCommonEndContainer( nd, how );
    }

    // case 4: preorder traversal of context tree.
    // There is a common ancestor container.  Find the
    // ancestor siblings that are children of that container.
    DOM_Node ancestor = commonAncestorOf(fStartContainer, fEndContainer);
    return traverseCommonAncestors( ancestor, ancestor, how );
}
예제 #12
0
//-----------------------------------------------------------------------------
//!
//-----------------------------------------------------------------------------
bool tAbstractSideBar::sceneEventFilter( QGraphicsItem* pWatched, QEvent* pEvent )
{
    if( ( ( pEvent->type() == QEvent::GraphicsSceneMousePress ) ||
        ( pEvent->type() == QEvent::GraphicsSceneMouseMove ) ||
        ( pEvent->type() == QEvent::GraphicsSceneMouseRelease ) ||
        ( pEvent->type() == QEvent::GraphicsSceneMouseDoubleClick ) ) && 
        isAncestorOf( pWatched ) )
    {

        return MouseHandler( (QGraphicsSceneMouseEvent*)pEvent );
    }

    return false;
}
예제 #13
0
파일: RangeImpl.cpp 프로젝트: mydw/mydw
/** This function must be called by the DOM _BEFORE_
*  a node is deleted, because at that time it is
*  connected in the DOM tree, which we depend on.
*/
void RangeImpl::updateRangeForDeletedNode(NodeImpl* node)
{

    if (node == null) return;
    if (fRemoveChild == node) return;

    DOM_Node tNode(node);

    if (node->getParentNode() == fStartContainer.fImpl) {
        unsigned short index = indexOf(tNode, fStartContainer);
        if ( fStartOffset > index) {
            fStartOffset--;
        }
    }

    if (node->getParentNode() == fEndContainer.fImpl) {
        unsigned short index = indexOf(tNode, fEndContainer);
        if ( fEndOffset > index) {
            fEndOffset--;
        }
    }

    if (node->getParentNode() != fStartContainer.fImpl
            ||  node->getParentNode() != fEndContainer.fImpl) {
        if (isAncestorOf(node, fStartContainer)) {
            DOM_Node tpNode(node->getParentNode());
            setStartContainer( tpNode );
            fStartOffset = indexOf( tNode, tpNode);
        }
        if (isAncestorOf(node, fEndContainer)) {
            DOM_Node tpNode(node->getParentNode());
            setEndContainer( tpNode );
            fEndOffset = indexOf( tNode, tpNode);
        }
    }

}
예제 #14
0
bool ReferenceSystem::linkTo(ReferenceSystem *rs)
{
	if(rs!=base)//if it is not currently dependant
	{   //it si posible to link if this is not parent grand parent ...etc) of rs	
		if(isAncestorOf(rs)==false){
			unLink();
			base=rs;//rs es el padre de *this
			if(rs)rs->dependentSystem.push_back(this);//set *this as dependant of 
			setNeedToUpdate();
			return true;
			}
		return false;
	}
	return true;

}
예제 #15
0
QList<Model::Node*> Method::findSymbols(const QRegExp& symbolExp, Model::Node* source, FindSymbolMode mode,
                                        bool exhaustAllScopes)
{
    if (mode == SEARCH_UP && isAncestorOf(source))
    {
        QList<Model::Node*> symbols;

        symbols << arguments()->findAllSymbolDefinitions(symbolExp);
        symbols << results()->findAllSymbolDefinitions(symbolExp);
        // Note that a StatementList also implements findSymbols and locally declared variables will be found there.

        if (exhaustAllScopes || symbols.isEmpty())
            symbols << Node::findSymbols(symbolExp, source, mode, exhaustAllScopes);

        return symbols;
    }
    else return QList<Model::Node*> ();
}
예제 #16
0
Model::Node* Project::navigateTo(Model::Node* source, QString path)
{
	QString symbol = extractFrontSymbol(path);
	Model::Node* found = nullptr;

	// Is the target symbol name the module's name
	if (isAncestorOf(source) && symbol == symbolName()) found = this;

	if (!found) found = projects()->findFirstSymbolDefinition(symbol);
	if (!found) found = libraries()->findFirstSymbolDefinition(symbol);
	if (!found) found = modules()->findFirstSymbolDefinition(symbol);
	if (!found) found = classes()->findFirstSymbolDefinition(symbol);
	if (!found) return ExtendableNode::navigateTo(source, path);

	QString rest = extractSecondaryPath(path);
	if (!rest.isEmpty()) return found->navigateTo(this, rest);
	else return found;
}
void KLFLibEntryEditor::slotCopy()
{
  QWidget *fw = QApplication::focusWidget();
  if (!isAncestorOf(fw))
    return;

  if (fw->inherits("QTextEdit")) {
    qobject_cast<QTextEdit*>(fw)->copy();
  } else if (fw->inherits("QLineEdit")) {
    qobject_cast<QLineEdit*>(fw)->copy();
  } else if (fw->inherits("QLabel")) {
#if QT_VERSION >= 0x040700
    QLabel *lbl = qobject_cast<QLabel*>(fw);
    if (lbl->hasSelectedText()) {
      QApplication::clipboard()->setText(lbl->selectedText());
    }
#endif
  }
}
예제 #18
0
bool VEditTab::tabHasFocus() const
{
    QWidget *wid = QApplication::focusWidget();
    return wid == this || isAncestorOf(wid);
}
예제 #19
0
bool TWidget::inFocusChain() const {
	return !isHidden() && App::wnd() && (App::wnd()->focusWidget() == this || isAncestorOf(App::wnd()->focusWidget()));
}
예제 #20
0
파일: RangeImpl.cpp 프로젝트: mydw/mydw
void RangeImpl::insertNode(DOM_Node& newNode)
{
    if (newNode == null) return; //don't have to do anything

    for (DOM_Node aNode = fStartContainer; aNode!=null; aNode = aNode.getParentNode()) {
        if (aNode.fImpl->isReadOnly()) {
            throw DOM_DOMException(
                DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
        }
    }

    if (fDocument != newNode.getOwnerDocument()) {
        throw DOM_DOMException(
            DOM_DOMException::WRONG_DOCUMENT_ERR, null);
    }

    // Prevent cycles in the tree.
    //isKidOK() is not checked here as its taken care by insertBefore() function
    if (isAncestorOf( newNode, fStartContainer)) {
        throw DOM_DOMException(
            DOM_DOMException::HIERARCHY_REQUEST_ERR, null);
    }

    if( fDetached) {
        throw DOM_DOMException(
            DOM_DOMException::INVALID_STATE_ERR, null);
    }

    int type = newNode.getNodeType();
    if (type == DOM_Node::ATTRIBUTE_NODE
            || type == DOM_Node::ENTITY_NODE
            || type == DOM_Node::NOTATION_NODE
            || type == DOM_Node::DOCUMENT_NODE)
    {
        throw DOM_RangeException(
            DOM_RangeException::INVALID_NODE_TYPE_ERR, null);
    }


    DOM_Node parent;
    DOM_Node next;

    if (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) {

        //set 'parent' and 'next' here
        parent = fStartContainer.getParentNode();

        //split the text nodes
        if (fStartOffset > 0)
            ((DOM_Text &)fStartContainer).splitText(fStartOffset);

        //update the new start information later. After inserting the first newNode
        if (fStartOffset == 0)
            next = fStartContainer;
        else
            next = fStartContainer.getNextSibling();

    } // end of text handling
    else {
        parent = fStartContainer;

        next = fStartContainer.getFirstChild();
        for(unsigned int i = 0; (i < fStartOffset) && (next != null); i++) {
            next=next.getNextSibling();
        }
    }

    if (parent != null) {
        if (next != null)
            parent.insertBefore(newNode, next);
        else
            parent.appendChild(newNode);
    }
}
예제 #21
0
파일: RangeImpl.cpp 프로젝트: mydw/mydw
short RangeImpl::compareBoundaryPoints(DOM_Range::CompareHow how, RangeImpl* srcRange) const
{
    if (fDocument != srcRange->fDocument) {
        throw DOM_DOMException(
            DOM_DOMException::WRONG_DOCUMENT_ERR, null);
    }
    if( fDetached) {
        throw DOM_DOMException(
            DOM_DOMException::INVALID_STATE_ERR, null);
    }

    DOM_Node pointA, pointB;
    int offsetA, offsetB;

    switch (how)
    {
    case (DOM_Range::START_TO_START) :
        pointB = srcRange->getStartContainer();
        pointA = fStartContainer;
        offsetB = srcRange->getStartOffset();
        offsetA = fStartOffset;
        break;
    case (DOM_Range::START_TO_END) :
        pointB = srcRange->getStartContainer();
        pointA = fEndContainer;
        offsetB = srcRange->getStartOffset();
        offsetA = fEndOffset;
        break;
    case (DOM_Range::END_TO_START) :
        pointB = srcRange->getEndContainer();
        pointA = fStartContainer;
        offsetB = srcRange->getEndOffset();
        offsetA = fStartOffset;
        break;
    case (DOM_Range::END_TO_END) :
        pointB = srcRange->getEndContainer();
        pointA = fEndContainer;
        offsetB = srcRange->getEndOffset();
        offsetA = fEndOffset;
        break;
    default:
        throw DOM_DOMException(
            DOM_DOMException::INVALID_STATE_ERR, null);
    }

    // case 1: same container
    if (pointA == pointB) {
        if (offsetA < offsetB) return -1; //A before B
        if (offsetA == offsetB) return 0; //A equal to B
        return 1; // A after B
    }
    // case 2: Child C of container A is ancestor of B
    for (DOM_Node node = pointA.getFirstChild(); node != null; node=node.getNextSibling()) {
        if (isAncestorOf(node, pointB)) {
            int index = indexOf(node, pointA);
            if (offsetA <=  index) return -1;
            return 1;
        }
    }
    // case 3: Child C of container B is ancestor of A
    for (DOM_Node nd = pointB.getFirstChild(); nd != null; nd=nd.getNextSibling()) {
        if (isAncestorOf(nd, pointA)) {
            int index = indexOf(nd, pointB);
            if (index < offsetB ) return -1;
            return 1; //B strictly before A
        }
    }

    // case 4: preorder traversal of context tree.
    DOM_Node ancestor = commonAncestorOf(pointA, pointB);
    DOM_Node current = ancestor;

    do {
        if (current == pointA) return -1;
        if (current == pointB) return 1;
        current = nextNode(current, true);
    }
    while (current!=null && current!=ancestor);

    return -2; // this should never happen
}
예제 #22
0
bool KCompletionBox::eventFilter( QObject *o, QEvent *e )
{
    int type = e->type();
    QWidget *wid = qobject_cast<QWidget*>(o);

    if (o == this) {
        return false;
    }

    if (wid && wid == d->m_parent &&
        (type == QEvent::Move || type == QEvent::Resize)) {
        hide();
        return false;
    }

    if (wid && (wid->windowFlags() & Qt::Window) &&
        type == QEvent::Move && wid == d->m_parent->window()) {
        hide();
        return false;
    }

    if (type == QEvent::MouseButtonPress && (wid && !isAncestorOf(wid))) {
        if (!d->emitSelected && currentItem() && !qobject_cast<QScrollBar*>(o)) {
            Q_ASSERT(currentItem());
            emit currentTextChanged(currentItem()->text() );
        }
        hide();
        e->accept();
        return true;
    }

    if (wid && wid->isAncestorOf(d->m_parent) && isVisible()) {
        if ( type == QEvent::KeyPress ) {
            QKeyEvent *ev = static_cast<QKeyEvent *>( e );
            switch ( ev->key() ) {
            case Qt::Key_Backtab:
                if ( d->tabHandling && (ev->modifiers() == Qt::NoButton ||
                                        (ev->modifiers() & Qt::ShiftModifier)) ) {
                    up();
                    ev->accept();
                    return true;
                }
                break;
            case Qt::Key_Tab:
                if ( d->tabHandling && (ev->modifiers() == Qt::NoButton) ) {
                    down();
                    // #65877: Key_Tab should complete using the first
                    // (or selected) item, and then offer completions again
                    if (count() == 1) {
                        KLineEdit* parent = qobject_cast<KLineEdit*>(d->m_parent);
                        if (parent) {
                            parent->doCompletion(currentItem()->text());
                        } else {
                            hide();
                        }
                    }
                    ev->accept();
                    return true;
                }
                break;
            case Qt::Key_Down:
                down();
                ev->accept();
                return true;
            case Qt::Key_Up:
                // If there is no selected item and we've popped up above
                // our parent, select the first item when they press up.
                if ( !selectedItems().isEmpty() ||
                     mapToGlobal( QPoint( 0, 0 ) ).y() >
                     d->m_parent->mapToGlobal( QPoint( 0, 0 ) ).y() )
                    up();
                else
                    down();
                ev->accept();
                return true;
            case Qt::Key_PageUp:
                pageUp();
                ev->accept();
                return true;
            case Qt::Key_PageDown:
                pageDown();
                ev->accept();
                return true;
            case Qt::Key_Escape:
                canceled();
                ev->accept();
                return true;
            case Qt::Key_Enter:
            case Qt::Key_Return:
                if ( ev->modifiers() & Qt::ShiftModifier ) {
                    hide();
                    ev->accept();  // Consume the Enter event
                    return true;
                }
                break;
            case Qt::Key_End:
                if ( ev->modifiers() & Qt::ControlModifier )
                {
                    end();
                    ev->accept();
                    return true;
                }
                break;
            case Qt::Key_Home:
                if ( ev->modifiers() & Qt::ControlModifier )
                {
                    home();
                    ev->accept();
                    return true;
                }
            default:
                break;
            }
        } else if ( type == QEvent::ShortcutOverride ) {
            // Override any accelerators that match
            // the key sequences we use here...
            QKeyEvent *ev = static_cast<QKeyEvent *>( e );
            switch ( ev->key() ) {
            case Qt::Key_Down:
            case Qt::Key_Up:
            case Qt::Key_PageUp:
            case Qt::Key_PageDown:
            case Qt::Key_Escape:
            case Qt::Key_Enter:
            case Qt::Key_Return:
                ev->accept();
                return true;
                break;
            case Qt::Key_Tab:
            case Qt::Key_Backtab:
                if ( ev->modifiers() == Qt::NoButton ||
                     (ev->modifiers() & Qt::ShiftModifier))
                {
                    ev->accept();
                    return true;
                }
                break;
            case Qt::Key_Home:
            case Qt::Key_End:
                if ( ev->modifiers() & Qt::ControlModifier )
                {
                    ev->accept();
                    return true;
                }
                break;
            default:
                break;
            }
        } else if ( type == QEvent::FocusOut ) {
            QFocusEvent* event = static_cast<QFocusEvent*>( e );
            if (event->reason() != Qt::PopupFocusReason
#ifdef Q_WS_WIN
                && (event->reason() != Qt::ActiveWindowFocusReason || QApplication::activeWindow() != this)
#endif
                )
                hide();
        }
    }

    return KListWidget::eventFilter( o, e );
}
예제 #23
0
/*!
 * \brief JsonDbObject::updateVersionOptimistic implement an optimisticWrite
 * \param other the object containing the update to be written. Do NOT call computeVersion()
 *        on the other object before passing it in! other._meta.history is assumed untrusted.
 * \param versionWritten contains the version string of the write upon return
 * \param trackHistory whether version history should be tracked or not. Defaults to true.
 * \return true if the passed object is a valid write. As this version can operate
 *         on conflicts too, version() and versionWritten can differ.
 */
bool JsonDbObject::updateVersionOptimistic(const JsonDbObject &other, QString *versionWrittenOut, bool trackHistory)
{
    QString versionWritten;
    // this is trusted and expected to contain a _meta object with book keeping info
    QJsonObject meta = value(JsonDbString::kMetaStr).toObject();

    // an array of all versions this object has replaced
    QJsonArray history = meta.value(QStringLiteral("history")).toArray();

    // all known conflicts
    QJsonArray conflicts = meta.value(JsonDbString::kConflictsStr).toArray();

    // check for in-object override of history tracking
    if (trackHistory && value(JsonDbString::kLocalStr).toBool())
        trackHistory = false;

    QString replacedVersion = other.version();

    int replacedCount;
    QString replacedHash = tokenizeVersion(replacedVersion, &replacedCount);

    int updateCount = replacedCount;
    QString hash = replacedHash;

    // we don't trust other._meta.history, so other._version must be replacedVersion
    // if other.computeVersion() was called before updateVersionOptimistic(), other can at max be a replay
    // as we lost which version other is replacing.
    bool isReplay = !other.computeVersion(replacedCount, replacedHash, &updateCount, &hash);

    bool isValidWrite = false;

    // first we check if this version can eliminate a conflict
    for (QJsonArray::const_iterator ii = conflicts.begin(); ii < conflicts.end(); ii++) {

        JsonDbObject conflict((*ii).toObject());
        if (conflict.version() == replacedVersion) {
            if (!isReplay)
                conflicts.removeAt(ii.i);
            if (!isValidWrite) {
                addAncestor(&history, updateCount, hash);
                versionWritten = versionAsString(updateCount, hash);
            }
            isValidWrite = true;
        }
    }

    // now we check if this version can progress the head
    if (version().isEmpty() || version() == replacedVersion) {
        if (!isReplay)
            *this = other;
        if (!isValidWrite)
            versionWritten = versionAsString(updateCount, hash);
        insert(JsonDbString::kVersionStr, versionWritten);
        isValidWrite = true;
    }

    // make sure we can resurrect a tombstone
    // Issue: Recreating a _uuid must have a updateCount higher than the tombstone
    //        otherwise it is considered a conflict.
    if (!isValidWrite && isDeleted()) {
        if (!isReplay) {
            addAncestor(&history, replacedCount, replacedHash);
        }

        replacedHash = tokenizeVersion(version(), &replacedCount);
        updateCount = replacedCount + 1;
        versionWritten = versionAsString(updateCount, hash);

        *this = other;
        insert(JsonDbString::kVersionStr, versionWritten);
        isValidWrite = true;
    }

    // update the book keeping of what versions we have replaced in this version branch
    if (isValidWrite && !isReplay) {
        addAncestor(&history, replacedCount, replacedHash);

        meta = QJsonObject();

        if (trackHistory && history.size())
            meta.insert(QStringLiteral("history"), history);
        if (conflicts.size())
            meta.insert(JsonDbString::kConflictsStr, history);

        if (!meta.isEmpty())
            insert(JsonDbString::kMetaStr, meta);
        else
            insert(JsonDbString::kMetaStr, QJsonValue::Undefined);
    }

    // last chance for a valid write: other is a replay from history
    if (!isValidWrite && isAncestorOf(history, updateCount, hash)) {
        isValidWrite = true;
        versionWritten = versionAsString(updateCount, hash);
    }

    if (versionWrittenOut)
        *versionWrittenOut = versionWritten;

    return isValidWrite;
}
예제 #24
0
void SettingsPopup::focusChanged(QWidget *, QWidget *to)
{
    if(!to || (to != this && !isAncestorOf(to)))
        deleteLater();
}