// ----------------------------------------------------------------------- // Is called when the select toolbar button is pressed. void QucsApp::slotSelect(bool on) { QWidget *w = DocumentTab->currentPage(); if(w->inherits("QTextEdit")) { ((TextDoc*)w)->viewport()->setFocus(); select->blockSignals(true); select->setOn(true); select->blockSignals(false); return; } // goto to insertWire mode if ESC pressed during wiring Schematic *Doc = (Schematic*)DocumentTab->currentPage(); if(MouseMoveAction == &MouseActions::MMoveWire2) { MouseMoveAction = &MouseActions::MMoveWire1; MousePressAction = &MouseActions::MPressWire1; Doc->viewport()->update(); view->drawn = false; select->blockSignals(true); select->setOn(false); select->blockSignals(false); return; } if(performToggleAction(on, select, 0, 0, &MouseActions::MPressSelect)) { MouseReleaseAction = &MouseActions::MReleaseSelect; MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; } }
void TestSchematic::testLuaTableSerialize(INodeDefManager *ndef) { static const v3s16 size(3, 3, 3); static const u32 volume = size.X * size.Y * size.Z; Schematic schem; schem.flags = 0; schem.size = size; schem.schemdata = new MapNode[volume]; schem.slice_probs = new u8[size.Y]; for (size_t i = 0; i != volume; i++) schem.schemdata[i] = MapNode(test_schem2_data[i], test_schem2_prob[i], 0); for (s16 y = 0; y != size.Y; y++) schem.slice_probs[y] = MTSCHEM_PROB_ALWAYS; std::vector<std::string> names; names.push_back("air"); names.push_back("default:lava_source"); names.push_back("default:glass"); std::ostringstream ss(std::ios_base::binary); UASSERT(schem.serializeToLua(&ss, names, false, 0)); UASSERTEQ(std::string, ss.str(), expected_lua_output); }
// place_schematic(p, schematic, rotation, replacement) int ModApiMapgen::l_place_schematic(lua_State *L) { Schematic schem; Map *map = &(getEnv(L)->getMap()); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); //// Read position v3s16 p = read_v3s16(L, 1); //// Read rotation int rot = ROTATE_0; if (lua_isstring(L, 3)) string_to_enum(es_Rotation, rot, std::string(lua_tostring(L, 3))); //// Read force placement bool force_placement = true; if (lua_isboolean(L, 5)) force_placement = lua_toboolean(L, 5); //// Read node replacements std::map<std::string, std::string> replace_names; if (lua_istable(L, 4)) read_schematic_replacements(L, replace_names, 4); //// Read schematic if (!get_schematic(L, 2, &schem, ndef, replace_names)) { errorstream << "place_schematic: failed to get schematic" << std::endl; return 0; } schem.placeStructure(map, p, 0, (Rotation)rot, force_placement, ndef); return 1; }
// create_schematic(p1, p2, probability_list, filename, y_slice_prob_list) int ModApiMapgen::l_create_schematic(lua_State *L) { INodeDefManager *ndef = getServer(L)->getNodeDefManager(); const char *filename = luaL_checkstring(L, 4); CHECK_SECURE_PATH_OPTIONAL(L, filename); Map *map = &(getEnv(L)->getMap()); Schematic schem; v3s16 p1 = check_v3s16(L, 1); v3s16 p2 = check_v3s16(L, 2); sortBoxVerticies(p1, p2); std::vector<std::pair<v3s16, u8> > prob_list; if (lua_istable(L, 3)) { lua_pushnil(L); while (lua_next(L, 3)) { if (lua_istable(L, -1)) { lua_getfield(L, -1, "pos"); v3s16 pos = check_v3s16(L, -1); lua_pop(L, 1); u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); prob_list.push_back(std::make_pair(pos, prob)); } lua_pop(L, 1); } } std::vector<std::pair<s16, u8> > slice_prob_list; if (lua_istable(L, 5)) { lua_pushnil(L); while (lua_next(L, 5)) { if (lua_istable(L, -1)) { s16 ypos = getintfield_default(L, -1, "ypos", 0); u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); slice_prob_list.push_back(std::make_pair(ypos, prob)); } lua_pop(L, 1); } } if (!schem.getSchematicFromMap(map, p1, p2)) { errorstream << "create_schematic: failed to get schematic " "from map" << std::endl; return 0; } schem.applyProbabilities(p1, &prob_list, &slice_prob_list); schem.saveSchematicToFile(filename, ndef); actionstream << "create_schematic: saved schematic file '" << filename << "'." << std::endl; lua_pushboolean(L, true); return 1; }
Schematic *load_schematic(lua_State *L, int index, INodeDefManager *ndef, StringMap *replace_names) { if (index < 0) index = lua_gettop(L) + 1 + index; Schematic *schem = NULL; if (lua_istable(L, index)) { schem = load_schematic_from_def(L, index, ndef, replace_names); if (!schem) { delete schem; return NULL; } } else if (lua_isnumber(L, index)) { return NULL; } else if (lua_isstring(L, index)) { schem = SchematicManager::create(SCHEMATIC_NORMAL); std::string filepath = lua_tostring(L, index); if (!fs::IsPathAbsolute(filepath)) filepath = ModApiBase::getCurrentModPath(L) + DIR_DELIM + filepath; if (!schem->loadSchematicFromFile(filepath, ndef, replace_names)) { delete schem; return NULL; } } return schem; }
// ----------------------------------------------------------------------- // Is called when the mouse is clicked upon the port toolbar button. void QucsApp::slotInsertPort(bool on) { editText->setHidden(true); // disable text edit of component property MouseReleaseAction = 0; MouseDoubleClickAction = 0; if(!on) { MouseMoveAction = 0; MousePressAction = 0; activeAction = 0; // no action active return; } if(activeAction) { activeAction->blockSignals(true); // do not call toggle slot activeAction->setOn(false); // set last toolbar button off activeAction->blockSignals(false); } activeAction = insPort; if(view->selElem) delete view->selElem; // delete previously selected component view->selElem = new SubCirPort(); Schematic *Doc = (Schematic*)DocumentTab->currentPage(); if(view->drawn) Doc->viewport()->update(); view->drawn = false; MouseMoveAction = &MouseActions::MMoveElement; MousePressAction = &MouseActions::MPressElement; }
// -------------------------------------------------------------- // Is called, when "Distribute horizontally" action is activated. void QucsApp::slotDistribHoriz() { editText->setHidden(true); // disable text edit of component property Schematic *Doc = (Schematic*)DocumentTab->currentPage(); Doc->distributeHorizontal(); Doc->viewport()->update(); view->drawn = false; }
// --------------------------------------------------------------------- // Is called when the "select markers" action is activated. void QucsApp::slotSelectMarker() { editText->setHidden(true); // disable text edit of component property Schematic *Doc = (Schematic*)DocumentTab->currentPage(); Doc->selectMarkers(); Doc->viewport()->update(); view->drawn = false; }
// --------------------------------------------------------------------- // Is called when the "select markers" action is triggered. void QucsApp::slotSelectMarker() { slotHideEdit(); // disable text edit of component property Schematic *Doc = (Schematic*)DocumentTab->currentWidget(); Doc->selectMarkers(); Doc->viewport()->update(); view->drawn = false; }
// -------------------------------------------------------------- // Is called, when "Distribute vertically" action is triggered. void QucsApp::slotDistribVert() { slotHideEdit(); // disable text edit of component property Schematic *Doc = (Schematic*)DocumentTab->currentWidget(); Doc->distributeVertical(); Doc->viewport()->update(); view->drawn = false; }
// -------------------------------------------------------------- // Is called, when "Center vertically" action is activated. void QucsApp::slotCenterVertical() { editText->setHidden(true); // disable text edit of component property Schematic *Doc = (Schematic*)DocumentTab->currentPage(); if(!Doc->aligning(5)) QMessageBox::information(this, tr("Info"), tr("At least two elements must be selected !")); Doc->viewport()->update(); view->drawn = false; }
// -------------------------------------------------------------- // Is called, when "Center horizontally" action is triggered. void QucsApp::slotCenterHorizontal() { slotHideEdit(); // disable text edit of component property Schematic *Doc = (Schematic*)DocumentTab->currentWidget(); if(!Doc->aligning(4)) QMessageBox::information(this, tr("Info"), tr("At least two elements must be selected !")); Doc->viewport()->update(); view->drawn = false; }
// ----------------------------------------------------------- void QucsApp::slotCursorRight() { if(!editText->isHidden()) return; // for edit of component property ? QPtrList<Element> movingElements; Schematic *Doc = (Schematic*)DocumentTab->currentPage(); int markerCount = Doc->copySelectedElements(&movingElements); if((movingElements.count() - markerCount) < 1) { if(markerCount > 0) { // only move marker if nothing else selected Doc->markerLeftRight(false, &movingElements); movingElements.clear(); } else { if(Doc->scrollRight(-Doc->horizontalScrollBar()->lineStep())) Doc->scrollBy(Doc->horizontalScrollBar()->lineStep(), 0); } Doc->viewport()->update(); view->drawn = false; return; } view->moveElements(&movingElements, Doc->GridX, 0); // move "GridX" to right view->MAx3 = 1; // sign for moved elements view->endElementMoving(Doc, &movingElements); }
// serialize_schematic(schematic, format, options={...}) int ModApiMapgen::l_serialize_schematic(lua_State *L) { NO_MAP_LOCK_REQUIRED; SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; //// Read options bool use_comments = getboolfield_default(L, 3, "lua_use_comments", false); u32 indent_spaces = getintfield_default(L, 3, "lua_num_indent_spaces", 0); //// Get schematic bool was_loaded = false; Schematic *schem = (Schematic *)get_objdef(L, 1, schemmgr); if (!schem) { schem = load_schematic(L, 1, NULL, NULL); was_loaded = true; } if (!schem) { errorstream << "serialize_schematic: failed to get schematic" << std::endl; return 0; } //// Read format of definition to save as int schem_format = SCHEM_FMT_MTS; const char *enumstr = lua_tostring(L, 2); if (enumstr) string_to_enum(es_SchematicFormatType, schem_format, std::string(enumstr)); //// Serialize to binary string std::ostringstream os(std::ios_base::binary); switch (schem_format) { case SCHEM_FMT_MTS: schem->serializeToMts(&os, schem->m_nodenames); break; case SCHEM_FMT_LUA: schem->serializeToLua(&os, schem->m_nodenames, use_comments, indent_spaces); break; default: return 0; } if (was_loaded) delete schem; std::string ser = os.str(); lua_pushlstring(L, ser.c_str(), ser.length()); return 1; }
// -------------------------------------------------------------- // Is called, when "Undo"-Button is pressed. void QucsApp::slotEditRedo() { Schematic *Doc = (Schematic*)DocumentTab->currentPage(); if(Doc->inherits("QTextEdit")) { ((TextDoc*)Doc)->viewport()->setFocus(); ((TextDoc*)Doc)->redo(); return; } editText->setHidden(true); // disable text edit of component property Doc->redo(); Doc->viewport()->update(); view->drawn = false; }
// -------------------------------------------------------------- // Is called, when "Undo"-Button is pressed. void QucsApp::slotEditRedo() { Schematic *Doc = (Schematic*)DocumentTab->currentWidget(); if(isTextDocument(Doc)) { ((TextDoc*)Doc)->viewport()->setFocus(); ((TextDoc*)Doc)->redo(); return; } slotHideEdit(); // disable text edit of component property Doc->redo(); Doc->viewport()->update(); view->drawn = false; }
// ----------------------------------------------------------------------- void QucsApp::slotEditPaste(bool on) { Schematic *Doc = (Schematic*)DocumentTab->currentPage(); if(Doc->inherits("QTextEdit")) { ((TextDoc*)Doc)->viewport()->setFocus(); ((TextDoc*)Doc)->paste(); editPaste->blockSignals(true); editPaste->setOn(false); // release toolbar button editPaste->blockSignals(false); return; } editText->setHidden(true); // disable text edit of component property if(!on) { MouseMoveAction = 0; MousePressAction = 0; MouseReleaseAction = 0; MouseDoubleClickAction = 0; activeAction = 0; // no action active if(view->drawn) Doc->viewport()->update(); return; } if(!view->pasteElements(Doc)) { editPaste->blockSignals(true); // do not call toggle slot editPaste->setOn(false); // set toolbar button off editPaste->blockSignals(false); return; // if clipboard empty } if(activeAction) { activeAction->blockSignals(true); // do not call toggle slot activeAction->setOn(false); // set last toolbar button off activeAction->blockSignals(false); } activeAction = editPaste; view->drawn = false; MouseMoveAction = &MouseActions::MMovePaste; view->movingRotated = 0; MousePressAction = 0; MouseReleaseAction = 0; MouseDoubleClickAction = 0; }
// ----------------------------------------------------------------------- // This function is called from all toggle actions. bool QucsApp::performToggleAction(bool on, QAction *Action, pToggleFunc Function, pMouseFunc MouseMove, pMouseFunc2 MousePress) { editText->setHidden(true); // disable text edit of component property if(!on) { MouseMoveAction = 0; MousePressAction = 0; MouseReleaseAction = 0; MouseDoubleClickAction = 0; activeAction = 0; // no action active return false; } Schematic *Doc = (Schematic*)DocumentTab->currentPage(); do { if(Function) if((Doc->*Function)()) { Action->blockSignals(true); Action->setOn(false); // release toolbar button Action->blockSignals(false); Doc->viewport()->update(); break; } if(activeAction) { activeAction->blockSignals(true); // do not call toggle slot activeAction->setOn(false); // set last toolbar button off activeAction->blockSignals(false); } activeAction = Action; MouseMoveAction = MouseMove; MousePressAction = MousePress; MouseReleaseAction = 0; MouseDoubleClickAction = 0; } while(false); // to perform "break" Doc->viewport()->update(); view->drawn = false; return true; }
int ModApiMapgen::l_place_schematic_on_vmanip(lua_State *L) { NO_MAP_LOCK_REQUIRED; SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; //// Read VoxelManip object MMVManip *vm = LuaVoxelManip::checkobject(L, 1)->vm; //// Read position v3s16 p = check_v3s16(L, 2); //// Read rotation int rot = ROTATE_0; const char *enumstr = lua_tostring(L, 4); if (enumstr) string_to_enum(es_Rotation, rot, std::string(enumstr)); //// Read force placement bool force_placement = true; if (lua_isboolean(L, 6)) force_placement = lua_toboolean(L, 6); //// Read node replacements StringMap replace_names; if (lua_istable(L, 5)) read_schematic_replacements(L, 5, &replace_names); //// Read schematic Schematic *schem = get_or_load_schematic(L, 3, schemmgr, &replace_names); if (!schem) { errorstream << "place_schematic: failed to get schematic" << std::endl; return 0; } bool schematic_did_fit = schem->placeOnVManip( vm, p, 0, (Rotation)rot, force_placement); lua_pushboolean(L, schematic_did_fit); return 1; }
// serialize_schematic(schematic, format, options={...}) int ModApiMapgen::l_serialize_schematic(lua_State *L) { SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; //// Read options NodeResolveMethod resolve_method = (NodeResolveMethod)getenumfield(L, 3, "node_resolve_method", es_NodeResolveMethod, NODE_RESOLVE_NONE); bool register_on_load = getboolfield_default(L, 3, "register_on_load", false); bool use_comments = getboolfield_default(L, 3, "use_lua_comments", false); //// Read schematic Schematic *schem = get_or_load_schematic(L, 1, schemmgr, NULL, register_on_load, resolve_method); if (!schem) { errorstream << "serialize_schematic: failed to get schematic" << std::endl; return 0; } //// Read format of definition to save as int schem_format = SCHEM_FMT_MTS; const char *enumstr = lua_tostring(L, 2); if (enumstr) string_to_enum(es_SchematicFormatType, schem_format, std::string(enumstr)); //// Serialize to binary string std::ostringstream os(std::ios_base::binary); switch (schem_format) { case SCHEM_FMT_MTS: schem->serializeToMts(&os); break; case SCHEM_FMT_LUA: schem->serializeToLua(&os, use_comments); break; default: return 0; } std::string ser = os.str(); lua_pushlstring(L, ser.c_str(), ser.length()); return 1; }
// place_schematic(p, schematic, rotation, replacement) int ModApiMapgen::l_place_schematic(lua_State *L) { MAP_LOCK_REQUIRED; GET_ENV_PTR; ServerMap *map = &(env->getServerMap()); SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; //// Read position v3s16 p = check_v3s16(L, 1); //// Read rotation int rot = ROTATE_0; const char *enumstr = lua_tostring(L, 3); if (enumstr) string_to_enum(es_Rotation, rot, std::string(enumstr)); //// Read force placement bool force_placement = true; if (lua_isboolean(L, 5)) force_placement = lua_toboolean(L, 5); //// Read node replacements StringMap replace_names; if (lua_istable(L, 4)) read_schematic_replacements(L, 4, &replace_names); //// Read schematic Schematic *schem = get_or_load_schematic(L, 2, schemmgr, &replace_names); if (!schem) { errorstream << "place_schematic: failed to get schematic" << std::endl; return 0; } schem->placeOnMap(map, p, 0, (Rotation)rot, force_placement); lua_pushboolean(L, true); return 1; }
// ----------------------------------------------------------- void QucsApp::slotCursorDown() { if(!editText->isHidden()) { // for edit of component property ? if(view->MAx3 == 0) return; // edit component namen ? Component *pc = (Component*)view->focusElement; Property *pp = pc->Props.at(view->MAx3-1); // current property int Pos = pp->Description.find('['); if(Pos < 0) return; // no selection list ? Pos = pp->Description.find(editText->text(), Pos); // current list item if(Pos < 0) return; // should never happen Pos = pp->Description.find(',', Pos); if(Pos < 0) return; // was last item ? Pos++; if(pp->Description.at(Pos) == ' ') Pos++; // remove leading space int End = pp->Description.find(',', Pos); if(End < 0) { // is last item ? End = pp->Description.find(']', Pos); if(End < 0) return; // should never happen } editText->setText(pp->Description.mid(Pos, End-Pos)); editText->selectAll(); return; } QPtrList<Element> movingElements; Schematic *Doc = (Schematic*)DocumentTab->currentPage(); int markerCount = Doc->copySelectedElements(&movingElements); if((movingElements.count() - markerCount) < 1) { if(markerCount > 0) { // only move marker if nothing else selected Doc->markerUpDown(false, &movingElements); movingElements.clear(); } else { if(Doc->scrollDown(-Doc->verticalScrollBar()->lineStep())) Doc->scrollBy(0, Doc->verticalScrollBar()->lineStep()); } Doc->viewport()->update(); view->drawn = false; return; } view->moveElements(&movingElements, 0, Doc->GridY); // move "GridY" down view->MAx3 = 1; // sign for moved elements view->endElementMoving(Doc, &movingElements); }
bool SES_AddNetLabel::updateLabel(Schematic& schematic, const Point& pos) noexcept { Q_ASSERT(mUndoCmdActive == true); try { // get netline under cursor QList<SI_NetLine*> lines = schematic.getNetLinesAtScenePos(pos); if (!lines.isEmpty()) mEditCmd->setNetSignal(lines.first()->getNetSignal(), true); mEditCmd->setPosition(pos, true); return true; } catch (Exception& e) { QMessageBox::critical(&mEditor, tr("Error"), e.getUserMsg()); return false; } }
// ----------------------------------------------------------- void QucsApp::slotCursorLeft(bool left) { int sign = 1; if(left){ sign = -1; } if(!editText->isHidden()) return; // for edit of component property ? Q3PtrList<Element> movingElements; Schematic *Doc = (Schematic*)DocumentTab->currentWidget(); int markerCount = Doc->copySelectedElements(&movingElements); if((movingElements.count() - markerCount) < 1) { if(markerCount > 0) { // only move marker if nothing else selected Doc->markerLeftRight(left, &movingElements); } else if(left) { if(Doc->scrollLeft(Doc->horizontalScrollBar()->singleStep())) Doc->scrollBy(-Doc->horizontalScrollBar()->singleStep(), 0); }else{ // right if(Doc->scrollRight(-Doc->horizontalScrollBar()->singleStep())) Doc->scrollBy(Doc->horizontalScrollBar()->singleStep(), 0); } Doc->viewport()->update(); view->drawn = false; return; } else { // random selection. move all of them view->moveElements(&movingElements, sign*Doc->GridX, 0); view->MAx3 = 1; // sign for moved elements view->endElementMoving(Doc, &movingElements); } }
// ----------------------------------------------------------- // Is called if user clicked on component text of if return is // pressed in the component text QLineEdit. // In "view->MAx3" is the number of the current property. void QucsApp::slotApplyCompText() { QString s; QFont f = QucsSettings.font; Schematic *Doc = (Schematic*)DocumentTab->currentPage(); f.setPointSizeFloat( Doc->Scale * float(f.pointSize()) ); editText->setFont(f); Property *pp = 0; Component *pc = (Component*)view->focusElement; if(!pc) return; // should never happen view->MAx1 = pc->cx + pc->tx; view->MAy1 = pc->cy + pc->ty; int z, n=0; // "n" is number of property on screen pp = pc->Props.first(); for(z=view->MAx3; z>0; z--) { // calculate "n" if(!pp) { // should never happen editText->setHidden(true); return; } if(pp->display) n++; // is visible ? pp = pc->Props.next(); } pp = 0; if(view->MAx3 > 0) pp = pc->Props.at(view->MAx3-1); // current property else s = pc->Name; if(!editText->isHidden()) { // is called the first time ? // no -> apply value to current property if(view->MAx3 == 0) { // component name ? Component *pc2; if(!editText->text().isEmpty()) if(pc->Name != editText->text()) { for(pc2 = Doc->Components->first(); pc2!=0; pc2 = Doc->Components->next()) if(pc2->Name == editText->text()) break; // found component with the same name ? if(!pc2) { pc->Name = editText->text(); Doc->setChanged(true, true); // only one undo state } } } else if(pp) { // property was applied if(pp->Value != editText->text()) { pp->Value = editText->text(); Doc->recreateComponent(pc); // because of "Num" and schematic symbol Doc->setChanged(true, true); // only one undo state } } n++; // next row on screen (view->MAx3)++; // next property pp = pc->Props.at(view->MAx3-1); // search for next property Doc->viewport()->update(); view->drawn = false; if(!pp) { // was already last property ? editText->setHidden(true); return; } while(!pp->display) { // search for next visible property (view->MAx3)++; // next property pp = pc->Props.next(); if(!pp) { // was already last property ? editText->setHidden(true); return; } } } // avoid seeing the property text behind the line edit if(pp) // Is it first property or component name ? s = pp->Value; editText->setMinimumWidth(editText->fontMetrics().width(s)+4); Doc->contentsToViewport(int(Doc->Scale * float(view->MAx1 - Doc->ViewX1)), int(Doc->Scale * float(view->MAy1 - Doc->ViewY1)), view->MAx2, view->MAy2); editText->setReadOnly(false); if(pp) { // is it a property ? s = pp->Value; view->MAx2 += editText->fontMetrics().width(pp->Name+"="); if(pp->Description.find('[') >= 0) // is selection list ? editText->setReadOnly(true); Expr_CompProp.setPattern("[^\"]*"); if(!pc->showName) n--; } else // it is the component name Expr_CompProp.setPattern("[\\w_]+"); Val_CompProp.setRegExp(Expr_CompProp); editText->setValidator(&Val_CompProp); z = editText->fontMetrics().lineSpacing(); view->MAy2 += n*z; editText->setText(s); editText->setPaletteBackgroundColor(QucsSettings.BGColor); editText->setFocus(); editText->selectAll(); editText->reparent(Doc->viewport(), 0, QPoint(view->MAx2, view->MAy2), true); }
bool SES_DrawWire::addNextNetPoint(Schematic& schematic, const Point& pos) noexcept { Q_ASSERT(mSubState == SubState_PositioningNetPoint); // abort if p2 == p0 (no line drawn) if (pos == mFixedStartAnchor->getPosition()) { abortPositioning(true); return false; } else { bool finishCommand = false; try { // create a new undo command group to make all changes atomic QScopedPointer<UndoCommandGroup> cmdGroup( new UndoCommandGroup("Add schematic netline")); // remove p1 if p1 == p0 || p1 == p2 if ((mPositioningNetPoint1->getPosition() == mFixedStartAnchor->getPosition()) || (mPositioningNetPoint1->getPosition() == mPositioningNetPoint2->getPosition())) { QScopedPointer<CmdSchematicNetSegmentRemoveElements> cmdRemove( new CmdSchematicNetSegmentRemoveElements( mPositioningNetPoint1->getNetSegment())); cmdRemove->removeNetPoint(*mPositioningNetPoint1); cmdRemove->removeNetLine(*mPositioningNetLine1); cmdRemove->removeNetLine(*mPositioningNetLine2); QScopedPointer<CmdSchematicNetSegmentAddElements> cmdAdd( new CmdSchematicNetSegmentAddElements( mPositioningNetPoint1->getNetSegment())); mPositioningNetLine2 = cmdAdd->addNetLine(*mFixedStartAnchor, *mPositioningNetPoint2); mUndoStack.appendToCmdGroup(cmdAdd.take()); mUndoStack.appendToCmdGroup(cmdRemove.take()); } // find anchor under cursor SI_NetLineAnchor* otherAnchor = nullptr; SI_NetSegment* otherNetSegment = nullptr; QString otherForcedNetName; if (SI_NetPoint* netpoint = findNetPoint(schematic, pos, mPositioningNetPoint2)) { otherAnchor = netpoint; otherNetSegment = &netpoint->getNetSegment(); } else if (SI_SymbolPin* pin = findSymbolPin(schematic, pos)) { otherAnchor = pin; otherNetSegment = pin->getNetSegmentOfLines(); // connect pin if needed if (!otherNetSegment) { Q_ASSERT(pin->getComponentSignalInstance()); mUndoStack.appendToCmdGroup(new CmdCompSigInstSetNetSignal( *pin->getComponentSignalInstance(), &mPositioningNetPoint2->getNetSignalOfNetSegment())); otherForcedNetName = pin->getComponentSignalInstance()->getForcedNetSignalName(); } } else if (SI_NetLine* netline = findNetLine(schematic, pos, mPositioningNetLine2)) { // split netline otherNetSegment = &netline->getNetSegment(); QScopedPointer<CmdSchematicNetSegmentAddElements> cmdAdd( new CmdSchematicNetSegmentAddElements(*otherNetSegment)); otherAnchor = cmdAdd->addNetPoint(pos); cmdAdd->addNetLine(*otherAnchor, netline->getStartPoint()); cmdAdd->addNetLine(*otherAnchor, netline->getEndPoint()); mUndoStack.appendToCmdGroup(cmdAdd.take()); // can throw QScopedPointer<CmdSchematicNetSegmentRemoveElements> cmdRemove( new CmdSchematicNetSegmentRemoveElements(*otherNetSegment)); cmdRemove->removeNetLine(*netline); mUndoStack.appendToCmdGroup(cmdRemove.take()); // can throw } // if anchor found under the cursor, replace "mPositioningNetPoint2" with // it if (otherAnchor) { if ((!otherNetSegment) || (otherNetSegment == &mPositioningNetPoint2->getNetSegment())) { QScopedPointer<CmdSchematicNetSegmentAddElements> cmdAdd( new CmdSchematicNetSegmentAddElements( mPositioningNetPoint2->getNetSegment())); cmdAdd->addNetLine(*otherAnchor, mPositioningNetLine2->getStartPoint()); mUndoStack.appendToCmdGroup(cmdAdd.take()); // can throw QScopedPointer<CmdSchematicNetSegmentRemoveElements> cmdRemove( new CmdSchematicNetSegmentRemoveElements( mPositioningNetPoint2->getNetSegment())); cmdRemove->removeNetPoint(*mPositioningNetPoint2); cmdRemove->removeNetLine(*mPositioningNetLine2); mUndoStack.appendToCmdGroup(cmdRemove.take()); // can throw } else { // change net signal if needed NetSignal* thisSignal = &mPositioningNetPoint2->getNetSignalOfNetSegment(); NetSignal* otherSignal = &otherNetSegment->getNetSignal(); if (thisSignal != otherSignal) { NetSignal* resultingNetSignal = nullptr; SI_NetSegment* netSegmentToChangeSignal = nullptr; if (otherNetSegment->getForcedNetNames().count() > 0) { resultingNetSignal = &otherNetSegment->getNetSignal(); netSegmentToChangeSignal = &mPositioningNetPoint2->getNetSegment(); } else if (mPositioningNetPoint2->getNetSegment() .getForcedNetNames() .count() > 0) { resultingNetSignal = &mPositioningNetPoint2->getNetSignalOfNetSegment(); netSegmentToChangeSignal = otherNetSegment; } else if (otherSignal->hasAutoName() && (!thisSignal->hasAutoName())) { resultingNetSignal = &mPositioningNetPoint2->getNetSignalOfNetSegment(); netSegmentToChangeSignal = otherNetSegment; } else { resultingNetSignal = &otherNetSegment->getNetSignal(); netSegmentToChangeSignal = &mPositioningNetPoint2->getNetSegment(); } mUndoStack.appendToCmdGroup( new CmdChangeNetSignalOfSchematicNetSegment( *netSegmentToChangeSignal, *resultingNetSignal)); } // combine both net segments mUndoStack.appendToCmdGroup(new CmdCombineSchematicNetSegments( mPositioningNetPoint2->getNetSegment(), *mPositioningNetPoint2, *otherNetSegment, *otherAnchor)); } if (!otherForcedNetName.isEmpty()) { // change net name if connected to a pin with forced net name try { CircuitIdentifier name = CircuitIdentifier(otherForcedNetName); // can throw NetSignal* signal = schematic.getProject().getCircuit().getNetSignalByName(*name); if (signal) { mUndoStack.appendToCmdGroup( new CmdChangeNetSignalOfSchematicNetSegment( mPositioningNetPoint2->getNetSegment(), *signal)); } else { QScopedPointer<CmdNetSignalEdit> cmd(new CmdNetSignalEdit( schematic.getProject().getCircuit(), mPositioningNetPoint2->getNetSignalOfNetSegment())); cmd->setName(name, false); mUndoStack.appendToCmdGroup(cmd.take()); } } catch (const Exception& e) { QMessageBox::warning( &mEditor, tr("Invalid net name"), QString( tr("Could not apply the forced net name because '%1' is " "not a valid net name.")) .arg(otherForcedNetName)); } } finishCommand = true; } else { finishCommand = false; } } catch (const UserCanceled& e) { return false; } catch (const Exception& e) { QMessageBox::critical(&mEditor, tr("Error"), e.getMsg()); return false; } try { // finish the current command mUndoStack.commitCmdGroup(); mSubState = SubState_Idle; // abort or start a new command if (finishCommand) { mUndoStack.beginCmdGroup(QString()); // this is ugly! abortPositioning(true); return false; } else { return startPositioning(schematic, pos, mPositioningNetPoint2); } } catch (const Exception& e) { QMessageBox::critical(&mEditor, tr("Error"), e.getMsg()); if (mSubState != SubState_Idle) { abortPositioning(false); } return false; } } }
// --------------------------------------------------------------- void LibraryDialog::slotSave() { stackedWidgets->setCurrentIndex(2); //message window libSaveName->setText(NameEdit->text() + ".lib"); ErrText->insert(tr("Saving library...")); if(!LibFile.open(QIODevice::WriteOnly)) { ErrText->append(tr("Error: Cannot create library!")); return; } QTextStream Stream; Stream.setDevice(&LibFile); Stream << "<Simgui Library " PACKAGE_VERSION " \"" << NameEdit->text() << "\">\n\n"; bool Success = true, ret; QString tmp; QTextStream ts(&tmp, QIODevice::WriteOnly); for (int i=0; i < SelectedNames.count(); i++) { ErrText->insert("\n=================\n"); QString description = ""; if(checkDescr->checkState() == Qt::Checked) description = Descriptions[i]; Stream << "<Component " + SelectedNames[i].section('.',0,0) + ">\n" << " <Description>\n" << description << "\n </Description>\n"; Schematic *Doc = new Schematic(0, SimguiSettings.SimguiWorkDir.filePath(SelectedNames[i])); ErrText->insert(tr("Loading subcircuit \"%1\".\n").arg(SelectedNames[i])); if(!Doc->loadDocument()) { // load document if possible delete Doc; ErrText->append(tr("Error: Cannot load subcircuit \"%1\"."). arg(SelectedNames[i])); break; } Doc->DocName = NameEdit->text() + "_" + SelectedNames[i]; Success = false; // save analog model tmp.truncate(0); Doc->isAnalog = true; ErrText->insert("\n"); ErrText->insert(tr("Creating Simgui netlist.\n")); ret = Doc->createLibNetlist(&ts, ErrText, -1); if(ret) { intoStream(Stream, tmp, "Model"); int error = 0; QStringList IFiles; SubMap::Iterator it = FileList.begin(); while(it != FileList.end()) { QString f = it.data().File; QString ifn, ofn; if(it.data().Type == "SCH") { ifn = f + ".lst"; ofn = ifn; } else if(it.data().Type == "CIR") { ifn = f + ".lst"; ofn = ifn; } if (!ifn.isEmpty()) error += intoFile(ifn, ofn, IFiles); it++; } FileList.clear(); if(!IFiles.isEmpty()) { Stream << " <ModelIncludes \"" << IFiles.join("\" \"") << "\">\n"; } Success = error > 0 ? false : true; } else { ErrText->insert("\n"); ErrText->insert(tr("Error: Cannot create netlist for \"%1\".\n").arg(SelectedNames[i])); } // save verilog model tmp.truncate(0); Doc->isVerilog = true; Doc->isAnalog = false; ErrText->insert("\n"); ErrText->insert(tr("Creating Verilog netlist.\n")); ret = Doc->createLibNetlist(&ts, ErrText, 0); if(ret) { intoStream(Stream, tmp, "VerilogModel"); int error = 0; QStringList IFiles; SubMap::Iterator it = FileList.begin(); while(it != FileList.end()) { QString f = it.data().File; QString ifn, ofn; if(it.data().Type == "SCH") { ifn = f + ".lst"; ofn = f + ".v"; } else if(it.data().Type == "VER") { ifn = f; ofn = ifn; } if (!ifn.isEmpty()) error += intoFile(ifn, ofn, IFiles); it++; } FileList.clear(); if(!IFiles.isEmpty()) { Stream << " <VerilogModelIncludes \"" << IFiles.join("\" \"") << "\">\n"; } Success = error > 0 ? false : true; } else { ErrText->insert("\n"); } // save vhdl model tmp.truncate(0); Doc->isVerilog = false; Doc->isAnalog = false; ErrText->insert(tr("Creating VHDL netlist.\n")); ret = Doc->createLibNetlist(&ts, ErrText, 0); if(ret) { intoStream(Stream, tmp, "VHDLModel"); int error = 0; QStringList IFiles; SubMap::Iterator it = FileList.begin(); while(it != FileList.end()) { QString f = it.data().File; QString ifn, ofn; if(it.data().Type == "SCH") { ifn = f + ".lst"; ofn = f + ".vhdl"; } else if(it.data().Type == "VHD") { ifn = f; ofn = ifn; } if (!ifn.isEmpty()) error += intoFile(ifn, ofn, IFiles); it++; } FileList.clear(); if(!IFiles.isEmpty()) { Stream << " <VHDLModelIncludes \"" << IFiles.join("\" \"") << "\">\n"; } Success = error > 0 ? false : true; } else { ErrText->insert("\n"); } Stream << " <Symbol>\n"; Doc->createSubcircuitSymbol(); Painting *pp; for(pp = Doc->SymbolPaints.first(); pp != 0; pp = Doc->SymbolPaints.next()) Stream << " <" << pp->save() << ">\n"; Stream << " </Symbol>\n" << "</Component>\n\n"; delete Doc; if(!Success) break; } // for LibFile.close(); if(!Success) { LibFile.remove(); ErrText->append(tr("Error creating library.")); return; } ErrText->append(tr("Successfully created library.")); }
// ----------------------------------------------------------- void QucsApp::slotCursorUp(bool up) { if(editText->isHidden()) { // for edit of component property ? }else if(up){ if(view->MAx3 == 0) return; // edit component namen ? Component *pc = (Component*)view->focusElement; Property *pp = pc->Props.at(view->MAx3-1); // current property int Begin = pp->Description.indexOf('['); if(Begin < 0) return; // no selection list ? int End = pp->Description.indexOf(editText->text(), Begin); // current if(End < 0) return; // should never happen End = pp->Description.lastIndexOf(',', End); if(End < Begin) return; // was first item ? End--; int Pos = pp->Description.lastIndexOf(',', End); if(Pos < Begin) Pos = Begin; // is first item ? Pos++; if(pp->Description.at(Pos) == ' ') Pos++; // remove leading space editText->setText(pp->Description.mid(Pos, End-Pos+1)); editText->selectAll(); return; }else{ // down if(view->MAx3 == 0) return; // edit component namen ? Component *pc = (Component*)view->focusElement; Property *pp = pc->Props.at(view->MAx3-1); // current property int Pos = pp->Description.indexOf('['); if(Pos < 0) return; // no selection list ? Pos = pp->Description.indexOf(editText->text(), Pos); // current list item if(Pos < 0) return; // should never happen Pos = pp->Description.indexOf(',', Pos); if(Pos < 0) return; // was last item ? Pos++; if(pp->Description.at(Pos) == ' ') Pos++; // remove leading space int End = pp->Description.indexOf(',', Pos); if(End < 0) { // is last item ? End = pp->Description.indexOf(']', Pos); if(End < 0) return; // should never happen } editText->setText(pp->Description.mid(Pos, End-Pos)); editText->selectAll(); return; } Q3PtrList<Element> movingElements; Schematic *Doc = (Schematic*)DocumentTab->currentWidget(); int markerCount = Doc->copySelectedElements(&movingElements); if((movingElements.count() - markerCount) < 1) { // all selections are markers if(markerCount > 0) { // only move marker if nothing else selected Doc->markerUpDown(up, &movingElements); } else if(up) { // nothing selected at all if(Doc->scrollUp(Doc->verticalScrollBar()->singleStep())) Doc->scrollBy(0, -Doc->verticalScrollBar()->singleStep()); } else { // down if(Doc->scrollDown(-Doc->verticalScrollBar()->singleStep())) Doc->scrollBy(0, Doc->verticalScrollBar()->singleStep()); } Doc->viewport()->update(); view->drawn = false; return; }else{ // some random selection, put it back view->moveElements(&movingElements, 0, ((up)?-1:1) * Doc->GridY); view->MAx3 = 1; // sign for moved elements view->endElementMoving(Doc, &movingElements); } }