neingeist
/
arduinisten
Archived
1
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

953 lines
32 KiB
Plaintext

// 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 "<b>Brückenklemmen-Verwaltung: Brücken eintragen und ändern</b>\n<p> "
"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.<p> "
"Die erzeugte Liste (schaltungsname.brk) kann in einem Tabellenkalkulationsprogramm "
"weiter verarbeitet oder mit Hilfe von <i>e-makelist.ulp</i> direkt in die "
"Schaltungszeichnung importiert werden. <p>"
"<author>Author: support@cadsoft.de</author>"
/////////////////////////////////////////////////////////////////////////////////
// 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 =
"<b>Brückenklemmen-Verwaltung: Brücken eintragen und ändern</b><p>"
"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.<br> "
"Die erzeugte Liste (schaltungsname.brk) kann in einem Tabellenkalkulationsprogramm "
"weiter verarbeitet oder mit Hilfe von <i>e-makelist.ulp</i> direkt in die "
"Schaltungszeichnung importiert werden. <p>"
"<b>Klemmenbibliothek</b><p>"
"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 <i>BRUECKE</i> 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.<p> "
"<b>Prinzip</b><p>"
"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.<p> "
"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.<p> "
"<b>Was steht im Klemmenplan und im Brückenplan?</b><p>"
"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.<p> "
"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.<p> "
"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).<p> "
"Falls Kontakte auf beide Arten verbunden sind (was keinen Sinn macht), "
"erscheinen sie im Klemmenplan und im Brückenplan.<p> "
"<b>Wie werden Brücken im Stromlaufplan dargestellt?</b><p>"
"Im Brückenklemmen-Symbol weisen (maximal) zwei Zahlen auf die nächsten Klemmen hin, "
"mit denen es verbunden ist. Da Referenzverbindungen nicht über die <i>Draht</i>-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.<p> "
"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.<p> "
"<b>Bedienung</b><p>"
"In jeder Programmsitzung können Sie nur die Brücken eines Klemmenblocks (also etwa X1) "
"bearbeiten.<p> "
"Typischer Ablauf einer Programmsitzung:<p>"
"<b>Log-Datei:</b> Dieser Button öffnet ein Textfenster, in dem Sie die vorhandenen "
"Draht- und Referenz-Brücken sowie Warnungen zu eventuellen Fehlern finden.<p> "
"<b>Doppelklick auf obere Liste:</b> 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.<p> "
"<b>Untere Liste:</b> 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.<p> "
"<b>Doppelklick auf untere Liste:</b> 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 <b>Anwenden</b> ändert die selektierte "
"Zeile entsprechend. Falls Sie Klemmen gewählt haben, die nicht in der "
"Schaltung platziert sind, erscheint eine Fehlermeldung.<p> "
"<b>Speichern:</b> 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.<p> "
"<b>Undo:</b> Dieser Button bringt nach einer Änderung den letzten Zustand in die "
"untere Liste (nur eine Undo-Stufe).<p> "
"<b>Unbenutzte:</b> 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.<p> "
"<b>Löschen:</b> Löscht eine komplette Brückenzeile.<p> "
"<b>Neu:</b> Erzeugt eine neue Brückenzeile, in die Sie den Inhalt des Editier-Fensters "
"übertragen können.<p> "
"<b>Abbrechen:</b> 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( "<b>Unzulässige Brückenbezeichnung, siehe Log-Liste!</b><p>"
"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("<b>Kein Klemmenblock mit diesem Namen vorhanden!</b><p>");
// 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("<b>Ungültige Klemmennummern im Editier-Feld!</b><p>"
"Erlaubt sind Klemmennummern, die in der selektierten Brücke verwendet wurden, "
"aber in keiner anderen (nur Leerzeichen und 0-9).<p>"
"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( "<b>Sie müssen erst eine Zeile im unteren Fenster selektieren!</b><p>");
// 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();