void CtrlrPanelCanvas::pasteGroupComponent(const ValueTree &groupTree, const int destinationX, const int destinationY)
{
	if (groupTree.hasType ("groupTree"))
	{
		CtrlrComponent *parent		= addNewComponent (groupTree.getChild(0), 0, true);
		if (destinationX >= 0 && destinationY >= 0)
			parent->setTopLeftPosition (destinationX, destinationY);
		else
			parent->setTopLeftPosition (parent->getX()+(parent->getWidth()/2), parent->getY()+(parent->getHeight()/2));

		CtrlrGroup *group			= dynamic_cast<CtrlrGroup*>(parent);
		CtrlrTabsComponent *tabs	= dynamic_cast<CtrlrTabsComponent*>(parent);

		for (int i=0; i<groupTree.getChild(0).getNumChildren(); i++)
		{
			if (groupTree.getChild(0).getChild(i).hasType(Ids::modulator))
			{
				CtrlrComponent *child = addNewComponent (groupTree.getChild(0).getChild(i), 0, true);
				if (group && child)
				{
					group->setOwned(child, true);
				}

				if (tabs && child)
				{
					tabs->setOwned(child, child->getProperty(Ids::componentTabId), true);
				}
			}
		}
	}
}
void CtrlrPanelCanvas::replaceComponent (CtrlrModulator &modulator, const String &targetComponentType)
{
	CtrlrComponent *oldComponent = modulator.getComponent();
	CtrlrComponent *newComponent = nullptr;

	/* detach the existing component so it doesn't get notified about anything, the pointer will be invalid */
    if (getOwner().getSelection())
    {
        getOwner().getSelection()->deselectAll();
        getOwner().getSelection()->dispatchPendingMessages();
        getOwner().getSelection()->removeChangeListener(oldComponent);
    }

	if (oldComponent)
	{
		/* keep a copy of the old properties, we need to find out if the component is in a group */
		ValueTree oldComponentProperties = oldComponent->getObjectTree().createCopy();

		modulator.setComponentType(targetComponentType, false);

		/* get the new component pointer and attach it */
		newComponent = modulator.getComponent();
        if (getOwner().getSelection())
            getOwner().getSelection()->addChangeListener (newComponent);

		addAndMakeVisibleNg (modulator.getComponent(), nullptr, true);

		/* attach the new component to any group components the old component was int */
		if (oldComponentProperties.hasProperty(Ids::componentGroupName))
		{
			CtrlrGroup *group = dynamic_cast<CtrlrGroup*>(owner.getOwner().getComponent(oldComponentProperties.getProperty(Ids::componentGroupName)));
			if (group)
			{
				group->setOwned (newComponent, true);
			}
		}

		if (oldComponentProperties.hasProperty(Ids::componentTabName))
		{
			CtrlrTabsComponent *tabs = dynamic_cast<CtrlrTabsComponent*>(owner.getOwner().getComponent(oldComponentProperties.getProperty(Ids::componentTabName)));
			if (tabs)
			{
				tabs->setOwned (newComponent, oldComponentProperties.getProperty(Ids::componentTabId), true);
			}
		}

		/* copy any old properties to the new component */
        for (int i=0; i<oldComponentProperties.getNumProperties(); i++)
		{
			const Identifier propName 	= oldComponentProperties.getPropertyName(i);
			const var propValue			= oldComponentProperties.getProperty(propName);

			if (propName != Ids::uiType)
			{
				if (newComponent->getObjectTree().hasProperty(propName))
					newComponent->setProperty (propName, propValue);
			}
		}
	}
}
void CtrlrComponent::removeFromTab ()
{
	CtrlrModulator *tabsModulator = owner.getOwner().getModulator(getProperty(Ids::componentTabName));
	if (tabsModulator)
	{
		CtrlrTabsComponent *tabsComponent = dynamic_cast<CtrlrTabsComponent*>(tabsModulator->getComponent());
		if (tabsComponent)
		{
			tabsComponent->setOwned (this, getProperty(Ids::componentTabId), false);
		}
	}
}