예제 #1
0
bool NetworkGraphics::positionBranch(raw_address root, QPointF topLeft){
	if(!cloudAddrMap.contains(root)){
		return false;
	}

	GraphicNetCloud* cloud = getCloudByAddress(root);

	qDebug() << "NetworkGraphics::positionBranch - Moving cloud:" << cloud->getAddress().toString().c_str();

	QSizeF size = computeSize(root);
	qreal centerX = topLeft.x() + (size.width()/2.0);

	cloud->setY(topLeft.y());
	cloud->setX(centerX - (cloud->boundingRect().width() / 2.0));

	//Update to start in next row
	topLeft.setY(topLeft.y() + cloud->boundingRect().height());

	QMultiMap<uint8_t, raw_address> branch = network->getBranchAddresses(root);

	QList<uint8_t> keys = branch.uniqueKeys();

	if(keys.size() > 1){
	//for(int i=1; i<keys.size(); i++){
		QPointF cloudPos = topLeft;
		QList<GraphicNetCloud*> clouds = getCloudsByAddress(branch.values(keys[1]));
		qreal maxHeight = 0.0;

		for(int j=0; j<clouds.size(); j++){
			GraphicNetCloud* cloud = clouds[j];

			//cloud->setPos(cloudPos);

			QSizeF size = computeSize(cloud->getAddress());

			positionBranch(cloud->getAddress(), cloudPos);

			cloudPos.setX(cloudPos.x() + size.width());

			maxHeight = fmax(cloud->boundingRect().height(), maxHeight);
		}

		//topLeft.setY(topLeft.y() + maxHeight);
	}

	return true;
}
예제 #2
0
void ModelicaConnections::getOutside(ModItem* element,bool includeChildren,QStringList &uniquePorts, QList<QStringList> &outsideComps)
{
    QStringList listPorts;
    QStringList listOutsideComps;

    getOutside(element,includeChildren,listPorts,listOutsideComps);

    QMultiMap<QString,QString> map;
    for(int i=0;i<listPorts.size();i++)
    {
        map.insert(listPorts.at(i),listOutsideComps.at(i));
    }

    uniquePorts = map.uniqueKeys();
    outsideComps.clear();
    for(int i=0;i<uniquePorts.size();i++)
    {
        outsideComps.push_back(map.values(uniquePorts.at(i)));
    }
}
예제 #3
0
void PaletteTreeWidgets::refreshUserPalette(bool force)
{
	QList<QPair<QString, QList<gui::PaletteElement>>> groups;
	QMap<QString, QString> descriptions = { { mUserGroupTitle, mUserGroupDescription } };
	QList<gui::PaletteElement> groupElements;

	const QMultiMap<Id, Id> types = mMainWindow->models().exploser().explosions(mDiagram);
	for (const Id &source : types.uniqueKeys()) {
		for (const Id &target : types.values(source)) {
			const QString shape = mMainWindow->models().logicalRepoApi().stringProperty(target, "shape");
			QIcon icon;
			if (shape.isEmpty()) {
				icon = mEditorManager->icon(source);
			} else {
				QDomDocument doc;
				doc.setContent(shape);
				SdfIconEngineV2 * const engine = new SdfIconEngineV2(doc);
				icon = QIcon(engine);
			}

			groupElements << gui::PaletteElement(source
					, mMainWindow->models().logicalRepoApi().name(target)
					, QString(), icon
					, mEditorManager->iconSize(source)
					, target);
		}
	}

	if (!groupElements.isEmpty()) {
		groups << qMakePair(mUserGroupTitle, groupElements);
	}

	// This condition will filter out most of the cases.
	if (groupElements.toSet() != mUserTree->elementsSet() || force) {
		mUserTree->addGroups(groups, descriptions, true, mEditorManager->friendlyName(mDiagram), true);
	}

	if (groupElements.isEmpty()) {
		mUserTree->hide();
	}
}
예제 #4
0
QGridLayout* WidgetParameters::buildLayoutFromParameters()
{
    //Adding Layout
    QGridLayout *mainLayout = new QGridLayout(this);

    // get groups
    QMultiMap<QString,MOParameter*> groupmap = _localParameters->groupmap();
    QStringList groups = groupmap.uniqueKeys();


    QStringList paramNames;
    for(int i=0;i<_localParameters->size();i++)
        paramNames.push_back(_localParameters->at(i)->name());

    QPushButton *newPush;
    MOParameter* parameter;
    MOParameterListed *paramList;
    QList<MOParameter*> groupParameters;
    QGridLayout *curLayout;
    QGroupBox *curBox;

    // create group box
    for(int iG=0;iG<groups.size();iG++)
    {
        int iRow=0;
        if(groups.size()>1)
        {
            curBox = new QGroupBox(groups.at(iG),this);
            curLayout = new QGridLayout(curBox);
        }
        else
            curLayout = mainLayout;

        groupParameters = groupmap.values(groups.at(iG));

        // to reproduce parameters order, start from the end
        // it seems MultiMap behaves like a pile
        for(int iP=groupParameters.size()-1;iP>=0;iP--)
        {
            parameter = groupParameters.at(iP);
            // add setting
            QString dispName;
            if(parameter->name().contains("/"))
                dispName = parameter->name().section("/",1,-1);
            else
                dispName = parameter->name();

            curLayout->addWidget(new QLabel(parameter->description()),iRow,0);
            //boxLayout->addWidget(new QLabel(dispName),iRow,0);

            int type = parameter->getFieldValue(MOParameter::TYPE).toInt();
            QWidget *valueWidget;
            QVariant value = parameter->getFieldValue(MOParameter::VALUE);

            switch(type)
            {
            case MOParameter::STRING :
                valueWidget = new QLineEdit(this);
                ((QLineEdit*)valueWidget)->setText(value.toString());
                connect(((QLineEdit*)valueWidget),SIGNAL(textChanged(QString)),this,SLOT(onValueChanged()));
                break;
            case MOParameter::FILEPATH :
                valueWidget = new QLineEdit(this);
                ((QLineEdit*)valueWidget)->setText(value.toString());
                connect(((QLineEdit*)valueWidget),SIGNAL(textChanged(QString)),this,SLOT(onValueChanged()));
                // add button
                newPush = new QPushButton("...",this);
                newPush->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Preferred);
                _pathsMap.insert(newPush,((QLineEdit*)valueWidget));
                curLayout->addWidget(newPush,iRow,2);
                connect(newPush,SIGNAL(clicked()),this,SLOT(onSelectFileClicked()));
                break;
            case MOParameter::FOLDERPATH :
                valueWidget = new QLineEdit(this);
                ((QLineEdit*)valueWidget)->setText(value.toString());
                connect(((QLineEdit*)valueWidget),SIGNAL(textChanged(QString)),this,SLOT(onValueChanged()));
                //add button
                newPush = new QPushButton("...",this);
                newPush->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Preferred);
                _pathsMap.insert(newPush,((QLineEdit*)valueWidget));
                curLayout->addWidget(newPush,iRow,2);
                connect(newPush,SIGNAL(clicked()),this,SLOT(onSelectFolderClicked()));
                break;

            case MOParameter::DOUBLE :
                valueWidget = new QScienceSpinBox(this);
                ((QScienceSpinBox*)valueWidget)->setMinimum(parameter->getFieldValue(MOParameter::MIN).toDouble());
                ((QScienceSpinBox*)valueWidget)->setMaximum(parameter->getFieldValue(MOParameter::MAX).toDouble());
                ((QScienceSpinBox*)valueWidget)->setDecimals(10);
                ((QScienceSpinBox*)valueWidget)->setValue(value.toDouble());
                connect(((QScienceSpinBox*)valueWidget),SIGNAL(valueChanged(double)),this,SLOT(onValueChanged()));
                break;
            case MOParameter::INT :
                valueWidget = new QSpinBox(this);
                ((QSpinBox*)valueWidget)->setMinimum(parameter->getFieldValue(MOParameter::MIN).toInt());
                ((QSpinBox*)valueWidget)->setMaximum(parameter->getFieldValue(MOParameter::MAX).toInt());
                ((QSpinBox*)valueWidget)->setValue(value.toInt());
                connect(((QSpinBox*)valueWidget),SIGNAL(valueChanged(int)),this,SLOT(onValueChanged()));
                break;
            case MOParameter::BOOL :
                valueWidget = new QCheckBox(this);
                Qt::CheckState state;
                if(value.toBool())
                    state = Qt::Checked;
                else
                    state = Qt::Unchecked;
                connect(((QCheckBox*)valueWidget),SIGNAL(stateChanged(int)),this,SLOT(onValueChanged()));
                ((QCheckBox*)valueWidget)->setCheckState(state);
                break;
            case MOParameter::LIST :
                //if is a list, param should be a MOParameterListed
                valueWidget = new QComboBox(this);
                paramList = dynamic_cast<MOParameterListed*>(parameter);
                if(paramList)
                {
                    //adding list items in qcombobox
                    for(int iValue = 0 ; iValue<paramList->mapList().keys().size();iValue++)
                    {
                        ((QComboBox*)valueWidget)->addItem(
                                    paramList->mapList().values().at(iValue),
                                    paramList->mapList().keys().at(iValue));
                    }
                    // set current index
                    ((QComboBox*)valueWidget)->setCurrentIndex(((QComboBox*)valueWidget)->findData(value));
                    connect(((QComboBox*)valueWidget),SIGNAL(currentIndexChanged(int)),this,SLOT(onValueChanged()));
                }
                break;
            default :
                valueWidget = new QLineEdit(this);
                ((QLineEdit*)valueWidget)->setText(value.toString());
                connect(((QLineEdit*)valueWidget),SIGNAL(textChanged(QString)),this,SLOT(onValueChanged()));
                break;

            }

            curLayout->addWidget(valueWidget,iRow,1);
            valueWidget->setEnabled(_editable);

            // store (to save data when click ok)
            _mapValueWidgets.insert(parameter,valueWidget);
            _paramNames.push_back(parameter->name());
            _paramTypes.push_back(type);

            iRow++;
        }

        if(groups.size()>1)
        {
            curBox->setLayout(curLayout);
            mainLayout->addWidget(curBox);
        }
    }




    if(_editable)
        updateEnabled(); //update

    return mainLayout;
}
QList<ShopTemplateManager::ShopTemplateSection> ShopTemplateManager::FetchFromItemsKey(const QString &key, const Items &items, QHash<QString, QString> *options) {
    QList<ShopTemplateManager::ShopTemplateSection> result;
    if (items.size() > 0){
        Items matchingItems;

        bool includeNoBuyouts = options->contains("include.ignored");
        ShopTemplateContainType containType = CONTAIN_TYPE_NONE;

        if (key == "everything") {
            matchingItems = items;
        }
        else if (key.startsWith("stash:")) {
            int index = key.indexOf(":");
            QString name = (index + 1 >= key.length()) ? "" : key.mid(index + 1);
            if (!name.isEmpty()) {
                for (const std::shared_ptr<Item> &item : items) {
                    if (QString::fromStdString(item->location().GetLabel()).compare(name, Qt::CaseInsensitive) == 0) {
                        matchingItems.push_back(item);
                    }
                }
            }
        }
        else {
            Items pool = items;
            QStringList keyParts = key.split("+", QString::SkipEmptyParts);
            for (QString part : keyParts) {
                if (templateMatchers.contains(part)) {
                    matchingItems = FindMatchingItems(pool, part);
                }
                else {
                    // todo(novynn): phase these out? Prefer {Normal+Helmet} over {NormalHelmet}
                    bool matchedRarity = false;
                    const QStringList rarities = {"normal", "magic", "rare", "unique"};
                    for (QString rarity : rarities) {
                        if (part.startsWith(rarity)) {
                            QString type = part.mid(rarity.length());

                            matchingItems = FindMatchingItems(pool, rarity);
                            matchingItems = FindMatchingItems(matchingItems, type);
                            matchedRarity = true;
                        }
                    }

                    if (matchedRarity) continue;

                    if (part.endsWith("gems")) {
                        if (part == "gems" || part == "allgems") {
                            matchingItems = FindMatchingItems(pool, "gems");
                        }
                        else {
                            const QStringList gemTypes = {"AoE", "Attack", "Aura", "Bow", "Cast", "Chaining", "Chaos",
                                                          "Cold", "Curse", "Duration", "Fire", "Lightning", "Melee", "Mine", "Minion",
                                                          "Movement", "Projectile", "Spell", "Totem", "Trap", "Support"};
                            for (QString gemType : gemTypes) {
                                if (!part.startsWith(gemType, Qt::CaseInsensitive)) continue;

                                // This will never just be first key (?)
                                QString firstKey = gemType.toLower() + "gems";
                                matchingItems = FindMatchingItems(pool, firstKey);

                                if (part != firstKey) {
                                    // supportlightninggems
                                    QString secondKey = part.mid(gemType.length());
                                    matchingItems = FindMatchingItems(matchingItems, secondKey);
                                }
                            }
                        }
                    }
                }
                pool = matchingItems;
            }
        }

        // Only select items from your stash unless specified
        if (!options->contains("include.character")) {
            matchingItems = Items::fromStdVector(
                        from(matchingItems.toStdVector())
                        .where([](const std::shared_ptr<Item> item) { return item->location().type() == ItemLocationType::STASH; })
                        .toVector()
                     );
        }

        if (matchingItems.size() == 0)
            return result;

        if (containType == CONTAIN_TYPE_NONE && options->contains("wrap")) containType = CONTAIN_TYPE_WRAP;
        if (containType == CONTAIN_TYPE_NONE && options->contains("group")) containType = CONTAIN_TYPE_GROUP;

        switch (containType) {
            case (CONTAIN_TYPE_WRAP): {
                QString header = "Items";
                Buyout buyout = {};

                if (options->contains("header")) {
                    header = options->value("header");
                }

                const std::shared_ptr<Item> first = matchingItems.first();
                if (parent_->buyout_manager().Exists(*first)) buyout = parent_->buyout_manager().Get(*first);

                bool sameBuyout = from(matchingItems.toStdVector()).all([this, buyout](const std::shared_ptr<Item> item) {
                    Buyout thisBuyout = {};
                    if (parent_->buyout_manager().Exists(*item)) thisBuyout = parent_->buyout_manager().Get(*item);
                    return BuyoutManager::Equal(thisBuyout, buyout);
                });

                if (sameBuyout) {
                    header += BuyoutManager::Generate(buyout);
                }

                QStringList temp = WriteItems(matchingItems, !sameBuyout, includeNoBuyouts);
                if (!temp.isEmpty()) {
                    result << ShopTemplateSection(temp, SECTION_TYPE_SPOILER, header);
                }
                break;
            }
            case CONTAIN_TYPE_GROUP: {
                QMultiMap<QString, std::shared_ptr<Item>> itemsMap;

                for (auto &item : matchingItems) {
                    Buyout b = {};
                    if (parent_->buyout_manager().Exists(*item))
                        b = parent_->buyout_manager().Get(*item);
                    itemsMap.insert(BuyoutManager::Generate(b), item);
                }

                for (QString buyout : itemsMap.uniqueKeys()) {
                    Items itemList = itemsMap.values(buyout).toVector();
                    if (itemList.size() == 0)
                        continue;
                    QString header = buyout;
                    if (header.isEmpty()) header = "Offers Accepted";
                    QStringList temp = WriteItems(itemList, false, includeNoBuyouts);
                    if (temp.isEmpty())
                        continue;

                    result << ShopTemplateSection(temp, SECTION_TYPE_SPOILER, header);
                }
                break;
            }
            default: {
                QStringList temp = WriteItems(matchingItems, true, includeNoBuyouts);
                result << ShopTemplateSection(temp, SECTION_TYPE_NONE);
                break;
            }
        }
    }

    return result;
}
void tst_QWebPluginDatabase::preferredPlugin()
{
    QMultiMap<QString, QWebPluginInfo> pluginsMap;
    QWebPluginDatabase* database = QWebSettings::pluginDatabase();
    QList<QWebPluginInfo> plugins = database->plugins();

    for (int i = 0; i < plugins.count(); ++i) {
        QWebPluginInfo plugin = plugins.at(i);

        QList<MimeType> mimeTypes = plugin.mimeTypes();
        for (int j = 0; j < mimeTypes.count(); ++j) {
            QString mimeType = mimeTypes.at(j).name;
            pluginsMap.insert(mimeType, plugin);
        }
    }

    QMultiMap<QString, QWebPluginInfo>::iterator it = pluginsMap.begin();
    while (it != pluginsMap.end()) {
        QString mimeType = it.key();

        if (pluginsMap.count(mimeType) > 1) {
            QList<QWebPluginInfo> pluginsForMimeType = pluginsMap.values(mimeType);
            QWebPluginInfo plugin = database->pluginForMimeType(mimeType);
            QVERIFY(plugin.supportsMimeType(mimeType));

            pluginsForMimeType.removeAll(plugin);
            for (int i = 0; i < pluginsForMimeType.count(); ++i) {
                QWebPluginInfo anotherPlugin = pluginsForMimeType.at(i);
                QVERIFY(plugin.supportsMimeType(mimeType));
                QVERIFY(plugin != anotherPlugin);

                QCOMPARE(database->pluginForMimeType(mimeType), plugin);
                database->setPreferredPluginForMimeType(mimeType, anotherPlugin);
                QCOMPARE(database->pluginForMimeType(mimeType), anotherPlugin);

                anotherPlugin.setEnabled(false);
                QCOMPARE(database->pluginForMimeType(mimeType), plugin);

                anotherPlugin.setEnabled(true);
                QCOMPARE(database->pluginForMimeType(mimeType), anotherPlugin);
                database->setSearchPaths(database->searchPaths());
                QCOMPARE(database->pluginForMimeType(mimeType), anotherPlugin);

                database->setPreferredPluginForMimeType(mimeType, QWebPluginInfo());
                QCOMPARE(database->pluginForMimeType(mimeType), plugin);
            }
        } else {
            QWebPluginInfo plugin = database->pluginForMimeType(mimeType);
            QCOMPARE(pluginsMap.value(mimeType), plugin);

            database->setPreferredPluginForMimeType(mimeType, plugin);
            QCOMPARE(database->pluginForMimeType(mimeType), plugin);

            plugin.setEnabled(false);
            QCOMPARE(database->pluginForMimeType(mimeType), QWebPluginInfo());
            plugin.setEnabled(true);

            database->setPreferredPluginForMimeType(mimeType, QWebPluginInfo());
            QCOMPARE(database->pluginForMimeType(mimeType), plugin);
        }

        ++it;
    }

    if (pluginsMap.keys().count() >= 2) {
        QStringList mimeTypes = pluginsMap.uniqueKeys();

        QString mimeType1 = mimeTypes.at(0);
        QString mimeType2 = mimeTypes.at(1);
        QWebPluginInfo plugin1 = database->pluginForMimeType(mimeType1);
        QWebPluginInfo plugin2 = database->pluginForMimeType(mimeType2);

        int i = 2;
        while (plugin2.supportsMimeType(mimeType1)
               && !mimeType2.isEmpty()
               && i < mimeTypes.count()) {
            mimeType2 = mimeTypes.at(i);
            plugin2 = database->pluginForMimeType(mimeType2);
            ++i;
        }

        plugin1 = database->pluginForMimeType(mimeType1);
        QVERIFY(plugin1.supportsMimeType(mimeType1));
        QVERIFY(!plugin1.isNull());
        plugin2 = database->pluginForMimeType(mimeType2);
        QVERIFY(plugin2.supportsMimeType(mimeType2));
        QVERIFY(!plugin2.isNull());

        database->setPreferredPluginForMimeType(mimeType2, plugin1);
        QVERIFY(!plugin1.supportsMimeType(mimeType2));
        QCOMPARE(database->pluginForMimeType(mimeType2), plugin2);

        database->setPreferredPluginForMimeType(mimeType1, plugin1);
        QVERIFY(!plugin2.supportsMimeType(mimeType1));
        QCOMPARE(database->pluginForMimeType(mimeType2), plugin2);
    }
}
예제 #7
0
void NetTree::fillTree()
{
    // First let's add all the RSS

    m_rssGeneric = new MythGenericTree(
                    RSSNode, kSubFolder, false);

    // Add an upfolder
    if (m_type != DLG_TREE)
    {
          m_rssGeneric->addNode(QString(tr("Back")), kUpFolder, true, false);
    }

    m_rssGeneric->SetData(QString("%1/mythnetvision/icons/rss.png")
         .arg(GetShareDir()));

    RSSSite::rssList::iterator i = m_rssList.begin();
    for (; i != m_rssList.end(); ++i)
    {
        ResultItem::resultList items =
                   getRSSArticles((*i)->GetTitle(), VIDEO_PODCAST);
        MythGenericTree *ret = new MythGenericTree(
                   (*i)->GetTitle(), kSubFolder, false);
        ret->SetData(qVariantFromValue(*i));
        m_rssGeneric->addNode(ret);

        // Add an upfolder
        if (m_type != DLG_TREE)
        {
            ret->addNode(QString(tr("Back")), kUpFolder, true, false);
        }

        ResultItem::resultList::iterator it = items.begin();
        for (; it != items.end(); ++it)
        {
            AddFileNode(ret, *it);
        }
    }

    if (m_rssList.count() > 0)
        m_siteGeneric->addNode(m_rssGeneric);
    else
    {
        delete m_rssGeneric;
        m_rssGeneric = NULL;
    }

    // Now let's add all the grabber trees

    for (GrabberScript::scriptList::iterator i = m_grabberList.begin();
            i != m_grabberList.end(); ++i)
    {

        QMultiMap<QPair<QString,QString>, ResultItem*> treePathsNodes =
                           getTreeArticles((*i)->GetTitle(), VIDEO_FILE);

        QList< QPair<QString,QString> > paths = treePathsNodes.uniqueKeys();

        MythGenericTree *ret = new MythGenericTree(
                   (*i)->GetTitle(), kSubFolder, false);
        QString thumb = QString("%1mythnetvision/icons/%2").arg(GetShareDir())
                            .arg((*i)->GetImage());
        ret->SetData(qVariantFromValue(thumb));

        // Add an upfolder
        if (m_type != DLG_TREE)
        {
            ret->addNode(QString(tr("Back")), kUpFolder, true, false);
        }

        for (QList<QPair<QString, QString> >::iterator i = paths.begin();
                i != paths.end(); ++i)
        {
            QStringList curPaths = (*i).first.split("/");
            QString dirthumb = (*i).second;
            QList<ResultItem*> videos = treePathsNodes.values(*i);
            buildGenericTree(ret, curPaths, dirthumb, videos);
        }
        m_siteGeneric->addNode(ret);
    }
}
예제 #8
0
void Optimization::createSubExecs(QList<QList<ModModelPlus*> > & subModels, QList<BlockSubstitutions*> & subBlocks)
{

    subModels.clear();
    subBlocks.clear();

    QMultiMap<QString,QString> map; // <orgComponent,subcomponent>
    QMap<QString,QString> mapModel; //<orgComponent,model>
    // fill map
    for(int i=0; i < _blockSubstitutions->getSize();i++)
    {
        BlockSubstitution *curBlockSub = _blockSubstitutions->getAt(i);
        if(!curBlockSub->_subComponent.isEmpty())
        {
            map.insert(curBlockSub->_orgComponent,curBlockSub->_subComponent);
            mapModel.insert(curBlockSub->_orgComponent,curBlockSub->_model);
        }
    }

    int nbOrgs = map.uniqueKeys().size();
    //adding non-moving cases for each orgComponent
    for(int i = 0; i<nbOrgs; i ++)
    {
        map.insert(map.uniqueKeys().at(i),map.uniqueKeys().at(i));
    }


    //build first index and maximum index
    QList<int> index, maxIndex;
    nbOrgs = map.uniqueKeys().size();
    for(int i = 0; i<nbOrgs; i ++)
    {
        index.push_back(0);
        QList<QString> subs = map.values(map.uniqueKeys().at(i));
        maxIndex.push_back(subs.size()-1);
    }


    QStringList models = mapModel.values();
    models.removeDuplicates();



    // storing genuine mo file paths
    QStringList oldMoFilePaths;
    for(int iM=0;iM<models.size();iM++)
    {
        oldMoFilePaths.push_back(_omProject->modModelPlus(models.at(iM))->moFilePath());
    }



    int iCase=0;
    bool oneChange;
    while(!index.isEmpty())
    {


        // Display case (for debug)
        QString msg = "CASE " + QString::number(iCase) + "\n";
        for(int i=0; i < index.size(); i++)
        {
            msg += map.uniqueKeys().at(i);
            msg += " -> ";
            msg += map.values(map.uniqueKeys().at(i)).at(index.at(i));
            msg+=",";
        }
        msg.remove(msg.size()-1,1);
        msg +="\n \n";
        InfoSender::instance()->debug(msg);


        // create folder
        QString newName = "case_"+QString::number(iCase);
        QString newFolder = saveFolder()+ QDir::separator() + "SubModels" + QDir::separator() + newName;
        QDir dir(saveFolder());
        dir.mkpath(newFolder);
        QDir newDir(newFolder);


        // clone mo files and load them
        // and create corresponding modmodelplus
        QStringList newMoPaths;
        QStringList newMmoPaths;
        QMap<QString,ModModelPlus*> newModModels;
        for(int iM=0;iM<oldMoFilePaths.size();iM++)
        {
            QFileInfo oldMoFileInfo(oldMoFilePaths.at(iM));
            QFile oldMoFile(oldMoFilePaths.at(iM));

            QString newMoPath = newDir.filePath(oldMoFileInfo.fileName());
            QString newMmoPath = newMoPath;
            newMmoPath = newMmoPath.replace(".mo",".mmo");

            newDir.remove(newMoPath);
            oldMoFile.copy(newMoPath);

            newMoPaths.append(newMoPath);
            newMmoPaths.append(newMmoPath);


            // load file (! will replace previously loaded)
            _omProject->loadMoFile(newMoPath,false,true);

            // create new modModelPlus
            ModModelPlus* newModModelPlus = new ModModelPlus(_omProject,models.at(iM));
            newModModelPlus->setMmoFilePath(newMmoPath);
            newModModels.insert(models.at(iM),newModModelPlus);
        }


        // apply blocksubs
        BlockSubstitutions *curSubBlocks = new BlockSubstitutions();

        QMap<QString,bool> changes; // <model,hasChanged>
        changes.clear();
        for(int i=0; i<index.size();i++)
        {
            QString replacedComp = map.uniqueKeys().at(i);
            QString replacingComp = map.values(map.uniqueKeys().at(i)).at(index.at(i));

            if(replacedComp != replacingComp)
            {
                BlockSubstitution* blockSub = _blockSubstitutions->find(replacedComp,replacingComp);
                if(blockSub)
                {
                    ModModelPlus* corrNewModModelPlus = newModModels.value(blockSub->_model);
                    oneChange =  corrNewModModelPlus->applyBlockSub(blockSub,true) || oneChange ;
                    curSubBlocks->push_back(blockSub);
                    changes.insert(blockSub->_model,true);
                }
            }
        }

        QStringList modelsToCompile = changes.keys(true);// those which have been modified
        bool compilationOk = true;
        for(int iM=0;iM<modelsToCompile.size();iM++)
        {
            ModModelPlus* modelPlus = newModModels.value(modelsToCompile.at(iM));
            compilationOk = modelPlus->compile(ctrl(modelsToCompile.at(iM))) && compilationOk;
        }

        if(compilationOk)
        {

            // store subModel and subBlocks
            subModels.push_back(newModModels.values());
            subBlocks.push_back(curSubBlocks);
            _foldersToCopy << newFolder;

            InfoSender::instance()->send( Info(ListInfo::SUBMODELADDED,newName));
        }
        else
        {
            InfoSender::instance()->send( Info(ListInfo::SUBMODELNOTADDED,newName));
        }


        iCase++;
        index = LowTools::nextIndex(index,maxIndex);
    }

    // reload genuine mo file
    if(iCase>0)
    {
        for(int i=0;i<oldMoFilePaths.size();i++)
            _omProject->loadMoFile(oldMoFilePaths.at(i),false,true);
    }
}