/* * qlo10k1 - GUI frontend for ld10k1 * * Copyright (c) 2004 by Peter Zubaj * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "strglobal.h" #include "strparam.h" #include "structure.h" #include "structure_io.h" #include "structure_link.h" #include "structure_patch.h" #include "ld10k1file.h" StrGlobal::StrGlobal(CardParam *card) { Card = card; Card->Structure = this; // registers Inputs.setAutoDelete(TRUE); // the list owns the objects Outputs.setAutoDelete(TRUE); FXs.setAutoDelete(TRUE); Links.setAutoDelete(TRUE); // patches Patches.setAutoDelete(TRUE); // the list owns the objects } StrGlobal::~StrGlobal(void) { Card = NULL; } void StrGlobal::clear(void) { Links.clear(); Inputs.clear(); Outputs.clear(); FXs.clear(); Patches.clear(); UsedItems.clear(); } void StrGlobal::clearFlags(void) { StrFX *fx = NULL; for(fx = FXs.first(); fx; fx = FXs.next()) { fx->setFlagUsed(false); fx->setFlagNew(false); fx->setFlagChanged(false); } StrInput *in = NULL; for(in = Inputs.first(); in; in = Inputs.next()) { in->setFlagUsed(false); in->setFlagNew(false); in->setFlagChanged(false); } StrOutput *out = NULL; for(out = Outputs.first(); out; out = Outputs.next()) { out->setFlagUsed(false); out->setFlagNew(false); out->setFlagChanged(false); } StrPatch *p = NULL; for(p = Patches.first(); p; p = Patches.next()) { p->setFlagUsed(false); p->setFlagNew(false); p->setFlagChanged(false); } StrLink *l = NULL; for(l = Links.first(); l; l = Links.next()) { l->setFlagUsed(false); l->setFlagNew(false); l->setFlagChanged(false); } } int StrGlobal::loadFromLD(void) { clearFlags(); // load registers int cnt; int err = 0; int i; QString ioname; // FXs if ((err = Card->getFXCount(&cnt)) < 0) return err; for (i = 0; i < cnt; i++) { if ((err = Card->getFX(i, ioname)) < 0) return err; StrFX *fx = findFXByNum(i); if (fx) { if (fx->name() != ioname) { fx->setName(ioname); fx->setFlagChanged(true); } // Don't make unconnected IO/FX disappear. fx->setFlagUsed(true); } else { fx = new StrFX(i, ioname); fx->setFlagNew(true); FXs.append(fx); } } if ((err = Card->getInputCount(&cnt)) < 0) return err; for (i = 0; i < cnt; i++) { if ((err = Card->getInput(i, ioname)) < 0) return err; StrInput *in = findInputByNum(i); if (in) { if (in->name() != ioname) { in->setName(ioname); in->setFlagChanged(true); } in->setFlagUsed(true); } else { in = new StrInput(i, ioname); in->setFlagNew(true); Inputs.append(in); } } if ((err = Card->getOutputCount(&cnt)) < 0) return err; for (i = 0; i < cnt; i++) { if ((err = Card->getOutput(i, ioname)) < 0) return err; StrOutput *out = findOutputByNum(i); if (out) { if (out->name() != ioname) { out->setName(ioname); out->setFlagChanged(true); } out->setFlagUsed(true); } else { out = new StrOutput(i, ioname); out->setFlagNew(true); Outputs.append(out); } } // load patches and patch registers CardParamPatchInfo **pi; if ((err = Card->getPatchesInfo(&pi, &cnt)) < 0) return err; // copy registers to internal structure for (i = 0; i < cnt; i++) { StrPatch *patch = NULL; if ((err = actualizePatch(pi[i]->id, pi[i]->patch_num, pi[i]->patch_name, &patch)) < 0) { for (i = 0; i < cnt; i++) delete pi[i]; delete pi; return err; } patch->setOrder(i); } for (i = 0; i < cnt; i++) delete pi[i]; delete pi; int *ld_tmplids = NULL; if ((err = Card->getPointsInfo(&ld_tmplids, &cnt)) < 0) return err; for (i = 0; i < cnt; i++) { StrLink *link = NULL; if ((err = actualizeLink(ld_tmplids[i], &link)) < 0) { free(ld_tmplids); return err; } } free(ld_tmplids); // copy used items StrPatch *patch; UsedItems.clear(); for(patch = Patches.first(); patch; patch = Patches.next() ) { if (patch->flagUsed()) UsedItems.append(patch); } // remove unused for(patch = Patches.last(); patch; patch = Patches.prev() ) { if (!patch->flagUsed()) Patches.remove(patch); } QPtrListIterator itin(Inputs); StrInput *in; while ((in = itin.current()) != 0 ) { ++itin; if (in->flagUsed()) UsedItems.append(in); else Inputs.remove(in); } QPtrListIterator itout(Outputs); StrOutput *out; while ((out = itout.current()) != 0 ) { ++itout; if (out->flagUsed()) UsedItems.append(out); else Outputs.remove(out); } QPtrListIterator itfx(FXs); StrFX *fx; while ((fx = itfx.current()) != 0 ) { ++itfx; if (fx->flagUsed()) UsedItems.append(fx); else FXs.remove(fx); } QPtrListIterator itlnk(Links); StrLink *lnk; while ((lnk = itlnk.current()) != 0 ) { ++itlnk; if (lnk->flagUsed()) UsedItems.append(lnk); else Links.remove(lnk); } updatePatchesOrder(); AutoArange(&UsedItems); QPtrListIterator itlnk1(Links); while ((lnk = itlnk1.current()) != 0 ) { ++itlnk1; lnk->calcSize(); } return 0; } int StrGlobal::getPio(int pnum, bool out, int idx, QString &name) { int err; if (out) err = Card->getPOutput(pnum, idx, name); else err = Card->getPInput(pnum, idx, name); return err; } int StrGlobal::actualizePatch(int pid, int pnum, QString pname, StrPatch **out) { QString ioname; int z, j; int err; int cnt1[2]; if ((err = Card->getPInputCount(pnum, &(cnt1[0]))) < 0) return err; if ((err = Card->getPOutputCount(pnum, &(cnt1[1]))) < 0) return err; StrPatch *patch = findPatchById(pid); if (patch) { // check changes if (patch->name() != pname) { patch->setName(pname); patch->setFlagChanged(true); } for (z = 0; z < 2; z++) { for (j = 0; j < cnt1[z]; j++) { if ((err = getPio(pnum, z, j, ioname)) < 0) return err; RSItemIO *io = patch->getIO(z, j); if (io->getDesc() != ioname) { io->setDesc(ioname); patch->setFlagChanged(true); } } } } else { patch = new StrPatch(pnum, pid, pname); Patches.append(patch); for (z = 0; z < 2; z++) { for (j = 0; j < cnt1[z]; j++) { if ((err = getPio(pnum, z, j, ioname)) < 0) return err; RSItemIO *io = new RSItemIO(patch, z, j, ioname); patch->setIO(z, j, io); } } patch->setFlagNew(true); } patch->setFlagUsed(true); *out = patch; return 0; } StrPatch *StrGlobal::findPatchByNum(int num) { StrPatch *patch; for(patch = Patches.first(); patch; patch = Patches.next() ) { if (patch->num() == num) return patch; } return NULL; } StrPatch *StrGlobal::findPatchById(int id) { StrPatch *patch; for(patch = Patches.first(); patch; patch = Patches.next() ) { if (patch->id() == id) return patch; } return NULL; } StrFX *StrGlobal::findFXByNum(int num) { StrFX *fx; for(fx = FXs.first(); fx; fx = FXs.next() ) { if (fx->num() == num) return fx; } return NULL; } StrInput *StrGlobal::findInputByNum(int num) { StrInput *in; for(in = Inputs.first(); in; in = Inputs.next() ) { if (in->num() == num) return in; } return NULL; } StrOutput *StrGlobal::findOutputByNum(int num) { StrOutput *out; for(out = Outputs.first(); out; out = Outputs.next() ) { if (out->num() == num) return out; } return NULL; } StrLink *StrGlobal::findLinkById(int id) { StrLink *l; for(l = Links.first(); l; l = Links.next() ) { if (l->id() == id) return l; } return NULL; } int StrGlobal::conAdd(bool multi, bool simple, RSItemIO *from_io, RSItemIO *to_io, int *id) { int ftype = 0; int ttype = 0; int type = 0; int fp = 0; int tp = 0; int p = 0; int fio = 0; int tio = 0; int io = 0; RSItemIO *tmp; RSItemBaseWithType *owner; for (int i = 0; i < 2; i++) { if (!i) tmp = from_io; else tmp = to_io; owner = (RSItemBaseWithType *)tmp->getOwner(); p = -1; io = -1; switch (owner->type()) { case RSItemBaseWithType::In: type = CON_IO_IN; io = ((StrInput *)owner)->num(); break; case RSItemBaseWithType::Out: type = CON_IO_OUT; io = ((StrOutput *)owner)->num(); break; case RSItemBaseWithType::FX: type = CON_IO_FX; io = ((StrFX *)owner)->num(); break; case RSItemBaseWithType::Patch: if (!tmp->isOutput()) type = CON_IO_PIN; else type = CON_IO_POUT; io = tmp->getIdx(); p = ((StrPatch *)owner)->num(); break; default: break; } if (!i) { ftype = type; fio = io; fp = p; } else { ttype = type; tio = io; tp = p; } } return Card->conAdd(multi, simple, ftype, fp, fio, ttype, tp, tio, id); // FIXME - uprava strglobal - urobene inde } int StrGlobal::conDel(RSItemIO *from_io, int *id) { int io, p; int type = 0; RSItemBaseWithType *owner; owner = (RSItemBaseWithType *)from_io->getOwner(); p = -1; io = -1; switch (owner->type()) { // only patch valid case RSItemBaseWithType::Patch: if (!from_io->isOutput()) type = CON_IO_PIN; else type = CON_IO_POUT; io = from_io->getIdx(); p = ((StrPatch *)owner)->num(); break; default: break; } return Card->conDel(type, p, io, id); } int StrGlobal::load(LD10k1File *ld10k1file, StrPatch *before, StrPatch **loaded) { int bef = -1; int loade, loade_id; int retval; if (before) bef = before->num(); if ((retval = Card->load(ld10k1file, bef, &loade, &loade_id)) < 0) return retval; StrPatch *p = NULL; if ((retval = actualizePatch(loade_id, loade, ld10k1file->getPatchName(), &p)) < 0) return retval; UsedItems.append(p); updatePatchesOrder(); AutoArange(&UsedItems); *loaded = p; return retval; } int StrGlobal::unload(StrPatch *p) { int retval; if ((retval = Card->unload(p->num())) < 0) return retval; // FIXME - odmaz aj prepojenia UsedItems.remove(p); Patches.remove(p); updatePatchesOrder(); return retval; } int StrGlobal::clearDSP(void) { int retval; if ((retval = Card->clearDSP()) < 0) return retval; clear(); return 0; } void StrGlobal::destroyLink(StrLink *l) { UsedItems.remove(l); l->disconnectAll(); // delete not needed - autodelete Links.remove(l); } int StrGlobal::disconnectFromLink(RSItemIO *io) { StrLink *link = io->getConnectedTo(); if (link) { int idx = link->findRoute(io); int conn_id; int err; if((err = conDel(io, &conn_id)) < 0) return err; link->setRoutePoint(idx, NULL); if (conn_id < 0 || !link->isValid()) { destroyLink(link); return 0; } link->calcSize(); } return 0; } int StrGlobal::actualizeLink(int id, StrLink **out) { int err; CardParamPointInfo point; err = Card->getPointInfo(id, &point); if (err == LD10K1_ERR_UNKNOWN_POINT) { // FIXME - probably not exists - remove StrLink *delLink = findLinkById(id); if (delLink) destroyLink(delLink); *out = NULL; return 0; } if (err < 0) return err; RSItemIO *firstItem = NULL; StrLink::LinkType newType = StrLink::LinkFX; switch(point.type) { case CON_IO_FX: newType = StrLink::LinkFX; { StrFX *ft = findFXByNum(point.io_idx); if (ft) firstItem = ft->getIO(true, 0); } break; case CON_IO_IN: newType = StrLink::LinkIn; { StrInput *in = findInputByNum(point.io_idx); if (in) firstItem = in->getIO(true, 0); } break; case CON_IO_OUT: newType = StrLink::LinkOut; { StrOutput *out = findOutputByNum(point.io_idx); if (out) firstItem = out->getIO(false, 0); } break; case CON_IO_NORMAL: newType = StrLink::LinkNormal; break; } StrLink *link = findLinkById(id); if (link) { bool actualized[POINTINFO_MAX_CONN_PER_POINT]; RSItemIO *newIOs[POINTINFO_MAX_CONN_PER_POINT]; unsigned int j; unsigned int niosc = 0; for (j = 0; j < POINTINFO_MAX_CONN_PER_POINT; j++) actualized[j] = false; int r = 0; if (firstItem) { actualized[r] = true; ((RSItemBaseWithType *)firstItem->getOwner())->setFlagUsed(true); r++; } // actualize current for (j = 0; j < point.conn_count; j++) { RSItemIO *io = findPatchIO(point.io_type[j], point.patch[j], point.io[j]); ((RSItemBaseWithType *)io->getOwner())->setFlagUsed(true); // find io int rf = link->findRoute(io); if (rf >= 0) { actualized[rf] = true; link->setRoutePoint(rf, io); } else { newIOs[niosc++] = io; } } // delete old for (j = 0; j < POINTINFO_MAX_CONN_PER_POINT; j++) { if (!actualized[j]) { link->setRoutePoint(j, NULL); link->clearRoutesPoints(j); } } // add new int l = 0; for (j = 0; j < niosc; j++) { for (; l < POINTINFO_MAX_CONN_PER_POINT; l++) { if (!link->getRoutePoint(l)) { link->setRoutePoint(l, newIOs[j]); break; } } } link->setFlagChanged(true); } else { link = new StrLink(id, newType); int r = 0; if (firstItem) { link->setRoutePoint(r++, firstItem); ((RSItemBaseWithType *)firstItem->getOwner())->setFlagUsed(true); } unsigned int j = 0; for (j = 0; j < point.conn_count; j++) { RSItemIO *io = findPatchIO(point.io_type[j], point.patch[j], point.io[j]); ((RSItemBaseWithType *)io->getOwner())->setFlagUsed(true); link->setRoutePoint(r++, io); } link->setFlagNew(true); Links.append(link); UsedItems.append(link); } link->setFlagUsed(true); *out = link; return 0; } void StrGlobal::updatePatchesOrder(void) { CardParamPatchInfo **pi; int i, cnt; int err; if ((err = Card->getPatchesInfo(&pi, &cnt)) < 0) return; for (i = 0; i < cnt; i++) { StrPatch *p = findPatchById(pi[i]->id); if (p) p->setOrder(i); } for (i = 0; i < cnt; i++) delete pi[i]; delete pi; } RSItemIO *StrGlobal::findPatchIO(bool out, int pid, int ionum) { if (pid < 0 || ionum < 0) return NULL; StrPatch *p = findPatchById(pid); if (!p) return NULL; return p->getIO(out, ionum); } int StrGlobal::deleteOneLink(StrLink *l) { int err; for (int i = 0; i < l->getMaxRoute(); i++) { RSItemIO *io = l->getRoutePoint(i); if (io) { RSItemBaseWithType *owner = (RSItemBaseWithType *)io->getOwner(); if (owner->type() == RSItemBaseWithType::Patch) { // only patch can be disconnected int conn_id; if((err = conDel(io, &conn_id)) < 0) return err; if (conn_id < 0) { destroyLink(l); return 0; } } } } return 0; } int StrGlobal::deleteOneFX(StrFX *fx) { int err; RSItemIO *io = fx->getIO(true, 0); if (io) { StrLink *l = io->getConnectedTo(); if (l) { if ((err = deleteOneLink(l)) < 0) return err; } } UsedItems.remove(fx); // delete not needed - autodelete FXs.remove(fx); return 0; } int StrGlobal::deleteOneIn(StrInput *in) { int err; RSItemIO *io = in->getIO(true, 0); if (io) { StrLink *l = io->getConnectedTo(); if (l) { if ((err = deleteOneLink(l)) < 0) return err; } } UsedItems.remove(in); // delete not needed - autodelete Inputs.remove(in); return 0; } int StrGlobal::deleteOneOut(StrOutput *out) { int err; RSItemIO *io = out->getIO(false, 0); if (io) { StrLink *l = io->getConnectedTo(); if (l) { if ((err = deleteOneLink(l)) < 0) return err; } } UsedItems.remove(out); // delete not needed - autodelete Outputs.remove(out); return 0; } int StrGlobal::deleteOnePatch(StrPatch *p) { int err; int z; int j; // store all conn ids QValueList actIds; actIds.clear(); for (z = 0; z < 2; z++) { for (j = 0; j < p->getMaxIOIdx(z); j++) { RSItemIO *io = p->getIO(z, j); if (io) { StrLink *l = io->getConnectedTo(); if (l && actIds.findIndex(l->id()) < 0) actIds.append(l->id()); } } } if ((err = unload(p)) < 0) return err; // actualize links for (unsigned int i = 0; i < actIds.count(); i++) { StrLink *link = NULL; int aid = actIds[i]; if ((err = actualizeLink(aid, &link)) < 0) return err; if (link) { if (!link->isValid()) destroyLink(link); else //wasn't error link->calcSize(); } } return 0; } int StrGlobal::deleteOneItem(RSItemBaseWithType *item) { switch (item->type()) { case RSItemBaseWithType::In: return deleteOneIn((StrInput *)item); case RSItemBaseWithType::Out: return deleteOneOut((StrOutput *)item); case RSItemBaseWithType::FX: return deleteOneFX((StrFX *)item); case RSItemBaseWithType::Link: return deleteOneLink((StrLink *)item); case RSItemBaseWithType::Patch: return deleteOnePatch((StrPatch *)item); default: return 0; } } int StrGlobal::deleteAllSelected() { int err; // through all selected RSItemBaseWithType *item; // first connections QPtrListIterator it1(UsedItems); while ((item = it1.current()) != 0 ) { ++it1; if (item->flagSelected() && item->type() == RSItemBaseWithType::Link) { if ((err = deleteOneLink((StrLink *)item)) < 0) return err; } } // everything others QPtrListIterator it2(UsedItems); while ((item = it2.current()) != 0 ) { ++it2; if (item->flagSelected()) { if ((err = deleteOneItem(item)) < 0) return err; } } return 0; } QString StrGlobal::errorStr(int err) { return Card->errorStr(err); } int StrGlobal::get(int patch_num, LD10k1File **dc) { return Card->get(patch_num, dc); } int StrGlobal::getDspConfig(LD10k1DspFile **dc) { return Card->getDspConfig(dc); } int StrGlobal::putDspConfig(LD10k1DspFile *dc) { return Card->putDspConfig(dc); } StrCardGlobal::StrCardGlobal() { // cards Cards.setAutoDelete( TRUE ); // the list owns the objects }