void
AddItemsCommand::redo()
{

    KnobItemsTablePtr model = _items.front().item->getModel();

    model->beginEditSelection();
    model->clearSelection(eTableChangeReasonInternal);


    for (std::list<ItemToAdd>::const_iterator it = _items.begin(); it != _items.end(); ++it) {
        bool skipInsert = false;
        if (_isFirstRedo) {
            // The item may already be at the correct position in the parent, check it
            if (!it->parentItem) {
                if (model->getTopLevelItem(it->indexInParent) == it->item) {
                    skipInsert = true;
                }
            } else {
                if (it->parentItem->getChild(it->indexInParent) == it->item) {
                    skipInsert = true;
                }
            }
        }
        if (!skipInsert) {
            model->insertItem(it->indexInParent, it->item, it->parentItem, eTableChangeReasonInternal);
        }
        model->addToSelection(it->item, eTableChangeReasonInternal);
    }

    model->endEditSelection(eTableChangeReasonInternal);
    model->getNode()->getApp()->triggerAutoSave();
    _isFirstRedo = false;
}
void
RemoveItemsCommand::undo()
{
    KnobItemsTablePtr model = _items.begin()->item->getModel();
    model->beginEditSelection();
    model->clearSelection(eTableChangeReasonInternal);
    for (std::list<ItemToRemove>::const_iterator it = _items.begin(); it != _items.end(); ++it) {
        int prevIndex = -1;
        KnobTableItemPtr prevItem = it->prevItem.lock();
        if (prevItem) {
            prevIndex = prevItem->getIndexInParent();
        }
        if (prevIndex != -1) {
            model->insertItem(prevIndex, it->item, it->item->getParent(), eTableChangeReasonInternal);
        } else {
            model->addItem(it->item, it->item->getParent(), eTableChangeReasonInternal);
        }
        model->addToSelection(it->item, eTableChangeReasonInternal);
    }
    model->endEditSelection(eTableChangeReasonInternal);
    model->getNode()->getApp()->triggerAutoSave();
}