// Verwaltung von Brückenklemmen (nur für Devices KLEMME*BRUECKE in Bibliothek e-klemmen.lbr) // Gate-Namen der Brücken-Devices müssen alphabetisch so geordnet sein, dass ihre Pins // der Reihe nach 1.x, 2.x etc. sind // todo // Anzeigen, welcher Klemmenblock gerade bearbeitet wird string Version = "Version 1.01"; // History // 1.01 -- 2009-10-01 // nicht benötigte "\t\t" in Kopfzeilen von dlgDialog() entfernt // #require 4.9206 #usage "Brückenklemmen-Verwaltung: Brücken eintragen und ändern\n

" "Brückenklemmen sind Bauteile mit Einzelklemmen, die jeweils zwei Kontakte " "mit Anschlussmöglichkeit für Drähte haben. Zusätzlich können die Klemmen " "untereinander mit gesteckten Brückenkämmen o.ä. verbunden werden. Mit diesem " "User-Language-Programm (ULP) definieren Sie auf bequeme Weise, welche Klemmen " "innerhalb eines Klemmenblocks gebrückt werden sollen. Die Brückendefinitionen " "werden als Liste in einer Datei (schaltungsname.brk) ausgegeben. Außerdem " "wird eine Log-Datei (schaltungsname.log) angelegt, aus der mögliche Probleme " "hervorgehen. Die Log-Datei wird gelöscht, nachem die EAGLE-Sitzung beendet ist.

" "Die erzeugte Liste (schaltungsname.brk) kann in einem Tabellenkalkulationsprogramm " "weiter verarbeitet oder mit Hilfe von e-makelist.ulp direkt in die " "Schaltungszeichnung importiert werden.

" "Author: support@cadsoft.de" ///////////////////////////////////////////////////////////////////////////////// // Vom Benutzer zu ändern: // Wenn verdrahteten Verbindungen keine Verweise bekommen sollen, setzen Sie den // Wert für ExcludeDrahtverbindungen in der folgenden Zeile auf 1; int ExcludeDrahtverbindungen = 0; ///////////////////////////////////////////////////////////////////////////////// string s, cmd, f, LogCmd, DoCmd, ListCmd; string PartDatabase[], CurrentPart; numeric string ChangeString, SheetsUsedInEdit[]; int maxklemmen, LogOn, ErrOn, CurrentPartIndex; string scrfile, listfile, errorfile, pinfile, vbdfile, klpfile, kapfile, brpfile, pfad; numeric string sh, PartPin, SigName, col, row, PartName, PinName; numeric string pindatabase[], b[]; string PartPinSep = " "; int YRef[]; int distY, netnr, n, i; // Debug string DebugString; // Variablen für main int SelAll = -1, SelConnected = -1, Sort = 0, SortAll = 0, NrLinesListAll; numeric string listall[], listsel[], listundo[], listundoOben[]; string h[]; // Header-Variablen ------------------------------------------------------------------------------------------- string head [], SelParam[], ChangeParam[]; int NrHeader; // Zahl der Rubriken // head [] enthält ListHeader-Einträge: // head[Draehte].. v enum {Draehte, Bruecken}; numeric string ListHeader = "Drähte \tBrücken"; enum {Name, Anz, Verwendet, Verdrahtet}; numeric string ListHeaderMain = "Name\tAnz.\tVerwendet\tVerdrahtet"; // Ende Header-Variablen -------------------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////////////////////////// string HelpText = "Brückenklemmen-Verwaltung: Brücken eintragen und ändern

" "Brückenklemmen sind Bauteile mit Einzelklemmen, die jeweils zwei Kontakte " "mit Anschlussmöglichkeit für Drähte haben. Zusätzlich können die Klemmen " "untereinander mit gesteckten Brückenkämmen o.ä. verbunden werden. Mit diesem " "User-Language-Programm (ULP) definieren Sie auf bequeme Weise, welche Klemmen " "innerhalb eines Klemmenblocks gebrückt werden sollen. Die Brückendefinitionen " "werden als Liste in einer Datei (schaltungsname.brk) ausgegeben. Außerdem " "wird eine Log-Datei (schaltungsname.log) angelegt, aus der mögliche Probleme " "hervorgehen. Die Log-Datei wird gelöscht, nachem die EAGLE-Sitzung beendet ist.
" "Die erzeugte Liste (schaltungsname.brk) kann in einem Tabellenkalkulationsprogramm " "weiter verarbeitet oder mit Hilfe von e-makelist.ulp direkt in die " "Schaltungszeichnung importiert werden.

" "Klemmenbibliothek

" "Dieses Programm berücksichtigt nur Brückenklemmen, wie sie in der " "Bibliothek e-klemmen.lbr unter den Device-Namen KLEMME*BRUECKE definiert sind. " "In der Schaltung muss der Bauteilname mit X beginnen, und in der Bibliothek " "muss der Namensbestandteil BRUECKE vorhanden sein. " "In der Bibliothek e-klemmen.lbr befinden sich vordefinierte Brückenklemmen. " "Bitte lesen Sie die Bibliotheksbeschreibung (z.B. im Control-Panel), wenn Sie " "eigene Brückenklemmen definieren wollen.

" "Prinzip

" "Klemmen werden behandelt, wie jedes andere Bauteil auch: Kontakte, die mit " "anderen verbunden sind, erscheinen im Klemmenplan. Eine Verbindung entsteht, " "wenn die Kontakte über eine Netzlinie verbunden sind oder wenn an den Kontakten " "jeweils ein Netz mit gleichem Namen hängt. Letzteres ist insbesondere dann " "der Fall, wenn Kontakte auf unterschiedlichen Schaltplanseiten verbunden sind.

" "Brückenklemmen bieten darüber hinaus eine weitere Möglichkeit, Verbindungen " "innerhalb desselben Klemmenblocks zu definieren. Man bringt einen " "Verweis (Referenz) im Brückenklemmen-Symbol an, der auf die vorherige bzw. nächste " "Klemme zeigt, mit der die Klemme verbunden werden soll. Damit vermeidet man ein " "Wirrwarr von gezeichneten Brücken bei größeren Plänen. Die Verweise verwenden " "Attribute, die in der Bibliothek festgelegt sind. Der Benutzer hat damit aber " "nichts zu tun, solange er für die Definition der Brücken dieses ULP verwendet.

" "Was steht im Klemmenplan und im Brückenplan?

" "Der Klemmenplan stellt alle Draht- und Kabelverbindungen in einer Liste dar. " "Der Brückenplan enthält die (üblicherweise mit Brückenkämmen ausgeführten) " "Verbindungen innerhalb eines Klemmenblocks, die mit Hilfe dieses Programms " "erstellt wurden.

" "Werden Kontakte eines Brückenklemmenblocks über ein Netz verbunden, erscheint diese " "Verbindung im Klemmenplan als Drahtverbindung. Sie sollten das dann tun, wenn " "Sie darauf hinweisen wollen, dass hier tatsächlich ein Draht von einer Klemme " "zur anderen verlegt werden soll.

" "Werden Kontakte eines Brückenklemmenblocks über Klemmen-Referenzen (mit diesem " "Programm) verbunden, erscheint diese Verbindung im Brückenplan (ebenso wie " "Verbindungen zwischen unterschiedlichen Klemmenblöcken, etwa eine Klemme " "von X1 mit einer von X2).

" "Falls Kontakte auf beide Arten verbunden sind (was keinen Sinn macht), " "erscheinen sie im Klemmenplan und im Brückenplan.

" "Wie werden Brücken im Stromlaufplan dargestellt?

" "Im Brückenklemmen-Symbol weisen (maximal) zwei Zahlen auf die nächsten Klemmen hin, " "mit denen es verbunden ist. Da Referenzverbindungen nicht über die Draht-Anschlüsse " "realisiert werden, erscheint als Referenz nicht der jeweilige Kontaktname " "(1.1, 1.2 etc.), sondern die Klemmennummer (1, 2, 3 etc.). Klemme 5 etwa " "ist die Klemme mit den Kontakten 5.1 und 5.2.

" "Beispiel: In einem Block mit sechs Einzelklemmen, sollen die Klemmen 1, 3 und 5 " "miteinander verbunden sein: Klemme 1 verweist auf 3, Klemme 3 verweist auf 1 und 5, " "und Klemme 5 verweist auf Klemme 3.

" "Bedienung

" "In jeder Programmsitzung können Sie nur die Brücken eines Klemmenblocks (also etwa X1) " "bearbeiten.

" "Typischer Ablauf einer Programmsitzung:

" "Log-Datei: Dieser Button öffnet ein Textfenster, in dem Sie die vorhandenen " "Draht- und Referenz-Brücken sowie Warnungen zu eventuellen Fehlern finden.

" "Doppelklick auf obere Liste: Wählen Sie den zu bearbeitenden Klemmenblock. " "Dargestellt sind die Anzahl und die Nummern der in der Schaltung platzierten " "Klemmen sowie die Klemmen, die mit Drähten (Netzen) verbunden sind. " "Mit dem Doppelklick wird dieser Klemmenblock in die untere Liste zur Bearbeitung " "übertragen.

" "Untere Liste: Links sind Drahtverbindungen dargestellt, sie können nicht " "verändert werden (nur in der Schaltung). Rechts sind die Einzelbrücken " "in jeweils einer Zeile dargestellt.

" "Doppelklick auf untere Liste: Die verbundenen Klemmen einer Einzelbrücke " "wandern in das Editier-Fenster (Verbinden). Dort können Sie eintragen, " "welche Klemmen verbunden werden sollen (durch Leerzeichen getrennt). " "Die Eingabetaste oder ein Klick auf Anwenden ändert die selektierte " "Zeile entsprechend. Falls Sie Klemmen gewählt haben, die nicht in der " "Schaltung platziert sind, erscheint eine Fehlermeldung.

" "Speichern: Dieser Button beendet das Programm und führt die Änderungen " "an der zuletzt bearbeiteten Klemme durch. Der aktuelle Brückenplan " "wird als schaltungsname.brk abgespeichert, zusätzlich die Log-Datei " "(*.log) und eine Script-Datei (*.scr), aus der die EAGLE-Befehle zur Änderung " "der Referenzen hervorgehen. Um den endgültigen Brückenplan für ihre " "Projektunterlagen zu erstellen, sollten Sie das Programm starten und " "ohne eine Änderung durchzuführen den Button Speichern betätigen, dann " "ist die Liste richtig sortiert.

" "Undo: Dieser Button bringt nach einer Änderung den letzten Zustand in die " "untere Liste (nur eine Undo-Stufe).

" "Unbenutzte: Dieser Button bringt alle Klemmen in das Editier-Feld, die " "als Eingabe möglich sind, da sie gegenwärtig keiner anderen Brücke angehören. " "Am besten, sie betätigen diesen Button und löschen dann die Klemmen heraus, " "die nicht mit der zu erstellenden Brücke verbunden werden sollen.

" "Löschen: Löscht eine komplette Brückenzeile.

" "Neu: Erzeugt eine neue Brückenzeile, in die Sie den Inhalt des Editier-Fensters " "übertragen können.

" "Abbrechen: Programm ohne Änderungen verlassen." ; //////////////////////////////////////////////////////////////////////////////////////////////////// void SetFileNames(void) { // in Schematic-Kontext aufrufen if (!schematic) { // dlgMessageBox("Dieses Programm muss vom Schaltplan-Editor aus aufgerufen werden"); exit(1); } schematic(SCH) { scrfile = filesetext(SCH.name, ".scr"); errorfile = filesetext(SCH.name, ".log"); listfile = filesetext(SCH.name, ".brk"); } } string StripWhiteSpace(string s) { // mit Zusatz: Doppel-Whitespaces im Inneren werden 1 Whitespace int i, n; string t; while (s && isspace(s[0])) s = strsub(s, 1); while (s && isspace(s[strlen(s) - 1])) s = strsub(s, 0, strlen(s) - 1); // Doppel-Blanks for (i = 0; i < strlen(s); i++) { if (!isspace(s[i])) t[n++] = s[i]; else { if ((strlen(s) > i+1) && isspace(s[i+1])); else t[n++] = s[i]; }; } s = t; return s; } string SortBlankSeparatedString(string s) { int nb; numeric string b[]; s = StripWhiteSpace(s); nb = strsplit(b, s, ' '); sort(nb, b); s = strjoin(b, ' '); return s; } // Lösche Mehrfacheinträge aus blanksepariertem String und sortiere string DelMultiples(string st) { string s, h[], ht[]; int i, n, np; st = SortBlankSeparatedString(st); np = strsplit(h, st, ' '); for (i = 0; i < np; i++) { ht[n] = h[i]; if (ht[n] == h[i+1]) { i++; } n++; } s = strjoin(ht, ' '); return StripWhiteSpace(s); } // Liefert einen kommaseparierten String mit allen verdrahteten Brücken eines Klemmenblocks // Für Log werden die Brücken nach Netzen getrennt ausgegeben string GetConnectedOnePart(string pname) { int klnr, nrnetpins; string s, t, connects, allconnects; schematic(SCH) { SCH.nets(N) { nrnetpins = 0; N.pinrefs(P) { if (P.part.name == pname && P.pin.contact) { nrnetpins++; if (nrnetpins == 2) { sprintf(s, "%s\tNetz: %s\tKlemmen: ", P.part.name, N.name); LogCmd += s; break; } } } t = ""; connects = ""; nrnetpins = 0; N.pinrefs(P) { s = ""; if (P.part.name == pname && P.pin.contact) { if(strtol(P.pin.contact.pad.name)) klnr = strtol(P.pin.contact.pad.name); else sprintf(s, "\n%s: Fehler in Bibliothek! Pad-Name muss mit Ziffer beginnen!\n", P.pin.contact.pad.name); LogCmd += s; sprintf(s, "%d ", klnr); connects += s; t += s; // nur wegen \n nrnetpins++; } } if (nrnetpins == 1) connects = ""; // nur ein Pin an Netz LogCmd += SortBlankSeparatedString(connects); if (t && nrnetpins > 1) LogCmd += "\n"; allconnects += " " + connects; } } return SortBlankSeparatedString(allconnects); } void PackListsel (int ix, int pos, string s) { int np; if (ix < 0 || pos < 0) return; numeric string h[]; strsplit(h, listsel[ix], '\t'); h[pos] = s; listsel[ix] = strjoin(h, '\t'); } string UnpackListsel (int ix, int pos) { if (ix < 0) return ""; numeric string h[]; strsplit(h, listsel[ix], '\t'); return h[pos]; } void PackListall (int ix, int pos, string s) { int np; if (ix < 0 || pos < 0) return; numeric string h[]; strsplit(h, listall[ix], '\t'); h[pos] = s; listall[ix] = strjoin(h, '\t'); } string UnpackListall (int ix, int pos) { if (ix < 0) return ""; numeric string h[]; strsplit(h, listall[ix], '\t'); return h[pos]; } int IsInBlankStr (string item, string st) { // ist item in blanksep. String st vorhanden? int i, np; numeric string h[]; st = StripWhiteSpace(st); np = strsplit(h, st, ' '); for (i = 0; i < np; i++) { if (item == h[i]) return 1; } return 0; } // Löscht Edit-Liste void DelListsel(void) { for (i = 0; i < maxklemmen; i++) { listsel[i] = ""; } } // Ref-Verbindungen für Editierliste erstellen: blank/tab separated string (ordered) // 1 2 5 \n 4 6 Zeilen mit \t getrennt string GetConnectedRefwise(string pname){ numeric string s, sa, klemmenused[], ku, c1, c2, bridges[], h[], lastline[], prevline[]; int i, j, k, u, v, w, np, np1, np2, bx, found; schematic(SCH) { SCH.sheets(SH) { SH.parts(P) { if (P.name == pname) { if (LogOn) LogCmd += P.name + " "; np = strsplit(klemmenused, StripWhiteSpace(lookup(PartDatabase, P.name, "Verwendet", '\t')) ,' '); i = 0; bx = 0; found = 0;// Brückenindex, trennt Einzelpotentiale for (i = 0; i < np; i++) { ku = klemmenused[i]; c1 = P.attribute[klemmenused[i]+"1"]; c2 = P.attribute[klemmenused[i]+"2"]; if (P.attribute[klemmenused[i]+"1"] || P.attribute[klemmenused[i]+"2"]) { sprintf(s, "%d: %s %s %s\n", bx, ku, c1, c2); sprintf(s, "%s %s %s", ku, c1, c2); if (StripWhiteSpace(s)) bridges[bx++] = StripWhiteSpace(s); } } // bx Zahl der Klemmen mit Ref (höchster Index ist bx-1); max drei Klemmen pro Eintrag for (j = bx-1; j > 0; j--) { // Fasse Potentiale in bridges[] zusammen np1 = strsplit(lastline, bridges[j], ' '); // bis zu drei Klemmen in lastline v = j - 1; while (v >= 0) { // vorherige Zeilen strsplit(prevline, bridges[v], ' '); w = 0; while(prevline[w]) { u = 0; while (lastline[u]) { if (lastline[u] == prevline[w]) { bridges[v] += " " + StripWhiteSpace(bridges[j]); bridges[j] = ""; found = 1; break; } u++; } if (found) break; w++; } v--; } } // Ende Zusammenfassen der Potentiale (Mehrfacheinträge hier noch möglich) i = 0; n = 0; while (h[i]) h[i++] = ""; for (i = 0; i < maxklemmen; i++) { if (StripWhiteSpace(bridges[i])){ h[n] = DelMultiples(bridges[i]); n++; } } sort(n, h); i = 0; s = ""; while (StripWhiteSpace(h[i])) { h[i] = DelMultiples(h[i]); s += h[i] + "\n"; if (LogOn) LogCmd += " : " + h[i]; i++; } if (LogOn) LogCmd += "\n"; } } } } return s; } // Editier-Liste (Drähte) für einen Klemmenblock erstellen: blank/tab separated string (ordered) // 1 2 5 \n 4 6 Zeilen mit \t getrennt string GetConnectedNetwise(string pname){ int klnr, nrnetpins; string s, t, connects, allconnects; schematic(SCH) { SCH.nets(N) { t = ""; connects = ""; nrnetpins = 0; N.pinrefs(P) { s = ""; if (P.part.name == pname && P.pin.contact) { klnr = strtol(P.pin.contact.pad.name); // trennt .x ab von x.x sprintf(s, "%d ", klnr); connects += s; t += s; // t nur wegen \n erforderlich nrnetpins++; } } connects = SortBlankSeparatedString(connects); if (nrnetpins == 1) connects = ""; // nur ein Pin an Netz if (t && nrnetpins > 1) { allconnects += connects + "\n"; } } } return allconnects; } // Ermittelt Wired-Brücken an und schreibt Log nach Startvorgang // Part \t Klemmen // wobei Klemmen blanksepariert sind (alle fest verdrahteten Klemmen) // z. B.: X1 1 3 4 5 9 void GetConnectedAllParts(void) { int i, np; string h[]; LogCmd += "---------------------------------------------------------------------------------------------\n"; LogCmd += "Mit Netzen realisierte Brücken: nicht mit diesem ULP zu verändern!\n"; LogCmd += "---------------------------------------------------------------------------------------------\n"; while (listall[i]) { np = strsplit(h, listall[i], '\t'); // Wired Connections h[Verdrahtet] = DelMultiples((GetConnectedOnePart(h[Name]))); listall[i] = strjoin(h, '\t'); i++; } LogCmd += "---------------------------------------------------------------------------------------------\n"; LogCmd += "Mit Referenzen realisierte Brücken: mit diesem ULP zu verändern!\n"; LogCmd += "---------------------------------------------------------------------------------------------\n"; // Ref Connections i = 0; while (listall[i]) { np = strsplit(h, listall[i], '\t'); LogOn = 1; GetConnectedRefwise(h[Name]); LogOn = 0; i++; } LogCmd += "---------------------------------------------------------------------------------------------\n"; } int CheckOKBridgeLine(string st) { // lässt nur in schematic vorhandene Klemmen zu int i, np; string s, h[]; s = StripWhiteSpace(st); if (st == "") return 1; char c; for (i = 0; i < strlen(s); i++) { c = s[i]; if (isdigit(c) || c == ' ') { } else return 0; } np = strsplit(h, st, ' '); if (np == 1) return 0; for (i = 0; i < np; i++) { if (!IsInBlankStr(h[i], UnpackListall(CurrentPartIndex, Verwendet))) { return 0; } } return 1; } void MakeEditListOnePart(int Sel) { int i, ErrPrinted; string wirelines[], reflines[], h[], x[]; if (Sel < 0) return; strsplit(h, listall[Sel], '\t'); CurrentPartIndex = Sel; CurrentPart = h[Name]; DelListsel(); strsplit(wirelines, GetConnectedNetwise(h[Name]), '\n'); // alle Br. als Einzelzeilen strsplit(reflines, GetConnectedRefwise(h[Name]), '\n'); // alle Br. als Einzelzeilen while(wirelines[i] || reflines[i]) { listsel[i] = DelMultiples(wirelines[i]) + "\t" + DelMultiples(reflines[i]); if (!CheckOKBridgeLine(reflines[i])) { if (ErrOn && !ErrPrinted) { dlgMessageBox( "Unzulässige Brückenbezeichnung, siehe Log-Liste!

" "Bitte tragen Sie in die Brückenzeilen nur erlaubte Bezeichnungen ein " "und speichern Sie das Ergebnis ab!" ); ErrPrinted = 1; } if (!ErrOn) if (strsplit(x, reflines[i], ' ') == 1) LogCmd += UnpackListall(Sel, Name) + ": " + reflines[i] + "\tNur ein Klemmenverweis (min. 2 erforderlich)!\n"; else LogCmd += UnpackListall(Sel, Name) + ": " + reflines[i] + "\tNicht alle Klemmen in Schaltung vorhanden!\n"; } i++; } return; } // void MakeEditListPerName(string pname) { // int i; // pname = StripWhiteSpace(pname); // while (UnpackListall(i, Name)) { // if (pname == UnpackListall(i, Name)) { // MakeEditListOnePart(i); // SelAll = i; // return; // } // i++; // } // dlgMessageBox("Kein Klemmenblock mit diesem Namen vorhanden!

"); // return; // } // Sammle Brückenklemmen (Part-Name: X...; Device-Name: ..BRUECKE..) // Fülle obere Liste und lege identische Datenbank mit Header an (PartDatabase[]) void CollectX(void) { numeric string s, s1, s2, s3, sh0, sh; int i, n; PartDatabase[0] = ListHeaderMain + "\tSeite"; schematic(SCH) { SCH.sheets(SH) { SH.parts(P) { if (strchr(P.name, 'X') == 0) { if (strstr(P.device.name, "BRUECKE") >= 0) { n = 0; sprintf(s, "%s\t", P.name); P.instances(I) { n++; } maxklemmen = max(maxklemmen, n); sprintf(s1, "%d\t", n); listall[i] = s + s1; s3 = ""; P.instances(I) { s3 += I.gate.name + " "; } sh = ""; P.instances(I) { sprintf(sh, "%d ", SH.number); // sheets } listall[i] += StripWhiteSpace(s3) + "\t" + DelMultiples(sh); PartDatabase[i+1] = listall[i] + "\t" + DelMultiples(sh); // LogCmd += PartDatabase[i] + "\n"; i++; } } } } } } void PushUndo(void) { int i; while (listundo[i]) { listundo[i] = ""; i++; } i = 0; while (listsel[i]) { listundo[i] = listsel[i]; i++; } } void PullUndo(void) { int i; while (listsel[i]) { listsel[i] = ""; i++; } i = 0; while (listundo[i]) { listsel[i] = listundo[i]; i++; } } void ShowLog(void) { dlgDialog("Brückendaten aus der Schaltung") { dlgHBoxLayout dlgSpacing(600); dlgHBoxLayout{ dlgTextEdit(LogCmd); } dlgHBoxLayout { } dlgHBoxLayout { dlgStretch(1); dlgPushButton("&Hilfe") dlgMessageBox( "Die Liste gibt Hinweise auf mögliche Probleme beim Einlesen\n" "der Brückenverbindungen." ); dlgPushButton("+OK") dlgAccept(); } }; } // liefert alle a, die nicht in b sind; a,b und return-Wert sind blanksep. Strings string AllAnotinB(string a, string b) { int i, na; numeric string ha[]; a = StripWhiteSpace(a); b = StripWhiteSpace(b); na = strsplit(ha, a, ' '); a = ""; for (i = 0; i < na; i++) { if (!IsInBlankStr(ha[i], b)) { a += ha[i] + " "; } } return StripWhiteSpace(a); } string GetUnused(int Sel) { // liefert unbenutzte Klemmen als blanksep. String int i, n; string h[], s, usedB, usedD, t; // von Brücken benutzt; von Drähten benutzt if (Sel < 0 || CurrentPartIndex < 0) return ""; PushUndo(); s = UnpackListall(CurrentPartIndex, Verwendet); while (listsel[i]) { if (Sel != i) usedB += UnpackListsel(i, Bruecken) + " "; usedD += UnpackListsel(i, Draehte) + " "; i++; } s = AllAnotinB(s, usedB); if (ExcludeDrahtverbindungen) s += " " + AllAnotinB(s, usedD); return StripWhiteSpace(s); } int CheckOKChangeString(string st) { // lässt nur solche zu, die noch nicht in anderer Br. verwendet int i, np; string s, h[]; s = StripWhiteSpace(st); char c; for (i = 0; i < strlen(s); i++) { c = s[i]; if (isdigit(c) || c == ' ') { } else return 0; } np = strsplit(h, st, ' '); if (np == 1) return 0; for (i = 0; i < np; i++) { if (!IsInBlankStr(h[i], GetUnused(SelConnected))) { return 0; } } return 1; } void ClearGarbageListsel() { // löscht leere Einträge am Ende von listsel int i; while (listsel[i]) { if (UnpackListsel(i, Draehte) == "" && UnpackListsel(i, Bruecken) == "") listsel[i] = ""; i++; } } // Lösche eine Verbindung aus Auswahlliste void DelOneEntry(int Sel) { int i, n, imax; string x[]; PushUndo(); if (Sel < 0) return; SelConnected = -1; while(UnpackListsel(i, Bruecken)) i++; // # Einträge feststellen imax = i; for (i = 0; i < imax; i++) { if (i <= Sel) { x[i] = UnpackListsel(i, Bruecken); } else { x[i-1] = UnpackListsel(i, Bruecken); } } if (imax != 0) PackListsel(imax-1, Bruecken, ""); if (Sel == 0 && imax == 0) { PackListsel(0, Bruecken, ""); } else { imax = imax -1; for (i = 0; i < imax; i++) { PackListsel(i, Bruecken, x[i]); } } if (Sel > 0) SelConnected = Sel-1; else SelConnected = 0; ClearGarbageListsel(); // entferne leere Zeilen aus listsel } void CreateBridge(void) { int i; while(UnpackListsel(i, Bruecken)) i++; // # Einträge feststellen PackListsel(i, Bruecken, ""); ChangeString = ""; SelConnected = i; } void EditOneEntry(int Sel) { string h[]; if (Sel < 0) return; strsplit(h, listsel[Sel], '\t'); ChangeString = SortBlankSeparatedString(h[Bruecken]); } void TransferEditLine (int Sel) { string h[]; if (Sel < 0) return; PushUndo(); if (StripWhiteSpace(ChangeString) == "") { DelOneEntry(Sel); return; } ChangeString = SortBlankSeparatedString(ChangeString); if (CheckOKChangeString(ChangeString)) { PackListsel(Sel, Bruecken, ChangeString); } else dlgMessageBox("Ungültige Klemmennummern im Editier-Feld!

" "Erlaubt sind Klemmennummern, die in der selektierten Brücke verwendet wurden, " "aber in keiner anderen (nur Leerzeichen und 0-9).

" "Es müssen mindestens zwei Klemmen eingetragen sein."); } void WriteAttributeLog(void) { int i; string s; ErrOn = 0; LogCmd += "Warnungen! - Falsche Verweise\n"; LogCmd += "---------------------------------------------------------------------------------------------\n"; while (listall[i]) { SelAll = i; CurrentPartIndex = i; MakeEditListOnePart(i); i++; } SelAll = 0; CurrentPartIndex = 0; MakeEditListOnePart(0); ErrOn = 1; } string MakeList (void) { // aktuelle Brückenliste erstellen int i, j, k; string h[], b[], BrkCmd, s; BrkCmd += "Name\tBrücken\n"; while (listall[i]) { strsplit(h, listall[i], '\t'); // hole Bauteilnamen LogOn = 0; BrkCmd += h[Name] + "\t"; strsplit (b, GetConnectedRefwise(h[Name]), '\n'); // h: 1 2 3 \t 2 4 if (CurrentPartIndex == i) { k = 0; while (UnpackListsel(k, Bruecken)) { b[k] = UnpackListsel(k, Bruecken); k++; } b[k] = ""; } j = 0; s = ""; while (b[j]) { // Einzelbrücken // hier ev. aus 1 2 3 4 5 -> 1-5 if (!s) s += b[j] + " "; else s += " : " + b[j]; j++; } // s = strjoin(b, ':'); BrkCmd += s + "\n"; i++; } return BrkCmd; } int CancelOk(void) { int CancelOk; dlgDialog("Programm verlassen") { dlgHBoxLayout dlgSpacing(400); dlgHBoxLayout { dlgTextView ( "Wenn Sie das Programm abbrechen, verlieren Sie alle Änderungen!\n\n" "Abbrechen?" ); } dlgHBoxLayout { dlgStretch(1); dlgPushButton("+Nein") dlgReject(); dlgPushButton("-Ja") {CancelOk = 1; dlgAccept();} } }; if (CancelOk) return 1; else return 0; } void SaveList(void) { int i, k, np; string line, klemme[], h[], sht, pname; DoCmd = ""; // if (SelConnected < 0) { // dlgMessageBox( "Sie müssen erst eine Zeile im unteren Fenster selektieren!

"); // return; // } strsplit(h, listall[CurrentPartIndex], '\t'); pname = h[Name]; sht = lookup(PartDatabase, pname, "Seite", '\t'); LogCmd += "---------------------------------------------------------------------------------------------\n"; LogCmd += "Befehle zum Eintragen der neuen Verweise\n"; LogCmd += "---------------------------------------------------------------------------------------------\n"; DoCmd += "edit .s" + sht + ";\n"; DoCmd += "change display off;\n"; line = StripWhiteSpace(UnpackListall(CurrentPartIndex, Verwendet)); np = strsplit(klemme, line, ' '); for (k = 0; k < np; k++) { // alle Attr. der verwendeten Klemmen löschen DoCmd += "change display off;\n"; DoCmd += "attribute " + pname + " " + klemme[k] + "1 " + "'';\n"; DoCmd += "change display off;\n"; DoCmd += "attribute " + pname + " " + klemme[k] + "2 " + "'';\n"; } i = 0; k = 0; while (StripWhiteSpace(UnpackListsel(i, Bruecken))) { // alle Brückenzeilen in Att. eintragen line = StripWhiteSpace(UnpackListsel(i, Bruecken)); np = strsplit(klemme, line, ' '); for (k = 1; k < np; k++) { // alle Klemmen pro Brücke DoCmd += "change display off;\n"; DoCmd += "attribute " + pname + " " + klemme[k-1] + "2 " + "'" + klemme[k] + "';\n"; } for (k = np - 2; k >= 0; k--) { // alle Klemmen pro Brücke DoCmd += "change display off;\n"; DoCmd += "attribute " + pname + " " + klemme[k+1] + "1 " + "'" + klemme[k] + "';\n"; } i++; } LogCmd += DoCmd; LogCmd += "---------------------------------------------------------------------------------------------\n"; output(errorfile, "wtD") printf("%s", LogCmd); output(scrfile, "wtD") printf("%s", DoCmd); ListCmd = MakeList(); output(listfile, "wt") printf("%s", ListCmd); exit (DoCmd); // schematic(SCH) brkfile = filesetext(SCH.name, ".brk"); // string FileName = dlgFileSave("Speichere Brückenliste", brkfile); // if (FileName) { // string a[]; // output(FileName, "wtF") { // printf ("%s\n", ListHeaderMain); // while (listall[i]) { // printf("%s\n", listall[i]); // "%s" um Probleme zu vermeiden, wenn listall '%' enthält // i++; // } // } // } } void ShowHelp(void) { dlgDialog("Hilfe") { dlgHBoxLayout dlgSpacing(600); dlgHBoxLayout{ dlgVBoxLayout dlgSpacing(600); dlgTextView(HelpText); } dlgHBoxLayout { } dlgHBoxLayout { dlgStretch(1); dlgPushButton("+OK") dlgAccept(); } }; } //***************************************************** void ShowUserInterface(void) { dlgDialog("Brückenklemmen verwalten - " + Version) { dlgHBoxLayout dlgSpacing(300); dlgGroup("") { dlgLabel("Vorhandene Klemmenblöcke"); dlgListView(ListHeaderMain, listall, SelAll, SortAll) MakeEditListOnePart(SelAll); dlgSpacing(10); } dlgGroup("") { dlgHBoxLayout { dlgLabel(CurrentPart, 1) ; dlgLabel(": Brücken dieses Klemmenblocks editieren"); dlgStretch(1); } dlgListView(ListHeader, listsel, SelConnected, Sort) EditOneEntry(SelConnected); dlgHBoxLayout { dlgLabel("Verbinden"); dlgStringEdit(ChangeString); } dlgHBoxLayout { dlgStretch(1); dlgPushButton("Undo") PullUndo(); dlgStretch(1); dlgPushButton("Unbenutzte") ChangeString = GetUnused(SelConnected); dlgPushButton("Löschen") DelOneEntry(SelConnected); dlgPushButton("Neu") CreateBridge(); dlgPushButton("+Anwenden") TransferEditLine(SelConnected); } } dlgSpacing(10); dlgHBoxLayout { } dlgHBoxLayout { dlgPushButton("&Hilfe") ShowHelp(); dlgStretch(1); dlgPushButton("Log-Datei") ShowLog(); dlgPushButton("-Abbrechen") dlgReject(); // if (CancelOk()) dlgReject(); dlgPushButton("Speichern") SaveList(); } }; } //***************** Main ****************************** SetFileNames(); NrHeader = strsplit(head, ListHeader, '\t'); CollectX(); GetConnectedAllParts(); WriteAttributeLog(); output(errorfile, "wtD") printf("%s", LogCmd); ShowUserInterface();