Exemplo n.º 1
0
/**
 * Starts a new cycle for one undo step. Every undoable that is
 * added after calling this method goes into this cycle.
 */
void RS_Undo::startUndoCycle()
{
    if (1 < ++refCount) {
        // only the first fresh top call starts a new cycle
        return;
    }

    size_t  removePointer {static_cast<size_t>(undoPointer + 1)};
    // if there are undo cycles behind undoPointer
    // remove obsolete entities and undoCycles
    if (undoList.size() > removePointer) {
        // collect remaining undoables
        std::list<RS_Undoable*> keep;
        for (auto it = undoList.begin(); it != undoList.begin() + removePointer; ++it) {
            for (auto u: (*it)->getUndoables()){
                keep.push_back( u);
            }
        }
        keep.unique();

        // collect obsolete undoables
        std::list<RS_Undoable*> obsolete;
        for (auto it = undoList.begin() + removePointer; it != undoList.end(); ++it) {
            for (auto u: (*it)->getUndoables()){
                obsolete.push_back( u);
            }
        }
        // unique() only works correct on sorted list!
        obsolete.sort();
        obsolete.unique();

        // delete obsolte undoables which are not in keep list
        for (auto it = obsolete.begin(); it != obsolete.end(); ++it) {
            if (keep.end() == std::find( keep.begin(), keep.end(), *it)) {
                removeUndoable( *it);
            }
        }

        // clean up obsolete undoCycles
        while (undoList.size() > removePointer) {
            undoList.pop_back();
        }
    }

    // alloc new undoCycle
    currentCycle = std::make_shared<RS_UndoCycle>();
}
Exemplo n.º 2
0
/**
 * Starts a new cycle for one undo step. Every undoable that is
 * added after calling this method goes into this cycle.
 */
void RS_Undo::startUndoCycle()
{
  RS_DEBUG->print("RS_Undo::startUndoCycle");

  // definitely delete Undo Cycles and all Undoables in them
  //   that cannot be redone now:
  while ((int)undoList.count()>undoPointer+1 && (int)undoList.count()>0)
  {

    RS_UndoCycle* l = undoList.last();
    if (l!=NULL)
    {
      RS_Undoable* u=NULL;
      bool done = false;
      do
      {
        u = l->getFirstUndoable();
        if (u!=NULL)
        {
          // Remove the pointer from _all_ cycles:
          for (RS_UndoCycle* l2=undoList.first(); l2!=NULL;
               l2=undoList.next())
          {
            l2->removeUndoable(u);
          }

          // Delete the Undoable for good:
          if (u->isUndone())
          {
            removeUndoable(u);
          }
        }
        else
        {
          done = true;
        }
      }
      while(!done);
    }

    // Remove obsolete undo cycles:
    undoList.removeLast();
  }

  currentCycle = new RS_UndoCycle();
}