MCPcopy Create free account
hub / github.com/DISTRHO/Cardinal / cloneAction

Method cloneAction

src/override/ModuleWidget.cpp:846–928  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

844}
845
846void ModuleWidget::cloneAction(bool cloneCables) {
847 // history::ComplexAction
848 history::ComplexAction* h = new history::ComplexAction;
849 h->name = "duplicate module";
850
851 // Save patch store in this module so we can copy it below
852 APP->engine->prepareSaveModule(module);
853
854 // JSON serialization is the obvious way to do this
855 json_t* moduleJ = toJson();
856 DEFER({
857 json_decref(moduleJ);
858 });
859 engine::Module::jsonStripIds(moduleJ);
860
861 // Clone Module
862 INFO("Creating module %s", model->getFullName().c_str());
863 engine::Module* clonedModule = model->createModule();
864
865 // Set ID here so we can copy module storage dir
866 clonedModule->id = random::u64() % (1ull << 53);
867 system::copy(module->getPatchStorageDirectory(), clonedModule->getPatchStorageDirectory());
868
869 // This doesn't need a lock (via Engine::moduleFromJson()) because the Module is not added to the Engine yet.
870 try {
871 clonedModule->fromJson(moduleJ);
872 }
873 catch (Exception& e) {
874 WARN("%s", e.what());
875 }
876 APP->engine->addModule(clonedModule);
877
878 // Clone ModuleWidget
879 INFO("Creating module widget %s", model->getFullName().c_str());
880 ModuleWidget* clonedModuleWidget = model->createModuleWidget(clonedModule);
881 APP->scene->rack->updateModuleOldPositions();
882 APP->scene->rack->addModule(clonedModuleWidget);
883 // Place module to the right of `this` module, by forcing it to 1 HP to the right.
884 math::Vec clonedPos = box.pos;
885 clonedPos.x += clonedModuleWidget->box.getWidth();
886 if (settings::squeezeModules)
887 APP->scene->rack->squeezeModulePos(clonedModuleWidget, clonedPos);
888 else
889 APP->scene->rack->setModulePosNearest(clonedModuleWidget, clonedPos);
890 h->push(APP->scene->rack->getModuleDragAction());
891 APP->scene->rack->updateExpanders();
892
893 // history::ModuleAdd
894 history::ModuleAdd* hma = new history::ModuleAdd;
895 hma->setModule(clonedModuleWidget);
896 h->push(hma);
897
898 if (cloneCables) {
899 // Clone cables attached to input ports
900 for (PortWidget* pw : getInputs()) {
901 for (CableWidget* cw : APP->scene->rack->getCompleteCablesOnPort(pw)) {
902 // Create cable attached to cloned ModuleWidget's input
903 engine::Cable* clonedCable = new engine::Cable;

Callers 1

createContextMenuMethod · 0.45

Calls 12

u64Function · 0.85
prepareSaveModuleMethod · 0.80
c_strMethod · 0.80
addModuleMethod · 0.80
createModuleWidgetMethod · 0.80
getWidthMethod · 0.80
addCableMethod · 0.80
getFullNameMethod · 0.45
createModuleMethod · 0.45
fromJsonMethod · 0.45
pushMethod · 0.45
setModuleMethod · 0.45

Tested by

no test coverage detected