#import "Aprica.h"
// Aprica2
// copyright Pirmin Braun 1997-2007 - pirmin@pirmin.de
// all Rights reserved;
@implementation PBWOEditor
ACCESSClassm(soa, setSoa, NSArray)
ACCESSClassm(templ, setTempl, WOElement)
ACCESSm(selectedBoxName,setSelectedBoxName);
ACCESSClassm(waitingForName,setWaitingForName,PBWOAsso);
ACCESSClassm(currentAction, setCurrentAction, PBActionO)
ACCESSm(guiName,setGuiName);
ACCESSClassm(commonBox,setCommonBox,NSArray);
ACCESSClassm(suchabfrButtons,setSuchabfrButtons,NSArray);
ACCESSm(nameForScript,setNameForScript)
- (NSMutableArray *)clearOnSelObjChanged;{return clearOnSelObjChanged;}- (NSMutableArray *)refreshOnSelObjChanged;{return refreshOnSelObjChanged;}- (NSMutableDictionary *)portletDict;{return portletDict;}- (NSMutableArray *)stateArray;{return stateArray;}- (NSMutableDictionary *)colWidthDict;
{ return colWidthDict;
}
- (NSMutableDictionary *)changedInRequest;
{ return changedInRequest;
}
- (NSMutableDictionary *)parmDict;
{ return parmDict;
}
- (NSMutableArray *)boxNameArray;
{ return boxNameArray;
}
- (NSMutableArray *)filterQs;
{ return filterQs;
}
- (BOOL)hasFilter;
{ return ([filterQs count] > 0);
}
- (int)portletIndex;{return portletIndex;}- (NSString *)nextAssoID;
{ return [NSSWF @"asso_%i",assoIDCounter++];
}
- (WOElement *)invokeActionForRequest:(WORequest*)aRequest inContext:(WOContext*)aContext
{//take Values ist hier gelaufen
WOElement *e = nil;
NS_DURING;
e = [super invokeActionForRequest:aRequest inContext:aContext]; // hier wird df oder eine explizite action aufgerufen
NS_HANDLER;
NS_ENDHANDLER;
[parmDict setSecureObject:selObj forKey:@"p_eo"];
[_APP executeScriptNamed:[NSSWF @"%@/didInvokeActionForRequest",nameForScript] datasource:self parmDict:parmDict];
[parmDict removeObjectForKey:@"p_eo"];
if([self nextModul]){ [_SESSION setNextModul:nextModul];
return nextModul; //hat Vorrang;
}
if(e){ [_SESSION setNextModul:(PBWOEditor *)e];
return e; //actions, die explizit seite zurueckgeben
}
[_SESSION setNextModul:self];
return self; //falls eine instanceForBundleNamed nicht gefunden wird
}
- (NSString *)layoutInfoPathForRead;
{ NSString *s;
NSString *userName = [_SESSION use_lif_from];
if(!userName)userName = CURRENTUSER;
s = [NSSWF @"%@/LayoutsUsers/%@/%@.lif",MANDANTPATH,userName,[self name]];
if([myFM fileExistsAtPath:s])return s;
return [NSSWF @"%@/LayoutsUsers/Administrator/%@.lif",MANDANTPATH,[self name]];
}
- (BOOL)badLif;
{ return badLif;
}
- (NSString *)nameForLifdictKey:(NSString *)k;
{ NSString *label,*s;
NSArray *a1;
a1 = [k componentsSeparatedByString:@"|"];
s = [a1 firstObject];
if([a1 count]==3 && ([s iE:@"p"] || [s iE:@"a"] || [s iE:@"P"] || [s iE:@"A"])){ label = [a1 lastObject];
}else{ label = k;
}
return label;
}
- (NSMutableArray *)fassos;
{ return fassos;
}
- (PBWOAsso *)currentAsso;
{ return currentAsso;
}
- (NSString *)cmqName;
{ return [NSSWF @"%@_%@_%@",[waitingForName refdTableName],[self name],[waitingForName dbName]];
}
- (void)oeffneUebersicht:(NSString *)ueName tableName:(NSString *)tableName;
{ [self oeffneUebersicht:ueName tableName:tableName ueb_mode:UEB_NONE];
}
- (void)oeffneUebersichtMS:(NSString *)ueName tableName:(NSString *)tableName;
{ [self oeffneUebersicht:ueName tableName:tableName ueb_mode:UEB_MULTI_DEL];
}
- (void)oeffneUebersichtMSRef:(NSString *)ueName tableName:(NSString *)tableName;
{ [self oeffneUebersicht:ueName tableName:tableName ueb_mode:UEB_MULTI_REF];
}
- (void)oeffneUebersicht:(NSString *)ueName tableName:(NSString *)tableName ueb_mode:(int)ueb_mode;
{// UEB_NONE = kein Uebernehmenmode; bei Click zum default-Editor springen;
// UEB_SINGLE = nur 1 anklickbar; f. Kalender;
// UEB_MULTI_DEL = Multi-Select; uebernommene werden aus Tableview geloescht;
// UEB_MULTI_REF = Multi-Select Refetch; nach uebernehmen wird neu gefetched;
// wird i.a. von Buttons aufgerufen: expression:
// invk %datasource,oeffneUebersicht:tableName:,$ueName,$tn
PBWOUebersicht *pbe;
PBDDTable *t = [MYDD tableNamed:tableName];
PBSQLQualifier *cmq;
NSString *s,*soas;
NSDictionary *rd;
if(!t)return;
pbe = MODUL(@"PBWOUebersicht");
if(!pbe){ LOGI(TRANSLATION(@"Modul PBWOUebersicht nicht bekommen"));
return;
}
[pbe setSuchFelderQ:nil];
[[pbe filterQs] removeAllObjects];
if(![pbe configureUebersicht:ueName table:t cm:self])return;
//cmq per script ermitteln
// p_tableName Zieltablle, in der nachgeschlagen werden soll
// p_ueName Name der Uebersicht
// p_cmn modulname
// p_lifFileName modulname, ueName; wie lifFileName in PBWOUebersicht
// rp_cmq Rueckgabeparameter: erzeugter callingModulQualifier
// rp_csc Returnparameter Combisuch-Content; wird ins combisuchfeld eingetragen und damit gesucht; zieht staerker als rp_cmq
// rp_soa Returnparameter sort order array; String im soaFrom-Format steuert Sortierung
// parmDict nicht leeren, weil ja vielleicht der Button noch weitere Parameter eingestellt hat
[parmDict setObject:tableName forKey:@"p_tableName"];
[parmDict setObject:ueName forKey:@"p_ueName"];
[parmDict setObject:[self name] forKey:@"p_cmn"];
[parmDict setObject:[NSSWF @"%@_%@",[self name],ueName] forKey:@"p_lifFileName"];
rd = [_APP executeScriptNamed:@"getCMQForUebersicht" datasource:self parmDict:parmDict];
if([[rd ofk:@"scriptRC"]iE:@"N"])return; // abbruch
cmq = [rd ofk:@"rp_cmq"]; // callingModulQualifier
s = [rd ofk:@"rp_csc"]; // combiSuchContent
soas = [rd ofk:@"rp_soa"]; // sortOrderArray
[pbe setUebernMode:ueb_mode];
if(FILLED(soas)){ [pbe setSoseq:soas];
}
if(s){ // combiSuchContent uebergeben; hat Vorrang
[pbe setCombiSuchContent:s];
[pbe combiSucheActed];
}else{ [[pbe ma]removeAllObjects];
[pbe executeCallingMQ:cmq];
}
[self bringToFront:pbe];
}
- (void)followLink;
{ PBWOEditor *pbe;
PBSQLQualifier *q;
NSString *pkn,*en=[currentAsso refdTableName],*s=[currentAsso val];
NSString *targetModulName;
if(!FILLED(s))return;
pkn = [[MYDD tableNamedCheap:en]primaryKeyName];
if(!pkn)return;
q = [PBSQLQualifier qualifierWithString:[NSSWF @"%@ = '%@'",pkn,s]];
targetModulName = [currentAsso targetModulName]; //an attribut hinterlegt evt.
if(FILLED(targetModulName)){ pbe = MODUL(targetModulName);
if(!pbe)return; //wenn targetmodul angegeben, muss dieses genommen werden
}else{ pbe = [_SESSION instanceForBundleNamed:en];
}
SUCH_EXTERNAL(pbe,q);
}
- (void)filterAttrNames:(NSMutableArray *)lifa pa:(NSMutableArray *)pa;
{// aus den Strings im lifa, die attributnamen sind, attribute machen; die steueranweisungen belassen; unbekanntes rausfiltern;
// was nicht in allAttr ist, raus
// Attribute und Formatanweisungen in pa sammeln
// Formatanweisungen als NSString;
// unsichtbare Felder und Felder nur fuer Root rausfiltern
int i,j;
NSString *s;
PBDDAttribute *pba;
[pa removeAllObjects];
for(i=0,j=[lifa count];i<j;i++){ s = [lifa oai:i];
if([s hasSecurePrefix:@"<"]){ [pa addObject:s]; //Formatanweisung
continue;
}
if((pba = [allAttr ofk:s])){ if(![pba isVisible]){ [pa addObject:@"<invisible>"]; //Formatanweisung; cleared feldbezogene flags, damit diese nicht auf naechstes uebergehen;
continue;
}
[pa addObject:pba]; //echtes Attribut
}
}
}
- (BOOL)mayNotLeaveConfig;
{ return ![self mayLeaveConfig];
}
- (BOOL)mayNotChangeSelectedObject;
{ return ![self paNon];
}
- (void)createFullyQualifiedLif;
{}
- (void)saveLif:(NSMutableDictionary *)dict path:(NSString *)path;
{ LMD;
NSArray *a = [dict allKeys];
int i,j;
[myFM createAllDirsAtPath:[path stringByDeletingLastPathComponent]];
for(i=0,j=[a count];i<j;i++){ NSString *k = [a oai:i];
if(![k hasSecureSuffix:@"|System"])[lmd setObject:[dict ofk:k] forKey:k];
}
[[self lifStringWithDict:lmd] WTF:path];
}
- (void)saveLif;
{ if(!myTable)return;
if(![_SESSION use_lif_from]){ [self saveLif:lifDict path:[NSSWF @"%@/LayoutsUsers/%@/%@.lif",MANDANTPATH,CURRENTUSER,[self name]]];
}
}
- (void)useLif:(NSString *)c path:(NSString *)s dict:(NSMutableDictionary *)dict;
{// den String c in lifdict dict umformen
// path:s ist nur fuer log-meldungen
NSMutableArray *lma;
NSString *k;
int i,n;
NSArray *ws,*ls = [c componentsSeparatedByString:@"\n"];
NSString *fld,*l;
n = [ls count];
for (i=0;i<n;i++) { l = [[ls oai: i] stringWithoutWindowsShit];
ws = [l componentsSeparatedByString:@"\t"];
if ([ws count]!=2) {// LOGS(([NSSWF @"Lif fehlerhaft: %@ - '%@'",s,l]));
continue;
}
k = [ws oai: 0];
fld = [ws oai: 1];
if([k iE:SC_LIF_Unres] || [k iE:SC_LIF_Unknown]) continue;
if ([k iE: @"soseq"])continue; // nicht mehr im LIF, sondern im ueo.soseq
if ([fld iE: @"-"]) {// nervt if ([dict ofk:k]) LOGS(([NSSWF @"Warning: replacing %@ in %@",k,s]));
lma = [NSMutableArray arrayWithCapacity:10];
[dict setSecureObject:lma forKey:k];
} else { lma = [dict ofk: k];
if([fld hasSecurePrefix: @"<"]){ [lma addObject: fld];
}else{ NSArray *a1 = [fld componentsSeparatedByString:@":"];
if([a1 count]>1){ if(![allAttr ofk: [a1 firstObject]])continue;
}else{ if(![allAttr ofk:fld])continue;
}
[lma addObject: fld];
}
}
}
}
- (void)loadLif:(NSString *)s;
{ NSString *c;
//feste keys (obsolete):
//unresolved = nicht untergebrachte attr.
//unknown = ehemals in lif, aber nicht in allAttr gefunden
[lifDict removeAllObjects];
if(!myTable)return;
if([myFM fileExistsAtPath:s]){ NS_DURING;
c = [NSSWCOF s];
[self useLif:c path:s dict:lifDict];
[self addScriptTab];
NS_HANDLER;
LOGS_Ex(([NSSWF @"Lif in %@ fehlerhaft;",s]));
badLif = YES;
NS_ENDHANDLER;
}
if(![lifDict count]){ [self createDefaultLayout];
//wenn bundle kein lif hatte aufgrund parsing problem, das generierte default-lif nicht schreiben
//ansonsten in std-directory schreiben, nicht in kunden-spez., da erstmaliges speichern
if(!badLif && [lifDict count])[self saveLif];
}
if(![lifDict ofk:SC_LIF_COMMON])[lifDict setObject:[NSMutableArray array] forKey:SC_LIF_COMMON];
if(![lifDict ofk:SC_LIF_SUCHABFR])[lifDict setObject:[NSMutableArray array] forKey:SC_LIF_SUCHABFR];
[lifDict removeObjectForKey:SC_LIF_DRUCK];
[lifDict removeObjectForKey:SC_LIF_EXPORT];
[lifDict removeObjectForKey:@"_uebersicht"];
[lifDict removeObjectForKey:@"_funktionen"];
}
- (void)loadLif;
{ [self loadLif:[self layoutInfoPathForRead]];
}
- (NSString *)soseq;
{ return soseq;
}
- (void)setSoseq:(NSString *)s;
{ int i,j;
LMDN(colByName);
NSArray *a;
PBWOTVCCol *column;
LMAN(soa_elements);
if(s==soseq)return;
// Spalten zuruecksetzen
[self setTvcSortCol:nil];
for(i=0,j=[columns count];i<j;i++){ column = [columns oai:i];
[column setTvNewSortMode:SORTMODE_N];
[colByName setObject:column forKey:[column dbName]];
}
// alte Syntax aus Lif auf neue konvertieren
if(FILLED(s)){ if([s hasSecurePrefix:@"-"]){ s = [[s secureSubstringFromIndex:1]stringByAppendingString:@":d"];
}else if([s hasSecurePrefix:@"+"]){ s = [s secureSubstringFromIndex:1];
}
}
// pruefen, ob noch alle Sortierspalten vorhanden und in DB und Sortierspalten visualisieren
a = [s componentsSeparatedByString:@","];
for(i=0,j=[a count];i<j;i++){ NSString *s = [a oai:i];
int sortmode;
PBDDAttribute *pbat;
if([s hasSecureSuffix:@":d"]){ s = [s stringWithoutSuffix:@":d"];
sortmode = SORTMODE_D;
}else{ sortmode = SORTMODE_A;
}
pbat = [myTable plainAttrNamed:s];
if(pbat && [pbat isDB]){ if(sortmode == SORTMODE_A){ [soa_elements addObject:s];
}else{ [soa_elements addObject:[NSSWF @"%@:d",s]];
}
column = [colByName ofk:s];
if(column)[column setTvNewSortMode:sortmode];
if(column && !tvcSortCol)[self setTvcSortCol:column]; // erste spalte f. Positionieren
}
}
[soseq release];
soseq = [[soa_elements componentsJoinedByString:@","] retain];
[self setSoa:[NSArray soaADFrom:soseq]];
}
- (void)saveSoseq;
{// von von QueryPortlet oder Spaltenklick gesetzt wurde
NSString *s = soseq;
if(!s)s = @"";
[[_SESSION moduleSoseq] setObject:s forKey:[self name]];
[_SESSION saveSoseq];
}
- (void)addCustomTab;
{ NSString *tabName = @"a|600|Custom";
[lifDict setSecureObject:[NSMutableArray array] forKey:tabName];
}
- (void)addScriptTab;
{// bestehendes vorher loeschen
NSString *tabName = @"a|900|System";
NSArray *ks = [lifDict allKeys];
int i,j;
LMAN(fields); // muss mutable sein f. Editieren
NSArray *a = [_APP systemtab];
[fields addObjectsFromArray:a];
for(i=0,j=[ks count];i<j;i++){ NSString *k = [ks oai:i];
if([k hasSecureSuffix:@"|System"]){ [lifDict removeObjectForKey:k];
}
if([k hasSecureSuffix:@"|Media"]){ [lifDict removeObjectForKey:k];
}
if([k hasSecureSuffix:@"|Zuord"]){ [lifDict removeObjectForKey:k];
}
}
if(IS_ROOT || ![[[_APP configDict]ofk:@"no_system_tab"]iE:@"J"]){ // System-Tab kann abgeschaltet werden
[lifDict setSecureObject:fields forKey:tabName];
}
}
- (void)mapVisibleTVAttrToLifDict;
{ NSArray *a = [self visibleTVAttr];
int i,j;
LMA;
for(i=0,j=[a count];i<j;i++){ PBDDAttribute *pba =[a oai:i];
int customWidth = [[colWidthDict ofk:[pba dbName]]intValue];
if(customWidth){ [lma addObject:[NSSWF @"%@:%i",[pba dbName],customWidth]];
}else{ [lma addObject:[pba dbName]];
}
}
if([lma count])[lifDict setSecureObject:lma forKey:SC_LIF_TV];
}
- (WOElement *)previewConfig;
{ if(configMode==CONFIGMODE_Lif){// momentanes aktivieren
[self useLif:lifEditArea path:@"(edit-area)" dict:lifDict];
[self addScriptTab];
}else{ [self mapVisibleTVAttrToLifDict];
}
[self redrawAfterLeaveConfig];
return self;
}
- (WOElement *)leaveConfig;
{ NSString *oldBoxName;
if(configMode==CONFIGMODE_Lif){ [self saveAsMyLif]; //lifeditarea speichern als lif
[self loadLif]; //gespeichertes laden
}else{ [self mapVisibleTVAttrToLifDict];
}
isConfigMode=NO;
[self redrawAfterLeaveConfig];
if(configMode!=CONFIGMODE_Lif){ [self saveLif];
}
// versuchen, wieder auf alte Box zu positionieren
oldBoxName = [parmDict ofk:@"selectedBoxName"];
if(FILLED(oldBoxName)){ int i = [boxNameArray indexOfObject:oldBoxName];
if(NSNotFound == i)return self;
if([selectedBoxName iE:oldBoxName])return self;
[self setSelectedBoxName:oldBoxName];
}
return self;
}
- (WOElement *)abortConfig;
{ isConfigMode=NO;
[self loadLif]; //urspruengliches wieder laden, editierungen verwerfen;
return self;
}
- (void)redrawAfterLeaveConfigAction;
{// neu zeichnen Button
[self loadLif]; //File kann extern bearbeitet worden sein
[self redrawAfterLeaveConfig];
}
//lif-Editor
ACCESSClassm(selectedFields,setSelectedFields,NSArray);
ACCESSClassm(selectedFieldsOrControls,setSelectedFieldsOrControls,NSArray);
ACCESSClassm(fieldsInSelectedRegister,setFieldsInSelectedRegister,NSMutableArray);
ACCESSClassm(currentFieldInSelectedRegister, setCurrentFieldInSelectedRegister,PBStringWrapper)
ACCESSm(currentRegister, setCurrentRegister)
ACCESSm(selectedRegister, setSelectedRegister)
ACCESSm(selectedRegisterModify, setSelectedRegisterModify)
ACCESSm(newRegisterName, setNewRegisterName)
ACCESSm(currentFieldItem, setCurrentFieldItem)
ACCESSm(fieldTargetPos, setFieldTargetPos)
ACCESSm(selectedField, setSelectedField)
- (NSArray *)registers;
{ LMA;
int i,j;
NSArray *a = [lifDict allKeys];
for(i=0,j=[a count];i<j;i++){ NSString *s = [a oai:i];
if([s iE:SC_LIF_Unknown] || [s iE:SC_LIF_Unres] || [s iE:SC_LIF_TV] || [s iE:@"soseq"])continue;
if([s hasSecureSuffix:@"|System"])continue;
[lma addObject:s];
}
return [lma sortedArrayUsingSelector:@selector(compareBySecondIntField:)];
}
- (BOOL)isCurrentModule;
{// in launched Moduls
return (currentLaunchedModule == self);
}
- (BOOL)isFixRegister;
{ return [currentRegister iE:SC_LIF_COMMON] || [currentRegister iE:SC_LIF_SUCHABFR];
}
- (BOOL)isSelectedRegister;
{ return currentRegister == selectedRegister;
}
- (WOElement *)deleteSelectedRegister;
{ int i = [[self registers] indexOfObject:selectedRegister];
int j;
[lifDict removeObjectForKey:selectedRegister];
j = [[self registers] count];
if(i>=j)i=j-1;
[self setSelectedRegister:[[self registers]oai:i]];
[self setSelectedRegisterModify:selectedRegister];
[self rebuildFieldsInSelectedRegister];
return self;
}
- (WOElement *)gotoCurrentRegister;
{ [self setSelectedRegister:currentRegister];
[self setSelectedRegisterModify:selectedRegister];
[self rebuildFieldsInSelectedRegister];
return self;
}
- (WOElement *)createNewRegister;
{ if(!FILLED(newRegisterName)){ LOGI(TRANSLATION(@"bitte Name fuer neues Register angeben"));
return self;
}
if([lifDict ofk:newRegisterName]){ LOGI(TRANSLATION(@"dieses Register gibt es schon; bitte anderen Namen waehlen;"));
return self;
}
if([[newRegisterName componentsSeparatedByString:@"|"]count] != 3){ LOGI(TRANSLATION(@"falsches Format fuer Registername; Bsp.:\"a|200|Name\""));
return self;
}
[lifDict setSecureObject:[NSMutableArray array] forKey:newRegisterName];
return self;
}
- (void)rebuildFieldsInSelectedRegister;
{ LMA;
int i,j;
NSArray *a =[lifDict objectForKey:selectedRegister];
//stringWrapper, damit auch gleiche strings unterschieden werden, z.B. mehrfache <br>
for(i=0,j=[a count];i<j;i++){ [lma addObject:[PBStringWrapper stringWrapperWithString:[a oai:i]]];
}
[lma addObject:[PBStringWrapper stringWrapperWithString:@"<Ende>"]];
[self setFieldsInSelectedRegister:lma];
}
- (BOOL)isInLifDict:(NSString *)dbName;
{ if(![lifFieldDict count]){ //wird regelmaessig geleert NSArray *a = [lifDict allKeys];
int i,j;
for(i=0,j=[a count];i<j;i++){ NSString *k = [a oai:i];
NSArray *a1;
if([k iE:SC_LIF_TV])continue;
if([k iE:SC_LIF_SUCHABFR])continue;
if([k iE:SC_LIF_Unres])continue;
if([k iE:SC_LIF_Unknown])continue;
a1 = [lifDict ofk:k];
if(![a1 isKindOfClass:[NSArray class]])continue; // es sind auch strings drin;
[lifFieldDict setObjects:a1 forKeys:a1];
}
}
return ([lifFieldDict ofk:dbName]!=nil);
}
- (void)rebuildFieldsOrControl;
{ NSArray *a = [allAttr allValues];
int i,j;
LMA;
[fieldsOrControls removeAllObjects];
if(fieldsOrControlsTags)[fieldsOrControls addObjectsFromArray:[[self controlFields] sortedArray]]; //strings
for(i=0,j=[a count];i<j;i++){ PBDDAttribute *pba = [a oai:i];
NSString *dbName = [pba dbName];
// filter: fieldsOrControlsButtons,fieldsOrControlsFields,fieldsOrControlsParms,fieldsOrControlsUsed,fieldsOrControlsUnused,fieldsOrControlsFilled
if([self isInLifDict:dbName]){ if(!fieldsOrControlsUsed)continue;
}else{ if(!fieldsOrControlsUnused)continue;
}
if(fieldsOrControlsFilled && [self selObj] && [pba targetTyp]==ATTVCSELOBJ){ NSString *s = [[self selObj] vfk:[pba dbName]];
if(!FILLED(s))continue;
if([pba isNumeric] && [s doubleValue]==0.0)continue;
}
if(fieldsOrControlsButtons && ([pba targetTyp]==ATBU || [pba targetTyp]==ATPORTLET)){ [lma addObject:pba];
continue;
}
if(fieldsOrControlsParms && ([pba targetTyp]==ATTVCPD)){ [lma addObject:pba];
continue;
}
if(fieldsOrControlsFields && ([pba targetTyp]==ATTVCSELOBJ)){ [lma addObject:pba];
continue;
}
}
if(fieldsOrControlsSortByUI){ [fieldsOrControls addObjectsFromArray:[[lma sortedArrayUsingKeyOrderArray:[NSArray soaCaseInsensitiveFrom:@"guiNameTrans"]]valuesForKey:@"dbName"]];
}else{ [fieldsOrControls addObjectsFromArray:[[lma valuesForKey:@"dbName"]sortedArray]]; //dbnames
}
}
- (WOElement *)enterConfig;
{ isConfigMode=YES;
[self setSelectedRegister:nil];
if(!FILLED([parmDict ofk:@"p_lastAction"]))[parmDict setObject:@"removeField" forKey:@"p_lastAction"];
if(FILLED(selectedBoxName))[parmDict setObject:selectedBoxName forKey:@"selectedBoxName"]; // merken fuer leaveconfig, um wieder da hin zu positionieren
if([self isKindOfClass:[PBWOPosEditor class]]){ [self setSelectedRegister:@"_common"];
}else{ if(FILLED(selectedBoxName) && ![selectedBoxName iE:@"System"]){ int i,j;
NSArray *a = [self registers];
for(i=0,j=[a count];i<j;i++){ NSString *s = [a oai:i];
NSArray *a1 = [s componentsSeparatedByString:@"|"];
if([a1 count]==3){ NSString *s1 = [a1 oai:2];
if([s1 iE:selectedBoxName]){ [self setSelectedRegister:s];
}
}
}
}
}
[self setSelectedRegisterModify:selectedRegister];
[self rebuildFieldsInSelectedRegister];
[self rebuildFieldsOrControl];
return self;
}
- (BOOL)isConfigModeListe;
{ return configMode==CONFIGMODE_Liste;
}
- (BOOL)isConfigModeDetail;
{ return configMode==CONFIGMODE_Detail;
}
- (BOOL)isConfigModeLif;
{ return configMode==CONFIGMODE_Lif;
}
- (WOElement *)gotoConfigModeDetail;
{ configMode = CONFIGMODE_Detail;
if(!selectedRegister)[self setSelectedRegister:[[self registers]firstObject]];
[self setSelectedRegisterModify:selectedRegister];
[self rebuildFieldsInSelectedRegister];
[self rebuildFieldsOrControl];
return self;
}
- (BOOL)hasNoTV;
{ return !([self hasTV]);
}
- (WOElement *)gotoConfigModeLif;
{ configMode = CONFIGMODE_Lif;
return self;
}
- (WOElement *)fieldsOrControlsToggleUnused;
{ fieldsOrControlsUnused =! fieldsOrControlsUnused;
[self rebuildFieldsOrControl];
return self;
}
- (WOElement *)fieldsOrControlsToggleUsed;
{ fieldsOrControlsUsed =! fieldsOrControlsUsed;
[self rebuildFieldsOrControl];
return self;
}
- (WOElement *)fieldsOrControlsToggleParms;
{ fieldsOrControlsParms =! fieldsOrControlsParms;
[self rebuildFieldsOrControl];
return self;
}
- (WOElement *)fieldsOrControlsToggleSort;
{ fieldsOrControlsSortByUI =! fieldsOrControlsSortByUI;
[self rebuildFieldsOrControl];
return self;
}
- (WOElement *)fieldsOrControlsToggleFields;
{ fieldsOrControlsFields =! fieldsOrControlsFields;
[self rebuildFieldsOrControl];
return self;
}
- (WOElement *)fieldsOrControlsToggleFilled;
{ fieldsOrControlsFilled =! fieldsOrControlsFilled;
[self rebuildFieldsOrControl];
return self;
}
- (WOElement *)fieldsOrControlsToggleButtons;
{ fieldsOrControlsButtons =! fieldsOrControlsButtons;
[self rebuildFieldsOrControl];
return self;
}
- (WOElement *)fieldsOrControlsToggleTags;
{ fieldsOrControlsTags =! fieldsOrControlsTags;
[self rebuildFieldsOrControl];
return self;
}
- (NSString *)fieldsOrControlsToggleTagsSrc;
{ return [NSSWF @"/Aprica2_%@/Images/%@",[_APP mandant],(fieldsOrControlsTags?@"check_on.gif":@"check_off.gif")];
}
- (NSString *)fieldsOrControlsToggleButtonsSrc;
{ return [NSSWF @"/Aprica2_%@/Images/%@",[_APP mandant],(fieldsOrControlsButtons?@"check_on.gif":@"check_off.gif")];
}
- (NSString *)fieldsOrControlsToggleFieldsSrc;
{ return [NSSWF @"/Aprica2_%@/Images/%@",[_APP mandant],(fieldsOrControlsFields?@"check_on.gif":@"check_off.gif")];
}
- (NSString *)fieldsOrControlsToggleFilledSrc;
{ return [NSSWF @"/Aprica2_%@/Images/%@",[_APP mandant],(fieldsOrControlsFilled?@"check_on.gif":@"check_off.gif")];
}
- (NSString *)fieldsOrControlsToggleParmsSrc;
{ return [NSSWF @"/Aprica2_%@/Images/%@",[_APP mandant],(fieldsOrControlsParms?@"check_on.gif":@"check_off.gif")];
}
- (NSString *)fieldsOrControlsToggleSortSrc;
{ return [NSSWF @"/Aprica2_%@/Images/%@",[_APP mandant],(fieldsOrControlsSortByUI?@"check_on.gif":@"check_off.gif")];
}
- (NSString *)fieldsOrControlsToggleUsedSrc;
{ return [NSSWF @"/Aprica2_%@/Images/%@",[_APP mandant],(fieldsOrControlsUsed?@"check_on.gif":@"check_off.gif")];
}
- (NSString *)fieldsOrControlsToggleUnusedSrc;
{ return [NSSWF @"/Aprica2_%@/Images/%@",[_APP mandant],(fieldsOrControlsUnused?@"check_on.gif":@"check_off.gif")];
}
- (NSString *)guiNameForCurrentFieldInSelectedRegister;
{//f. StringWrapper in fieldsInSelectedRegister
NSString *s=nil,*gn,*dn;
NSString *string = [currentFieldInSelectedRegister string];
NSString *zeilennr = [NSSWF @"%03i ",fieldsInSelectedRegisterIndex++];
if([string hasSecurePrefix:@"<"])return [zeilennr stringByAppendingString:string]; //Format-Anweisung
//guiName des PBDDAttribute bzw. dbName wenn showDescri= NO u. in Klammern der Beispiel-Value des selObj
if([self selObj] && ![string iE:@"cryptedpw"]){ PBEO *eo = [self selObj];
s = [[eo values] ofk:string];
}
gn = [[allAttr ofk:string] guiNameTrans];
dn = [[allAttr ofk:string] dbName];
if(!FILLED(s))return [NSSWF @"%@%@ (%@)",zeilennr,gn,dn];
return [[NSSWF @"%@%@ (%@) [%@]",zeilennr,gn,dn,s]abbrevToLength:50];
}
- (NSString *)guiNameForCurrentFieldItem;
{//f. Strings in fieldsOrControls
//controls woertlich
//suffix * wenn schon irgendwo verbaut
//guiName, evt. uebersetzt
//dbName
//dahinter in klammern den evt. Wert im EO;
NSString *s=nil,*gn,*dn;
NSString *string = currentFieldItem;
NSString *usedMarker=@"";
if([string hasSecurePrefix:@"<"])return string; //Format-Anweisung
//guiName des PBDDAttribute bzw. dbName wenn showDescri= NO u. in Klammern der Beispiel-Value des selObj
if([self selObj] && ![string iE:@"cryptedpw"]){ PBEO *eo = [self selObj];
s = [[eo values] ofk:string];
}
gn = [[allAttr ofk:string] guiNameTrans];
dn = [[allAttr ofk:string] dbName];
if([self isInLifDict:string])usedMarker=@" *";
if(FILLED(s)){ s = [NSSWF @"[%@]",s];
}else{ s = @"";
}
if(fieldsOrControlsSortByUI){ return [[NSSWF @"%@%@(%@) %@",gn,usedMarker,dn,s]abbrevToLength:50];
}else{ return [[NSSWF @"%@%@(%@) %@",dn,usedMarker,gn,s]abbrevToLength:50];
}
}
- (WOElement *)fieldUp;
{ [self fieldDirection:-1];
return self;
}
- (WOElement *)fieldDown;
{ [self fieldDirection:1];
return self;
}
- (void)fieldDirection:(int)direction;
{ NSMutableArray *lma = (NSMutableArray *)[self fieldsInSelectedRegister],*lma1=[self lifDictArrrayOfSelectedRegister];
PBStringWrapper *field;
NSString *s;
int ip;
if((field = [selectedFields firstObject])){ if([[field string] iE:@"<Ende>"])return;
ip = [lma indexOfObject:field];
if(ip == NSNotFound)return;
field = [lma oai:ip];
s = [lma1 oai:ip];
[field retain];
[s retain];
[lma removeObjectAtIndex:ip];
[lma1 removeObjectAtIndex:ip];
ip+=direction;
if(ip<0)ip=0;
if(ip>=[lma count]){ ip=[lma count]-1;
}
[lma insertObject:field atIndex:ip];
[lma1 insertObject:s atIndex:ip];
[field release];
[s release];
}
}
- (WOElement *)fieldMoveToTargetPos;
{ NSMutableArray *lma = (NSMutableArray *)[self fieldsInSelectedRegister],*lma1=[self lifDictArrrayOfSelectedRegister];
PBStringWrapper *field;
int ip,nip,amount,direction=0;
NSString *s;
if([fieldTargetPos hasSecurePrefix:@"+"]){ amount=[[fieldTargetPos substringFromIndex:1] intValue];
direction = 1;
}else if([fieldTargetPos hasSecurePrefix:@"-"]){ amount=[[fieldTargetPos substringFromIndex:1] intValue];
direction = 2;
}else{ amount=[fieldTargetPos intValue];
}
if((field = [selectedFields firstObject])){ if([[field string] iE:@"<Ende>"])return self;
ip = [lma indexOfObject:field];
if(ip == NSNotFound)return self;
[field retain];
s = [lma1 oai:ip];
[s retain];
[lma removeObjectAtIndex:ip];
[lma1 removeObjectAtIndex:ip];
if(direction == 1){ nip = ip + amount;
}else if(direction == 2){ nip = ip - amount;
}else{ nip = amount;
if(nip > ip)nip--; //da urspr. pba jetzt draussen
}
if(nip>=[lma count]){ nip = [lma count]-1;
}
if(nip<0)nip=0;
[lma insertObject:field atIndex:nip];
[lma1 insertObject:s atIndex:nip];
[field release];
[s release];
}
return self;
}
- (WOElement *)selectFieldForEdit;
{ PBStringWrapper *field;
NSMutableArray *lma = (NSMutableArray *)[self fieldsInSelectedRegister];
if((field = [selectedFields firstObject])){ NSString *s = [field string];
if([s hasSecurePrefix:@"<width "]
|| [s hasSecurePrefix:@"<descrWidth "]
|| [s hasSecurePrefix:@"<editWidth "]
|| [s hasSecurePrefix:@"<bezWidth "]
|| [s hasSecurePrefix:@"<guiName "]
|| [s hasSecurePrefix:@"<ESC "]
|| [s hasSecurePrefix:CLASS_PREFIX]
|| [s hasSecurePrefix:TEXT_PREFIX]
|| [s hasSecurePrefix:IMG_PREFIX]
|| [s hasSecurePrefix:NI_PREFIX]
|| [s hasSecurePrefix:ZEILEN_PREFIX]
|| [s hasSecurePrefix:BLOCK_PREFIX]
|| [s hasSecurePrefix:HTML_PREFIX]
|| [s hasSecurePrefix:RASTER_PREFIX]){ indexOfSelectedField = [lma indexOfObject:field];
if(indexOfSelectedField == NSNotFound){ [self setSelectedField:EON];
return self;
}
[self setSelectedField:s];
}
}
[parmDict setObject:@"selectFieldForEdit" forKey:@"p_lastAction"];
return self;
}
- (WOElement *)submitSelectedRegisterModified;
{ if(!FILLED(selectedRegisterModify)){ LOGI(TRANSLATION(@"bitte Name fuer neues Register angeben"));
return self;
}
if([lifDict ofk:selectedRegisterModify]){ LOGI(TRANSLATION(@"dieses Register gibt es schon; bitte anderen Namen waehlen;"));
return self;
}
if([[selectedRegisterModify componentsSeparatedByString:@"|"]count] != 3){ LOGI(TRANSLATION(@"falsches Format fuer Registername; Bsp.:\"a|200|Name\""));
return self;
}
[lifDict setSecureObject:[lifDict ofk:selectedRegister] forKey:selectedRegisterModify];
[lifDict removeObjectForKey:selectedRegister];
[self setSelectedRegister:selectedRegisterModify];
[self rebuildFieldsInSelectedRegister];
return self;
}
- (WOElement *)submitSelectedField;
{ if(FILLED(selectedField) && indexOfSelectedField!=NSNotFound){ [(NSMutableArray *)[self lifDictArrrayOfSelectedRegister]replaceObjectAtIndex:indexOfSelectedField withObject:selectedField];
[[[self fieldsInSelectedRegister]oai:indexOfSelectedField] setString:selectedField];
}
return self;
}
- (WOElement *)toggleConfigFocus;
{ if([[parmDict ofk:@"p_lastAction"]iE:@"removeField"]){ [parmDict setObject:@"addField" forKey:@"p_lastAction"];
return self;
}
if([[parmDict ofk:@"p_lastAction"]iE:@"addField"]){ [parmDict setObject:@"removeField" forKey:@"p_lastAction"];
return self;
}
[parmDict setObject:@"removeField" forKey:@"p_lastAction"];
return self;
}
- (WOElement *)removeField;
{ int i,j=[selectedFields count],oldPos;
if(!j)return self;
oldPos = [fieldsInSelectedRegister indexOfObject:[selectedFields firstObject]];
if(oldPos < 0)oldPos = 0;
for(i=0;i<j;i++){ PBStringWrapper *field = [selectedFields oai:i];
NSString *s = [field string];
if([s iE:@"<Ende>"])continue;
[fieldsOrControls addObject:s]; //nicht uniq, damit feldfolgen mit controls dazwischen intakt bleiben
[(NSMutableArray *)[self fieldsInSelectedRegister] removeObject:field];
}
[self reflectFieldsInSelectedRegister];
[parmDict setObject:@"removeField" forKey:@"p_lastAction"];
// versuchen wieder in die Naehe zu positionieren
if(oldPos >= [[self fieldsInSelectedRegister]count])oldPos--;
if(oldPos < 0)return self; // nix zu machen
[self setSelectedFields:[NSArray arrayWithObject:[[self fieldsInSelectedRegister]oai:oldPos]]];
return self;
}
- (WOElement *)copyField;
{//in Register belassen, kopieren f. paste
int i,j;
for(i=0,j=[selectedFields count];i<j;i++){ PBStringWrapper *field = [selectedFields oai:i];
NSString *s = [field string];
if([s iE:@"<Ende>"])continue;
[fieldsOrControls addObject:s];
}
return self;
}
- (void)reflectFieldsInSelectedRegister;
{// aus Editer-Array, welches stringwrappers enthaelt, zurueck ins lif-Array des Registers
int i,j;
NSArray *a = [[self fieldsInSelectedRegister]valuesForKey:@"string"];
[[self lifDictArrrayOfSelectedRegister] removeAllObjects];
for(i=0,j=[a count];i<j;i++){ NSString *s = [a oai:i];
if([s iE:@"<Ende>"])continue;
[[self lifDictArrrayOfSelectedRegister] addObject:s];
}
}
- (NSMutableArray *)lifDictArrrayOfSelectedRegister;
{ return [lifDict ofk:selectedRegister];
}
- (WOElement *)addField;
{ NSMutableArray *lma = (NSMutableArray *)[self fieldsInSelectedRegister],*lma1=[self lifDictArrrayOfSelectedRegister];
int i,j,ip=0;
PBStringWrapper *field;
NSString *s;
if((field = [selectedFields firstObject])){ ip = [lma indexOfObject:field];
}
if(ip < 0)ip = 0; //insertion point
for(i=0,j=[selectedFieldsOrControls count];i<j;i++){ int eip = ip + i;
s = [selectedFieldsOrControls oai:i];
if(eip >= [lma count]){ [lma1 addObject:s];
[lma addObject:[PBStringWrapper stringWrapperWithString:s]];
}else{ [lma1 insertObject:s atIndex:ip+i];
[lma insertObject:[PBStringWrapper stringWrapperWithString:s] atIndex:ip+i];
}
}
[parmDict setObject:@"addField" forKey:@"p_lastAction"];
return self;
}
- (void)insertString:(NSString *)s;
{ NSMutableArray *lma = (NSMutableArray *)[self fieldsInSelectedRegister],*lma1=[self lifDictArrrayOfSelectedRegister];
int ip=0;
PBStringWrapper *field;
if((field = [selectedFields firstObject])){ ip = [lma indexOfObject:field];
}
if(ip < 0)ip = 0; //insertion point
field = [PBStringWrapper stringWrapperWithString:s];
if(ip >= [lma count]){ [lma1 addObject:s];
[lma addObject:field];
}else{ [lma1 insertObject:s atIndex:ip];
[lma insertObject:field atIndex:ip];
}
}
- (WOElement *)insertBR;
{ [self insertString:@"<br>"];
return self;
}
- (WOElement *)insertClass1;
{ [self insertString:@"<class=1>"];
return self;
}
- (WOElement *)insertClass2;
{ [self insertString:@"<class=2>"];
return self;
}
- (WOElement *)insertClass3;
{ [self insertString:@"<class=3>"];
return self;
}
- (WOElement *)insertClass4;
{ [self insertString:@"<class=4>"];
return self;
}
- (WOElement *)insertClass5;
{ [self insertString:@"<class=5>"];
return self;
}
- (WOElement *)insertClass6;
{ [self insertString:@"<class=6>"];
return self;
}
- (NSArray *)fieldsOrControls;
{ return fieldsOrControls;
}
- (NSArray *)controlFields;
{return [NSArray arrayWithObjects:@"<tab>",@"<zeilen 4>",@"<zeilen 16>",@"<width 4>",@"<width 8>",@"<width 12>",@"<text 16 bla>",@"<guiName andererGuiName>",@"<pidimg width=100 height=100>",@"<namedIcon width=40 height=39 dbName=storno>",@"<pw>",@"<raster 30>",@"<rasterd>",@"<nodescr>",@"<descrWidth 2>",@"<descrWidth 4>",@"<descrWidth 8>",@"<editWidth 2>",@"<editWidth 4>",@"<editWidth 8>",@"<editWidth 12>",@"<bezWidth 2>",@"<bezWidth 4>",@"<bezWidth 8>",@"<block 12>",@"<endblock>",@"<html <br><br>>",@"<ESC a>",@"<ESC b>",@"<ESC c>",nil];
}
- (WOElement *)loadMyLif;
{ NSString *s = [NSSWF @"%@/LayoutsUsers/%@/%@.lif",MANDANTPATH,CURRENTUSER,[self name]];
[self setLastLifPath:s];
[self setLifEditArea:[NSSWCOF s]];
return self;
}
- (WOElement *)saveAsMyLif;
{ NSString *c=lifEditArea;
if(FILLED(c)){ NSString *s = [NSSWF @"%@/LayoutsUsers/%@/%@.lif",MANDANTPATH,CURRENTUSER,[self name]];
[myFM createAllDirsAtPath:[s stringByDeletingLastPathComponent]];
[c WTF:s];
}
return self;
}
- (NSString *)lifStringWithDict:(NSDictionary *)dict;
{ NSMutableString *s=[NSMutableString stringWithCapacity: 1024];
NSArray *keys = [[dict allKeys] sortedArray];
id flds;
NSString *key,*fld;
unsigned i,j,n,m;
for (i=0,n=[keys count];i<n;i++) { key = [keys oai: i];
if(![key iE:@"soseq"]){ [s appendString: key];
[s appendString: @"\t-\n"];
}
flds = [dict ofk: key];
if ([flds isKindOfClass:[NSArray class]]) { for (j=0,m=[flds count];j<m;j++) { fld = [flds oai: j];
[s appendString: key];
[s appendString: @"\t"];
[s appendString: fld];
if([key iE:SC_LIF_TV]){ int customWidth = [[colWidthDict ofk:fld]intValue]; //customwidth
if(customWidth)[s appendFormat:@":%i", customWidth];
}
[s appendString: @"\n"];
}
} else { [s appendString: key];
[s appendString: @"\t"];
[s appendString: flds];
[s appendString: @"\n"];
}
}
return s;
}
- (int)editBezWidthPixel;
{// f. plainFields
return [currentAsso width] - [currentAsso descrWidthPixel];
}
- (void)buildUpFields:(NSArray *)a forTitle:(NSString *)k;
{//a enthaelt echte Attribute und NSStrings fuer Formatanweisungen
//nur noch breite setzen; wird von float:left platziert
//<br> macht ein <br clear=all>
//<tab> macht ein 1 raster grosses Element
//keine Fluchtlinien mehr, dafuer einheitliche Breiten
int i,j,ac=[a count],autoAssoCount=0,width=0;
NSString *k1=nil,*s;
PBDDAttribute *pba;
NSMutableArray *assosInBox; //box to fill
BOOL nodescr=NO,pw=NO,isBR=NO;
PBWOAsso *pbas;
NSString *gn = nil;
int zeilen=0; //steuert abweichende zeilenzahl der unmittelbar folgenden textarea bzw. Hoehe des Elements
int raster,descrWidth,editWidth,bezWidth; //ueberschreiben der App-Defaults
int classNo=0;
unichar ascii=0;
BOOL short_fields = [[[_APP configDict]ofk:@"short_fields"]iE:@"J"];
raster = [_APP raster];
descrWidth = [_APP descrWidth];
bezWidth = [_APP bezWidth];
editWidth = [_APP editWidth];
if([k iE:@".AUTO"] || [k iE:@"Felder"]){ //jew. erstes Feld der Box k1 = nil;
}else{ k1 = k; //aus lif
}
if(!ac && ![k1 iE:SC_LIF_COMMON] && ![k1 iE:SC_LIF_SUCHABFR]){ if(!k1)return; //nix zu machen
if(![boxDict count]){ [self setSelectedBoxName:k1]; //auf erste Box positionieren
}
[boxDict sofk([NSArray array],k1)]; //customBoxes ohne Felder
[boxNameArray addObject:k1];
return;
}
assosInBox = [NSMutableArray arrayWithCapacity:20];
if(!k1)k1 = TRANSLATION(@"Detail");
if(![boxDict count]){ [self setSelectedBoxName:k1]; //auf erste Box positionieren
}
[boxDict sofk(assosInBox,k1)];
if([k1 iE:SC_LIF_COMMON]){ [self setCommonBox:assosInBox];
}else if([k1 iE:SC_LIF_SUCHABFR]){ [self setSuchabfrButtons:assosInBox];
}else{ [boxNameArray addObject:k1];
}
for(i=0,j=[a count];i<j;i++){ pba = [a oai:i];
if([pba isKindOfClass:[PBDDAttribute class]]){ if(![pba isAuthorized])continue;
if([pba targetTyp]==ATPORTLET){// Abmessungen bestimmt Portlet selbst
pbas = [[PBWOAsso alloc]initWith:self andAttr:pba]; // guiName ist PortletName
portletIndex++;
goto platzieren;
}
if([pba targetTyp]==ATBU){// ein button
int w,h;
// bei buttons wird width in px interpretiert: nein, nicht mehr; fuehrte zu verschobenen layouts
if(width){ w = raster * width;
width=0;
}else{ w = raster * 3;
}
h=LINEHEIGHT;
pbas = [[PBWOAsso alloc]initWith:self andAttr:pba];
[pbas setWidth:w];
[pbas setHeight:h];
goto platzieren;
}
pbas = [[PBWOAsso alloc]initWith:self andAttr:pba];
if(nodescr){ [pbas setNoDescr:YES];
nodescr = NO;
}
if(pw){ [pbas setPw:YES];
pw = NO;
}
if(zeilen){ [pbas setZeilen:zeilen];
zeilen = 0;
}
if(gn){ [pbas setGuiName:gn];
gn = nil;
}
if(ascii){ [pbas setAssoID:[NSSWF @"target%i",(int)ascii]];
[pbas setGuiName:[NSSWF @"%@ ESC-%@",[pbas guiName],[NSString stringWithCharacters:&ascii length:1]]];
ascii = 0;
}
if([pba length]>=50 && ![pbas isTextArea] && !short_fields){ editWidth = 12;
}
[pbas determineSizeDwp:raster * descrWidth ewp:raster * editWidth bwp:raster * bezWidth];
if(width){ [pbas setWidth:width * raster];
width=0;
}
editWidth = [_APP editWidth];
descrWidth = [_APP descrWidth];
bezWidth = [_APP bezWidth];
platzieren:
[assosInBox addObject:pbas]; //erstmal alles in eine box
[pbas release];
if(isBR){ [pbas setIsBR:YES];
isBR = NO;
}
[pbas setClassNo:classNo];
classNo = 0;
}else{ s = (NSString *)pba;
//NSString; Formatieranweisung; in pbas steht letzte platzierte
// <br> auf erste ganz leere zeile
// <nodescr> Bezeichnung abschalten
// <pw> als Passwortfeld darstellen
// <invisible> unsichtbar; wird nur vom system eingefuegt
// <tab> macht raster breites element
// <class=1> setzt class f. naechstes Element
// <raster x> raster umsetzen
// <rasterd> raster auf default ruecksetzen
// <descrWidth 4> descrWidth auf 4
// <editWidth 4> editWidth auf 4
// <bezWidth 4> bezWidth auf 4
// <block 6> <endblock> einen Block der angegebenen Breite beginnen/beenden
// <width 5> gesamtbreite des naechsten Elements uebersteuern
// <text 2 bla, fasel> 2 Rastereinheiten eigener Text; wird wie Feld positioniert
// <pidimg width=... height=... > Bild zum Datensatz als Thumbnail einfuegen
// <namedIcon width=... height=... dbName=... [descr] [bez]> Bild einfuegen: dbName + Wert des Feldes mit "_" verbunden ist Name des gif; descr = descriptor mit anzeigen; bez=bei NamedValues klartext mit anzeigen
// <guiName xx> fuer folgende Asso diesen guiNamen vorsehen
// <ESC x> setzt fuer folgende Asso die AssoID auf targetXX wobei XX der ASCII Code von x ist
if([s iE:@"<invisible>"]){ //feldbezogene flags u. eigenschaften ruecksetzen; wird vom system eingefuegt, wenn ein unsichtbares Feld uebersprungen wurde nodescr=NO;
pw = NO;
classNo = 0;
zeilen = 0;
width=0;
gn = nil;
goto platziert;
}
if([s iE:@"<nodescr>"]){ nodescr=YES;
goto platziert;
}
if([s iE:@"<pw>"]){ pw=YES;
goto platziert;
}
if([s iE:@"<tab>"]){ //dummy Asso erzeugen PBDDAttribute *pba1;
pba1 = [MYDD minimalAttributeNamed:[NSSWF @"tab_%i",autoAssoCount++]];
[pba1 setGuiName:@""];
pbas = [[PBWOAsso alloc]initWith:self andAttr:pba1];
if(width){ [pbas setWidth:raster * width];
width=0;
}else{ [pbas setWidth:raster];
}
[pbas setHeight:LINEHEIGHT];
[pbas setIsProtected:YES];
[pbas setOnlyDescr:YES];
classNo=0;
goto platzieren;
}
if([s iE:@"<br>"]){//fuehrt zu einem <br clear=all>
isBR = YES;
}
if([s hasSecurePrefix:@"<guiName "]){ s = [s substringFromIndex:[@"<guiName " length]];
gn = TRANSLATION([s substringToIndex:[s length]-1]); //ohne >
goto platziert;
}
if([s hasSecurePrefix:@"<width "]){ width = [[s substringFromIndex:[@"<width " length]]intValue];
goto platziert;
}
if([s hasSecurePrefix:@"<ESC "]){ ascii = [[s substringFromIndex:[@"<ESC " length]]characterAtIndex:0];
goto platziert;
}
if([s hasSecurePrefix:CLASS_PREFIX]){ s = [s substringFromIndex:[CLASS_PREFIX length]];
classNo = [s intValue];
goto platziert;
}
if([s hasSecurePrefix:TEXT_PREFIX]){ int rasters;
s = (NSString *)pba; //s war lowercase, jetzt wieder wie aus lif
s = [s substringFromIndex:[TEXT_PREFIX length]];
rasters = [s intValue]; // auch 2-stelllige zahlen zulassen
if(rasters < 0)rasters = 2;
if([s length]>1){ PBDDAttribute *pba1;
s = [s substringFromIndex:2];
s = [s substringToIndex:[s length]-1]; //der Nutztext
pba1 = [MYDD minimalAttributeNamed:[NSSWF @"text_%i",autoAssoCount++]];
[pba1 setGuiName:s]; //lifs sind schon uebersetzt
pbas = [[PBWOAsso alloc]initWith:self andAttr:pba1];
[pbas setWidth:raster * rasters]; //lines, height, width
[pbas setHeight:LINEHEIGHT];
[pbas setIsProtected:YES];
[pbas setOnlyDescr:YES];
goto platzieren;
}
}
if([s hasSecurePrefix:IMG_PREFIX]){// <pidimg width=... height=... >
int w,h,r;
NSArray *whs,*kv;
PBDDAttribute *pba1;
s = [s substringFromIndex:[IMG_PREFIX length]];
s = [s substringToIndex:[s length]-1]; //ohne ">"
whs = [s componentsSeparatedByString:@" "];
if([whs count]!=2){ LOGS(([NSSWF @"falsche <img.. zeile: %@",s]));
continue;
}
kv = [[whs oai:0]componentsSeparatedByString:@"="];
if([kv count]!=2 || ![[kv firstObject]iE:@"width"]){ LOGS(([NSSWF @"falsche width in <img.. zeile: %@",s]));
continue;
}
w = [[kv oai:1]intValue];
kv = [[whs oai:1]componentsSeparatedByString:@"="];
if([kv count]!=2 || ![[kv firstObject]iE:@"height"]){ LOGS(([NSSWF @"falsche height in <img.. zeile: %@",s]));
continue;
}
h = [[kv oai:1]intValue];
if(h<LINEHEIGHT)h=LINEHEIGHT;
pba1 = [MYDD minimalAttributeNamed:[NSSWF @"bild_%i",autoAssoCount++]]; //
pbas = [[PBWOAsso alloc]initWith:self andAttr:pba1];
r = w/raster;
if(w%raster > 0.0)r++;
[pbas setWidth:r * raster]; //lines, height, width
[pbas setHeight:h];
[pbas setIsImage:YES];
goto platzieren;
}
if([s hasSecurePrefix:HTML_PREFIX]){// <html bla-fasel>
s = [s substringFromIndex:[HTML_PREFIX length]];
s = [s substringToIndex:[s length]-1]; //ohne ">"
pbas = [[PBWOAsso alloc]init];
[pbas setIsHTMLCarrier:YES];
[pbas setDbName:s];
goto platzieren;
}
if([s hasSecurePrefix:BLOCK_PREFIX]){// <block x>
s = [s substringFromIndex:[BLOCK_PREFIX length]];
s = [s substringToIndex:[s length]-1]; //ohne ">"
pbas = [[PBWOAsso alloc]init];
[pbas setIsHTMLCarrier:YES];
[pbas setDbName:[NSSWF @"<div class=\"LifBlock\" style=\"width: %ipx;\">",raster * [s intValue]]];
goto platzieren;
}
if([s iE:@"<endblock>"]){// <endblock>
pbas = [[PBWOAsso alloc]init];
[pbas setIsHTMLCarrier:YES];
[pbas setDbName:@"</div>"];
goto platzieren;
}
if([s hasSecurePrefix:RASTER_PREFIX]){// <raster x>
s = [s substringFromIndex:[RASTER_PREFIX length]];
s = [s substringToIndex:[s length]-1]; //ohne ">"
raster = [s intValue];
goto platziert;
}
if([s hasSecurePrefix:@"<descrWidth "]){// <descrWidth x> descrWidth auf x
s = [s substringFromIndex:[@"<descrWidth " length]];
s = [s substringToIndex:[s length]-1]; //ohne ">"
descrWidth = [s intValue];
goto platziert;
}
if([s hasSecurePrefix:@"<editWidth "]){// <editWidth x> editWidth auf x
s = [s substringFromIndex:[@"<editWidth " length]];
s = [s substringToIndex:[s length]-1]; //ohne ">"
editWidth = [s intValue];
goto platziert;
}
if([s hasSecurePrefix:@"<bezWidth "]){// <bezWidth x> bezWidth auf x
s = [s substringFromIndex:[@"<bezWidth " length]];
s = [s substringToIndex:[s length]-1]; //ohne ">"
bezWidth = [s intValue];
goto platziert;
}
if([s iE:RASTER_D]){// <rasterd>
raster = [_APP raster]; //wieder aus config.dict
goto platziert;
}
if([s hasSecurePrefix:ZEILEN_PREFIX]){// <zeilen 8>
s = [s substringFromIndex:[ZEILEN_PREFIX length]];
s = [s substringToIndex:[s length]-1]; //ohne ">"
zeilen=[s intValue];
goto platziert;
}
if([s hasSecurePrefix:NI_PREFIX]){ pbas = [self assoForNIFrom:s];
if(!pbas)continue;
goto platzieren;
}
}
platziert: ;
}
}
- (int)lineHeight;
{ return LINEHEIGHT; //f. wod
}
- (int)descrWidthPixelOr0;
{ if([currentAsso noDescr])return 0;
return [currentAsso descrWidthPixel];
}
- (PBWOAsso *)assoForNIFrom:(NSString *)s;
{// returned eine retained PBWOAsso !
// <namedIcon width=... height=... dbName=... [descr] [bez]> Bild einfuegen: dbName + Wert des Feldes mit "_" verbunden ist Name des gif; descr = descriptor mit anzeigen; bez=bei NamedValues klartext mit anzeigen
int w,h;
NSArray *whs,*kv;
PBDDAttribute *pba1;
NSString *dbName;
PBWOAsso *pbas;
s = [s substringFromIndex:[NI_PREFIX length]];
s = [s substringToIndex:[s length]-1]; //ohne ">"
whs = [s componentsSeparatedByString:@" "];
if([whs count]<3){ LOGS(([NSSWF @"falsche <namedIcon.. zeile: %@",s]));
return nil;
}
kv = [[whs oai:0]componentsSeparatedByString:@"="];
if([kv count]!=2 || ![[kv firstObject]iE:@"width"]){ LOGS(([NSSWF @"falsche width in <namedIcon.. zeile: %@",s]));
return nil;
}
w = [[kv oai:1]intValue];
kv = [[whs oai:1]componentsSeparatedByString:@"="];
if([kv count]!=2 || ![[kv firstObject]iE:@"height"]){ LOGS(([NSSWF @"falsche height in <namedIcon.. zeile: %@",s]));
return nil;
}
h = [[kv oai:1]intValue];
if(h<LINEHEIGHT)h=LINEHEIGHT;
kv = [[whs oai:2]componentsSeparatedByString:@"="];
if([kv count]!=2 || ![[kv firstObject]iE:@"dbName"]){ LOGS(([NSSWF @"kein dbName in <namedIcon.. zeile: %@",s]));
return nil;
}
dbName = [kv oai:1];
pba1 = [myTable plainAttrNamed:dbName];
if(!pba1){ LOGS(([NSSWF @"falscher dbName in <namedIcon.. zeile: %@",s]));
return nil;
}
pbas = [[PBWOAsso alloc]initWith:self andAttr:pba1];
[pbas setWidth:w]; //nicht alignen
[pbas setHeight:h];
[pbas setIsImage:YES];
[pbas setIsNI:YES];
return pbas;
}
- (NSString *)modulName;
{ return guiName;
}
- (NSString *)bundleDoku;
{ if([_SESSION lang]){ NSString *s;
s = [bundle doku1];
if(FILLED(s))return s;
}
return [bundle doku0];
}
- (void)didSetUpWithBundle;
{ [_APP executeScriptNamed:[NSSWF @"%@/didSetUpWithBundle",nameForScript] datasource:self parmDict:parmDict];
}
- (NSString *)name;
{ return [bundle name];
}
- (void)sleep;
{// LOGS(@".........3");
[super sleep];
}
- (WOElement *)_template;
{//wird erst in appendToResponse aufgerufen; da ist bundle schon bekannt;
if(!templ){ NSString *dn = [bundle htmlwodName]; //explizit angegebener geht vor
if([_APP logActions])LOGS(@"..._template");
if(!FILLED(dn))dn = [bundle name]; //sonst mit bundle-Name suchen
[self setTempl:[_APP getTemplateForName:dn]];
if(!templ && !FILLED([bundle htmlwodName])){ //wenn kein explizites angegeben und mit bundle-name nicht gefunden, noch default probieren [self setTempl:[_APP getTemplateForName:@"defaultNew"]];
}
if(!templ){ LOGS(([NSSWF @"html f. Modul %@ konnte nicht erstellt werden",[bundle name]]));
return nil;
}
[self tvfk(templ,@"_template")];
}
return templ;
}
- (PBWOEditor *)callingModul;
{ [callingModul ensureAwakeInContext:[self context]];
return callingModul;
}
- (void)setNextModul:(PBWOEditor *)nm;
{ if(nm == self)return;
if(nm == nextModul)return;
nextModul = nm; //keine retain-Cycles
}
- (PBWOEditor *)nextModul;
{ [nextModul ensureAwakeInContext:[self context]];
return nextModul;
}
- (void)markInitialSearchTookPlace;
{ initialSearchTookPlace = YES;
}
- (void)bringToFront:(PBWOEditor *)m andPerformInitialSearch:(BOOL)andPerformInitialSearch;
{ [m ensureAwakeInContext:[self context]];
if(andPerformInitialSearch)[m performInitialSearch];
[m markInitialSearchTookPlace]; //auf jedenfall das Flag setzen
[self setNextModul:m];
if(![m bundle])return; //beim ersten mal bevor setupWithBundle gelaufen ist
// doch immer refetch, damit Felder richtig gesteuert werden
[m refetchEO];
}
- (void)bringToFrontWithInitialSearch:(PBWOEditor *)m;
{// bei aufrufen aus Menue etc.
[m setCallingModul:MODUL(@"Home")];
[self bringToFront:m andPerformInitialSearch:YES]; //standard; bisherige methode
}
- (void)bringToFront:(PBWOEditor *)m;
{ [self bringToFront:m andPerformInitialSearch:NO]; //standard; bisherige methode
}
- (NSString *)additionalOnLoadFContent;
{// im didBuildUp Eventscript oder sonst wo ins parmDict schreiben
NSString *s = [parmDict ofk:@"additionalOnLoadFContent"];
if(s)return s;
return @"";
}
- (NSString *)additionalScriptContent;
{// im didBuildUp Eventscript oder sonst wo ins parmDict schreiben
NSString *s = [parmDict ofk:@"additionalScriptContent"];
if(s)return s;
return @"";
}
- (NSString *)stdScriptSrc;
{ NSString *scriptf = @"<script src=\"%@/stdScript%i.js\" type=\"text/javascript\"></script>";
if([_SESSION lang]){ return [NSSWF scriptf,[_APP resourceURL],1];
}
return [NSSWF scriptf,[_APP resourceURL],0];
}
- (NSString *)script;
{//hat jedes htlmwod, wo Browser_minimal drin ist;
//- externe URLs und DruckURL in neuem Window oeffnen
//onloadF ausfuehren:
//- auf 1. Feld positionieren
//- submitter clearen
//onLoadF kann erst nach komplettem Laden des Body ausgefuehrt werden;
// wird f. jeden request dynamsich ermittelt; statisches JS ist in stdScript0/1
NSString *onLoadF,*functionContent;
NSString *druckUrl = [_APP urlToOpenInNewBrowser]; //pdf Druck
NSString *externalUrl = [_APP externalUrlToOpenInNewBrowser],*scriptResult;
functionContent = @"document.forms[0].submitter.value=\"\"; document.forms[0].clickedColumnName.value=\"\"; document.forms[0].clickedRowNumber.value=\"\";";
if([_SESSION timeOut]<=10){ NSString *exitScript = [NSSWF @"document.location.assign(\"%@\");", [_APP frameSourceLink]];
if(exitScript)functionContent = [functionContent stringByAppendingString:exitScript];
}
if(externalUrl){ NSString *fcd = [NSSWF @"\n\
wd = window.open(\"\",\"extern\");\n\
wd.close();\n\
wd = window.open(\"%@\",\"extern\");\n\
", externalUrl];
[_APP setExternalUrlToOpenInNewBrowser:nil];
functionContent = [functionContent stringByAppendingString:fcd];
}
if(druckUrl){ NSString *fcd = [NSSWF @"\n\
wd = window.open(\"\",\"DruckPDF\");\n\
wd.close();\n\
wd = window.open(\"%@\",\"DruckPDF\");\n\
", druckUrl];
[_APP setUrlToOpenInNewBrowser:nil];
functionContent = [functionContent stringByAppendingString:fcd];
}
if(!druckUrl && !externalUrl){ NSString *s = [self fieldIDToFocusOn];
if(s) functionContent = [functionContent stringByAppendingString:[NSSWF @" document.getElementById(\"%@\").focus();",s]];
}
functionContent = [functionContent stringByAppendingString:[self additionalOnLoadFContent]];
onLoadF = [NSSWF @"function onLoadF(){ %@ };",functionContent]; scriptResult = [NSSWF @"var submitOnReturn = false;\n%@\n%@",onLoadF,[self additionalScriptContent]];
[self setExternalFieldToFocusOn:nil];
return scriptResult;
}
- (void)resetErrorAssos;
{ int i,j;
PBWOAsso *pbas;
for(i=0,j=[errorAssos count];i<j;i++){ pbas = [errorAssos oai:i];
[pbas resetError];
}
[errorAssos removeAllObjects];
}
- (WOElement *)attributeButtonActed:(NSString *)actionName;
{// vorgeparstes Script oder Druck ausfuehren
PBDDAttribute *pbat = [myTable plainAttrNamed:actionName];
if(!pbat)return self;
[parmDict setSecureObject:selObj forKey:@"p_eo"]; // %selObj immer als p_eo verfuegbar machen, damit buttons auch von anderen Scripts aufgerufen werden koennen;
[parmDict setObject:actionName forKey:@"_actionName"]; //damit er im script abgefragt werden kann
if([pbat isDruck]){ [_APP druckPDFNamed:[pbat scriptName] datasource:self parmDict:parmDict];
}else{ [_APP executeScriptNamed:[pbat scriptName] datasource:self parmDict:parmDict];
}
return self;
}
- (NSArray *)fassosWithName:(NSString *)s;
{ LMA;
int i,j;
for(i=0,j=[fassos count];i<j;i++){ PBWOAsso *pbas = [fassos oai:i];
if([[pbas dbName]iE:s]){ [lma addObject:pbas];
}
}
return lma;
}
- (void)rebuildFassosByName;
{ int i,j;
[fassosByName removeAllObjects];
for(i=0,j=[fassos count];i<j;i++){ PBWOAsso *pbas = [fassos oai:i];
[fassosByName setSecureObject:pbas forKey:[pbas dbName]];
}
}
- (void)bu_dbnames;
{ int i,j;
for(i=0,j=[fassos count];i<j;i++){ PBWOAsso *pbas = [fassos oai:i];
[pbas setGuiName:[pbas dbName]];
}
}
- (NSMutableDictionary *)fassosByName;
{ return fassosByName;
}
- (NSMutableDictionary *)disabledFieldNames;
{ return disabledFieldNames;
}
- (NSMutableDictionary *)enabledFieldNames;
{ return enabledFieldNames;
}
- (NSMutableDictionary *)hiddenFieldNames;
{ return hiddenFieldNames;
}
- (BOOL)paNon;
{ return ([self pendingAction] == pa_non);
}
- (NSString *)paNonS
{ if([self paNon])return @"J"; // no pending action
return @"N";
}
- (NSString *)gotoCurrentLaunchedModuleAction;
{// Action f. Klick auf geoeffnete Module
return [NSSWF @"gotoCurrentLaunchedModule%i",currentLaunchedModuleIndex];
}
- (void)gotoCurrentLaunchedModuleNr:(int)i;
{ [self bringToFront:[[_SESSION launchedModuls]oai:i]];
}
- (WOElement *)doku;
{//Hilfe zum Modul aufrufen
PBWOBundleDoku *e = MODUL(@"doku");
[e setCallingModul:self];
[e loadCustomDoku];
[self bringToFront:e];
return self;
}
- (BOOL)isConfigMode;
{ return isConfigMode;
}
- (WOElement *)exit;
{ [_SESSION terminate];
return self;
}
- (WOElement *)addToPersonal;
{ [_SESSION addToPersonal:self];
return self;
}
- (WOElement *)removeFromPersonal;
{ [_SESSION removeFromPersonal:self];
return self;
}
- (void)closeModule;
{// Modul beenden
// aus instanceDict und launchedModuls raus
// Modulen, die dieses als callingModul gesetzt haben, callingModul clearen;
// auf das Modul davor platzieren in launchedModuls
NSArray *a = [_SESSION launchedModuls];
int i=0,j = [a count]-1;
PBWOEditor *e;
[_SESSION setModulToClose:self]; // hier noch retainen bis man es gefahrlos releasen kann
while(j>=0){ e = [a oai:j];
if(e == self){ [(NSMutableArray *)[_SESSION launchedModuls]removeObjectAtIndex:j];
[(NSMutableDictionary *)[_SESSION instanceDict]removeObjectForKey:[self name]];
i=j-1;
}else{ if([e callingModul]==self){ [e setCallingModul:nil];
}
}
j--;
}
// vorheriges Modul holen
if(i>=0 && [a count]>i){ e = [a oai:i];
}else{ e=MODUL(@"Home");
}
[self bringToFront:e];
}
/*
- retain;
{ if([self retainCount] < 10){ PRINTCURRENTSTACK;
}
return [super retain];
}
*/
- (PBWOEditor *)gotoStart;
{ PBWOEditor *e=nil;
e=MODUL(@"Home");
if(e){ [self bringToFront:e];
return e;
}else{ LOGI(TRANSLATION(@"Probleme mit Home-Modul"));
return self;
}
}
- (WOElement *)gotoHelpdesk;
{ PBWOEditor *e = MODUL(@"HelpdeskV3");
[self bringToFront:(PBWOEditor *)e];
return self;
}
- (WOElement *)gotoZwischenablage;
{ PasteboardEWO *e;
PBSQLQualifier *q;
if(!(e=(PasteboardEWO *)MODUL(@"PasteboardE")))return self;
// auf tabelle und modul vorselektieren, aber nicht cmq setzen;
q = [PBSQLQualifier qualifierWithString:[NSSWF @"eo_entityname = '%@' and modul = '%@'",[myTable dbName],[self name]]];
SUCH_EXTERNAL(e,q);
return self;
}
//f. Assos
- (BOOL)_fieldIsDisabled:(NSString *)s;
{// wird von Asso aufgerufen
if(!s)return NO;
if(allFieldsDisabled && !([enabledFieldNames ofk:s]!=nil))return YES;
return ([disabledFieldNames ofk:s]!=nil);
}
- (BOOL)allFieldsDisabled;
{// das ist etwas anderes als anzeigemodus; nur die Felder werden gesperrt, Funktionen gehen noch;
return allFieldsDisabled;
}
- (void)setAllFieldsDisabled:(BOOL)yn;
{ allFieldsDisabled = yn;
if(!yn)[disabledFieldNames removeAllObjects];
if(yn)[enabledFieldNames removeAllObjects];
}
- (void)setAnzeigemodus:(BOOL)yn;
{ anzeigemodus = yn;
}
- (BOOL)anzeigemodus;
{ return anzeigemodus;
}
- (void)setCreate_ButtonIsDisabled:(BOOL)yn;{create_ButtonIsDisabled=yn;}- (void)setDuplicate_ButtonIsDisabled:(BOOL)yn;{duplicate_ButtonIsDisabled=yn;}- (void)setDelete_ButtonIsDisabled:(BOOL)yn;{delete_ButtonIsDisabled=yn;}//f. htmlwod bindings, die von WO verlangt werden
- (id)ignore;{return nil;}- (void)setIgnore:(id)obj;{}// DialogMode
// confirmation
- (void)confirm_ja;
{ [_SESSION set_rv:@"J"];
[_APP continueScript];
}
- (void)confirm_nein;
{ [_SESSION set_rv:@"N"];
[_APP continueScript];
}
// ---- bis hierher ehemal. PBWOBrowserComponent
ACCESSClassm(tvcSortCol,setTvcSortCol,PBWOTVCCol);
ACCESSClassm(bundle, setBundle, PBWOBundle)
ACCESSClassm(duplicatedObj, setDuplicatedObj, PBEO)
ACCESSm(masterEntityName, setMasterEntityName)
ACCESSClassm(myTable, setMyTable, PBDDTable)
ACCESSClassm(masterEO, setMasterEO, PBEO)
ACCESSClassm(positionsTabellen,setPositionsTabellen,NSArray);
ACCESSClassm(lastCombinedQ, setLastCombinedQ, PBSQLQualifier)
ACCESSClassm(staticQ,setStaticQ,PBSQLQualifier);
ACCESSClassm(callingMQ,setCallingMQ,PBSQLQualifier);
ACCESSClassm(suchFelderQ,setSuchFelderQ,PBSQLQualifier);
ACCESSClassm(ma,setMa,NSMutableArray)
ACCESSClassm(selObj, setSelObj, PBEO)
ACCESSClassm(externalFieldToFocusOn,setExternalFieldToFocusOn,PBWOAsso);
ACCESSm(combiSuchContent,setCombiSuchContent);
ACCESSm(customWidthTF,setCustomWidthTF);
- (int)fetchLimit;
{ return fetchLimit;
}
- (void)setFetchLimit:(int)i;
{ fetchLimit=i;
}
- (NSString *)currentBoxName;
{ return currentBoxName;
}
- (void)setNeedsSave:(BOOL)yn;
{ needsSave = yn;
}
- (NSMutableArray *)visibleTVAttr;
{ return visibleTVAttr;
}
- _componentDefinition;
{ return nil;
}
- init;
{ if(!(self = [super init]))return nil;
MA(fieldsOrControls);
MD(colWidthDict);
MD(allAttr);
MD(lifDict);
MD(portletDict);
MD(boxDict);
MA(errorAssos);
MD(fassosByName);
MD(disabledFieldNames);
MD(enabledFieldNames);
MD(hiddenFieldNames);
MD(changedInRequest);
MA(fassos);
MA(boxNameArray);
MA(boxNameArrayBak);
MA(registerActions);
MA(registerActionsBak);
MD(parmDict);
MD(lifFieldDict);
MA(clearOnSelObjChanged);
MA(refreshOnSelObjChanged);
MA(stateArray);
assoIDCounter = 0;
callingModul=nil;
nextModul=nil;
anzeigemodus = NO;
initialSearchTookPlace = NO;
[self setTempl:nil];
[self setMyTable:nil];
[self setCurrentAction:nil];
[self setBundle:nil];
isConfigMode = NO;
configMode = CONFIGMODE_Detail;
create_ButtonIsDisabled = NO;
duplicate_ButtonIsDisabled = NO;
delete_ButtonIsDisabled = NO;
fieldsOrControlsTags = YES;
fieldsOrControlsButtons = YES;
fieldsOrControlsFields = YES;
fieldsOrControlsFilled = NO;
fieldsOrControlsParms = YES;
fieldsOrControlsSortByUI = YES;
fieldsOrControlsUsed = YES;
fieldsOrControlsUnused = YES;
allFieldsDisabled = NO;
portletIndex = 0;
countCombinedQ = 0;
[self setFetchLimit:[_APP fetchLimit]];
[self setPendingAction:pa_non];
[self setSuchFelderQ:nil]; //wird bei Suchen gesetzt
[self setStaticQ:nil]; //wird in init von customModulen gesetzt
[self setCallingMQ:nil]; //wird in customFindPresel gesetzt
[self setPositionsTabellen:nil];
uebernMode = UEB_NONE;
currentPage = 0;
MA(columns);
MA(filterQs);
MA(visibleTVAttr); // f. configuration
MA(allTVAttr); // f. configuration
selectedObjects = [[NSMutableArray alloc]initWithCapacity:fetchLimit];
ma = [[NSMutableArray alloc]initWithCapacity:fetchLimit];
maOffset = 0;
[self setExternalFieldToFocusOn:nil];
isMaximized = YES;
isMaximizedDetail = YES;
if([_APP logActions])LOGS(@"...init");
return self;
}
- (NSString *)currentPbaDisplayString;
{ NSString *s;
int customWidth;
s = [NSSWF @"%@ (%@)",[currentPba guiNameTrans], [currentPba dbName]];
customWidth = [[colWidthDict ofk:[currentPba dbName]]intValue];
if(customWidth){ s = [s stringByAppendingFormat:@":%i",customWidth];
}else{ s = [s stringByAppendingFormat:@"(%i)",[currentPba widthForColumn]];
}
return s;
}
- (WOElement *)recentlyChanged;
{// zuletzt geaenderte; anzahl fetchlimit; sortierung auf ldate aendern
if(hasStatisticFields){// die TV einstellen, soa erzeugen; nicht speichern;
[self setSoseq:@"ldate:d"];
[self suchInternalQ:nil];
}
return self;
}
- (WOElement *)combiSucheActed;
{// +... Modulkuerzel
//combi-suchfeld fuer suche ueber mehrere textfelder
// leer = alles
// <wert><space>{+,++,+++}{&}// & alle Begriffe and-verknuepft mit wildcards drumherum in allen cs-feldern; max. fetchlimit
// normal hoert suche mit erstem gefundenen auf; erweiterten Suchumfang festlegen mit + ++ +++ bis zu fetchlimit
// Schleife ueber csFelder der Tabelle:
// exakt
// wildcard:
// bei num. Feldern entfaellt WildCard
// bei char Feldern: prefix, infix
NSString *pkn = [myTable primaryKeyName];
NSArray *csa = [myTable csAttrNames];
int i,j;
NSDictionary *returnDict;
NSString *nutzString,*nutzStringWC;
BOOL and_wc = NO;
BOOL extendedSearch = NO;
int min_results = 1;
int extendedSearchLimit = [[[_APP configDict]ofk:@"extendedsearchlimit"]intValue];
LMA;
NSArray *a;
LMAN(nutzStringA);
if(extendedSearchLimit < 1)extendedSearchLimit=10;
[filterQs removeAllObjects];
if(!FILLED(combiSuchContent)){ [self suchInternalQ:nil];
return self;
}
if([combiSuchContent iE:@"?"]){ LOGI(TRANSLATION(@"leer = alles suchen; sonst: Suchbegriff(e)[leer]Steuercodes"));
LOGI(TRANSLATION(@"+,++,+++ fuer mehr Ergebnisse;"));
LOGI(TRANSLATION(@"& fuer Und-verknuepfung aller Begriffe"));
}
// Eventscript combiSucheActed aufrufen; dort koennen Geheimcodes abegfragt werden; erkennt das Script einen
// Geheimcode, fuehrt es die Suche selbst durch und liefert _
returnDict = [_APP executeScriptNamed:[NSSWF @"%@/combiSucheActed",nameForScript] datasource:self parmDict:parmDict];
if([combiSuchContent iE:@"?"])return self;
if([[returnDict ofk:@"scriptRC"] iE:@"N"])return self;
if([combiSuchContent hasSecurePrefix:@"+"] && ![combiSuchContent rangeOfString:@" "].length){ NSString *kuerzel = [combiSuchContent substringFromIndex:1];
if(FILLED(kuerzel)){ PBWOEditor *pbe = [_SESSION instanceForKuerzel:kuerzel];
if(pbe)[self bringToFront:pbe];
return self;
}
}
min_results = [[[_APP configDict]ofk:@"min_results"]intValue];
if(min_results > fetchLimit)min_results=fetchLimit;
if(!min_results){ min_results=1;
if(![[csa firstObject]iE:pkn])min_results = 5; // wenn nicht primaer nach primarykey gesucht wird, mehr treffer;
}
// Eingabe parsen
nutzString = combiSuchContent;
a = [combiSuchContent componentsSeparatedByString:@" "];
if([a count] > 1){ NSString *sc = [a lastObject];
if(FILLED(sc) && [sc isSearchCode]){// falls sc etwas anderes als +,f,& enthaelt, nicht verwenden
if([sc rangeOfString:@"+++"].length){ min_results = fetchLimit;
extendedSearch = YES;
}else if([sc rangeOfString:@"++"].length){ min_results *= 10;
extendedSearch = YES;
}else if([sc rangeOfString:@"+"].length){ min_results *= 3;
extendedSearch = YES;
}
if(min_results > fetchLimit)min_results=fetchLimit;
if([sc rangeOfString:@"&"].length)and_wc = YES;
nutzString = [combiSuchContent substringToIndex:[combiSuchContent length] - ([sc length] + 1)];
}
}
if(and_wc){ a = [nutzString componentsSeparatedByString:@" "];
for(i=0,j=[a count];i<j;i++){ NSString *s = [a oai:i];
if(FILLED(s))[nutzStringA addObject:[NSSWF @"%%%@%%",[s sqlWildCardEscapedString]]];
}
if([nutzStringA count]==0)and_wc = NO;
}
nutzStringWC = [[nutzString sqlWildCardEscapedString]replace:@" " with:@"%"];
if(extendedSearch){ j=[csa count]; // alle suchfelder durchgehen
}else{ j=MIN(extendedSearchLimit,[csa count]); // wenn nicht mind. ein + eingegeben, nur die Felder bis zum extendedSearchLimit durchsuchen
}
countCombinedQ = 0;
for(i=0;i<j;i++){ // schleife ueber zu beruecksichtigende combisuchfelder NSString *csName = [csa oai:i];
PBDDAttribute *pba;
pba = [myTable plainAttrNamed:csName];
if(and_wc){ if([pba dataTyp]!=DT_INT){ LMAN(andQA);
int i1,j1;
for(i1=0,j1=[nutzStringA count];i1<j1;i1++){ // NutzstringA enthaelt die Elemente schon in %..% eingeschlossen
PBSQLQualifier *q = [PBSQLQualifier qualifierWithString:[NSSWF @"%@ like '%@'",csName,[nutzStringA oai:i1]]];
if(q)[andQA addObject:q];
}
if([andQA count]){ [lma addObject:[PBSQLQualifier andQualifierWithArray:andQA]];
if([self sfqArray:lma willReachMin_Results:min_results])break;
}
}
continue; // naechstes Suchfeld
}
if([pba dataTyp]==DT_INT){ if([nutzString isNumeric]){ // INT kann nur mit numerischem nutzstring gesucht werden
// rein numerische Eingabe ohne Spaces: exakter match ist gemeint
[lma addObject:[PBSQLQualifier qualifierWithString:[NSSWF @"%@ = %i",csName,[nutzString intValue]]]];
if([self sfqArray:lma willReachMin_Results:min_results])break;
}
}else{ // exakt
[lma addObject:[PBSQLQualifier qualifierWithString:[NSSWF @"%@ = '%@'",csName,nutzString]]];
if([self sfqArray:lma willReachMin_Results:min_results])break;
// prefix
[lma addObject:[PBSQLQualifier qualifierWithString:[NSSWF @"%@ like '%@%%'",csName,nutzStringWC]]];
if([self sfqArray:lma willReachMin_Results:min_results])break;
// suffix
[lma addObject:[PBSQLQualifier qualifierWithString:[NSSWF @"%@ like '%%%@'",csName,nutzStringWC]]];
if([self sfqArray:lma willReachMin_Results:min_results])break;
// infix
[lma addObject:[PBSQLQualifier qualifierWithString:[NSSWF @"%@ like '%%%@%%'",csName,nutzStringWC]]];
if([self sfqArray:lma willReachMin_Results:min_results])break;
}
}
if(!countCombinedQ){ // min_result wurde nicht erreicht [self setSuchFelderQ:[PBSQLQualifier orQualifierWithArray:lma]];
}
[self evaluateQualifiers];
return self;
}
- (BOOL)sfqArray:(NSArray *)lma willReachMin_Results:(int)min_results;
{// nur interne Methode f. combiSuche
// testet, ob ein aus dem lma als or-qualifiert gebauter potentieller suchfelderq genuegend Treffer ergibt
// wenn ja, wird suchfelderQ, countCombinedQ und lastCombinedQ gesetzt
PBSQLQualifier *combined_cand,*sfq_cand;
int countq;
if(!lma || ![lma count])return NO;
sfq_cand = [PBSQLQualifier orQualifierWithArray:lma];
combined_cand = [self combinedQWith:sfq_cand];
countq = [self countQ:combined_cand];
if(countq>=min_results){ countCombinedQ = countq;
[self setSuchFelderQ:sfq_cand];
[self setEffectiveCombinedQ:combined_cand];
return YES;
}
return NO;
}
- (BOOL)hasRegister;
{ return FILLED([self registerFieldDBName]);
}
- (NSString *)registerFieldDBName;
{ return [bundle registerFieldDBName];
}
- (NSString *)registerFieldGuiName;
{ return [[myTable plainAttrNamed:[self registerFieldDBName]]guiNameTrans];
}
- (NSString *)wasDuplicate;
{ return (wasDuplicate?@"J":@"N");
}
- (void)setUpWithBundle:(PBWOBundle *)b;
{ NSString *en;
PBDDAttribute *pbat;
if(!b)return;
[self setBundle:b]; //wg. name
[self setNameForScript:[self name]];
if([_SESSION lang]){ NSString *s = [b guiName1];
if(!FILLED(s))s=[b guiName];
[self setGuiName:s];
}else{ [self setGuiName:[b guiName]];
}
en = [[self bundle]entityName];
if(FILLED(en)){ [self setMyTable:[MYDD tableNamed:en]];
[self setPositionsTabellen:[MYDD positionsTabellenForTablenamed:en]];
}
hasStatisticFields = ([myTable hasStatisticFields]);
[self determineStaticBerecht];
[self setAnzeigemodus:(![self hasEditierBerecht])];
isPosition = NO; //master-detail -> detail
needsMasterEO = ![b needsNoMasterEO];
hasPositionsnr = NO;
wasDuplicate = NO;
if((pbat = [myTable plainAttrNamed:@"masterkey"])){ //calling modul muss masterEntityName als myTable haben u. selObj; masterkey ist dann [selObj primaryKey] if(FILLED([pbat refdTableName])){ isPosition = YES;
[self setMasterEntityName:[pbat refdTableName]];
if([myTable plainAttrNamed:@"positionsnr"]){ hasPositionsnr = YES; //wird dann autom. hochgezaehlt
}
}
}
[self setCallingModul:nil];
[self determineAttributes];
[self determineRegisterActions];
[self loadLif];
[self buildUpTVAndRegisters]; // macht u.a. builduptv
[self setSoseq:[[_SESSION moduleSoseq] ofk:[self name]]];
// nicht immer; nur wenn aus Menue heraus aufgerufen wird; sonst kann es passieren, dass ein gesperrter Satz in selObj steht und Actions aus Scripts nicht mehr gehen; [self performInitialSearch]
[parmDict setObject:[self name] forKey:@"modulname"];
[parmDict setSecureObject:[[self myTable]dbName] forKey:@"mytable"];
[self didSetUpWithBundle];
}
- (void)performInitialSearch;
{// f. subclasses
if(initialSearchTookPlace)return;
if(![[myTable type] iE:SC_Abstract] && ![bundle initialSearchOff]){ [self evaluateQualifiers];
}
initialSearchTookPlace = YES;
}
- (NSMutableArray *)allExceptVisibleTVAttr;
{ LMA;
int i,j;
PBDDAttribute *pba;
for(i=0,j=[allTVAttr count];i<j;i++){ int tt;
pba = [allTVAttr oai:i];
tt = [pba targetTyp];
if(([visibleTVAttr indexOfObject:pba]==NSNotFound) && (tt == ATTVCSELOBJ))[lma addObject:pba];
}
[lma sortUsingKeyOrderArray:[NSArray soaCaseInsensitiveFrom:@"guiName"]];
return lma;
}
- (NSString *)currentPbaGuiName;
{ NSString *s=nil,*dbn=[currentPba dbName];
if([dbn hasSecurePrefix:NI_PREFIX])return dbn;
if([selectedObjects count] && ![dbn iE:@"cryptedpw"]){ PBEO *eo = [selectedObjects firstObject];
s = [[eo values] ofk:dbn];
}
if(!FILLED(s))return [NSSWF @"%@ (%@)",[currentPba guiNameTrans],dbn];
return [[NSSWF @"%@ (%@) [%@]",[currentPba guiNameTrans],dbn,s]abbrevToLength:50];
}
- (BOOL)mayLeaveConfig;
{//wenn spalten, dann muessen auch attribute configuriert werden
return (![self colCount] || [visibleTVAttr count]>0);
}
- (WOElement *)removeFromVisibleTVAttr;
{ int i,j;
for(i=0,j=[selectedVisibleTVAttrs count];i<j;i++){ [visibleTVAttr removeObject:[selectedVisibleTVAttrs oai:i]];
}
return self;
}
- (WOElement *)setCustomWidth;
{ int i,j,customWidth = [customWidthTF intValue];
if(customWidth < 0)customWidth=0;
if(customWidth > 400)customWidth=400;
for(i=0,j=[selectedVisibleTVAttrs count];i<j;i++){ PBDDAttribute *pba = [selectedVisibleTVAttrs oai:i];
if(!customWidth){ [colWidthDict removeObjectForKey:[pba dbName]];
}else{ [colWidthDict setObject:NSS(customWidth) forKey:[pba dbName]];
}
}
return self;
}
- (WOElement *)addToVisibleTVAttr;
{ //hinter selektiertes einfuegen
int i,j,ip=0;
PBDDAttribute *pba;
if((pba = [selectedVisibleTVAttrs firstObject])){ ip = [visibleTVAttr indexOfObject:pba];
}
if(ip < 0)ip = 0; //insertion point
for(i=0,j=[selectedAllTVAttrs count];i<j;i++){ int eip = ip + i;
pba = [selectedAllTVAttrs oai:i];
if(eip >= [visibleTVAttr count]){ [visibleTVAttr addObject:pba];
}else{ [visibleTVAttr insertObject:pba atIndex:ip+i];
}
}
return self;
}
- (WOElement *)visibleTVAttrUp;
{ return [self visibleTVAttrDirection:-1];
}
- (WOElement *)visibleTVAttrDown;
{ return [self visibleTVAttrDirection:1];
}
- (WOElement *)visibleTVAttrDirection:(int)direction;
{ PBDDAttribute *pba;
int ip;
if((pba = [selectedVisibleTVAttrs firstObject])){ ip = [visibleTVAttr indexOfObject:pba];
if(ip == NSNotFound)return self;
[visibleTVAttr removeObjectAtIndex:ip];
ip+=direction;
if(ip<0)ip=0;
if(ip>=[visibleTVAttr count]){ [visibleTVAttr addObject:pba];
}else{ [visibleTVAttr insertObject:pba atIndex:ip];
}
}
return self;
}
- (WOElement *)visibleTVAttrMoveToTargetPos;
{ PBDDAttribute *pba;
int ip,nip,amount,direction=0;
if([visibleAttrTargetPos hasSecurePrefix:@"+"]){ amount=[[visibleAttrTargetPos substringFromIndex:1] intValue];
direction = 1;
}else if([visibleAttrTargetPos hasSecurePrefix:@"-"]){ amount=[[visibleAttrTargetPos substringFromIndex:1] intValue];
direction = 2;
}else{ amount=[visibleAttrTargetPos intValue];
}
if((pba = [selectedVisibleTVAttrs firstObject])){ ip = [visibleTVAttr indexOfObject:pba];
if(ip == NSNotFound)return self;
[visibleTVAttr removeObjectAtIndex:ip];
if(direction == 1){ nip = ip + amount;
}else if(direction == 2){ nip = ip - amount;
}else{ nip = amount;
if(nip > ip)nip--; //da urspr. pba jetzt draussen
}
if(nip<0)nip=0;
if(nip>=[visibleTVAttr count]){ [visibleTVAttr addObject:pba];
}else{ [visibleTVAttr insertObject:pba atIndex:nip];
}
}
return self;
}
- (void)executetempscript;
{// wird von Button in System-Register aufgerufen
if([_APP isSecure]){ LOGI(TRANSLATION(@"Durch Commandline-Option -secure unterbunden"));
return;
}
SCRIPT([parmDict ofk:@"tempscript"]);
}
- (PBWOEditor *)datasource;
{ return self;
}
- (void)createexamplescript;
{ NSString *script = EON;
NSString *templateTempScript = [NSSWCOF [NSSWF @"%@/TempScriptTemplate.txt",MANDANTPATH]];
if(!templateTempScript)templateTempScript = [NSSWCOF [NSSWF @"%@/TempScriptTemplate.txt",GLOBALCONFIGPATH]];
if(!templateTempScript){ LOGS(@"TempScriptTemplate.txt nicht gefunden");
return;
}
script = [NSSWF templateTempScript,[myTable dbName]];
script = [script stringByAppendingString:[_APP attributAuflistungForTable:myTable withDoku:YES]];
[parmDict setSecureObject:script forKey:@"tempscript"];
}
- (void)savetempscript;
{// wert aus tempscriptname ist filename
NSString *fn;
if([_APP isSecure]){ LOGI(TRANSLATION(@"Durch Commandline-Option -secure unterbunden"));
return;
}
if(!FILLED([parmDict ofk:@"tempscriptname"])){ LOGI(TRANSLATION(@"bitte Filename angeben"));
return;
}
fn = [NSSWF @"%@/Scripts/%@/%@",MANDANTPATH,[self name],[parmDict ofk:@"tempscriptname"]];
[myFM createAllDirsAtPath:[fn stringByDeletingLastPathComponent]];
[[parmDict ofk:@"tempscript"] WTF:fn];
}
- (void)loadtempscript;
{// wert aus tempscriptname ist filename
NSString *fn;
if(!FILLED([parmDict ofk:@"tempscriptname"])){ LOGI(TRANSLATION(@"bitte Filename angeben"));
return;
}
fn = [NSSWF @"%@/Scripts/%@/%@",MANDANTPATH,[self name],[parmDict ofk:@"tempscriptname"]];
[parmDict setSecureObject:[NSSWCOF fn] forKey:@"tempscript"];
}
- (void)listtempscript;
{// aus mandantendirectory Scripts/mdodulname alle filenamen lesen und in tempscript stellen
NSString *scriptPath = [NSSWF @"%@/Scripts/%@",MANDANTPATH,[self name]];
NSArray *a = [myFM directoryContentsAtPath:scriptPath];
[parmDict setSecureObject:[a componentsJoinedByString:@"\n"] forKey:@"tempscript"];
}
- (void)buildUpTVAndRegisters;
{ NSMutableArray *pa = [NSMutableArray arrayWithCapacity:10];
NSArray *a,*lifTV;
NSMutableArray *lifa;
int attrC;
int i,j;
NSString *k;
[visibleTVAttr removeAllObjects];
[colWidthDict removeAllObjects];
[allTVAttr removeAllObjects];
[allTVAttr addObjectsFromArray:[allAttr allValues]]; //f. config-Sicht
[self addNamedIconsToAllTVAttr]; //dummy Attribute f. namedIcons reinmachen
lifTV = [lifDict ofk:SC_LIF_TV]; //Auswahl u. Reihenfolge der Spalten
if(lifTV){ for(i=0,j=[lifTV count];i<j;i++){ //enthaelt namen NSString *s = [lifTV oai:i];
PBDDAttribute *pba;
if([s hasSecurePrefix:NI_PREFIX]){ pba = [MYDD minimalAttributeNamed:s];
[pba setGuiName:s];
[pba setLength:1];
}else{ NSArray *a1 = [s componentsSeparatedByString:@":"];
if([a1 count]>1){ int customWidth = [[a1 oai:1]intValue];
NSString *k = [a1 firstObject];
if(customWidth < 0)customWidth = 0;
if(customWidth > 400)customWidth = 400;
pba = [allAttr ofk:k];
[colWidthDict setObject:NSS(customWidth) forKey:k];
}else{ pba = [allAttr ofk:s];
}
}
if(!pba)continue; //gar kein attr.
if(![pba isAuthorized])continue;
[visibleTVAttr addObject:pba];
if([visibleTVAttr count] >= NUM_OF_COL_TO_SHOW)break;
}
}else{ [allTVAttr sortUsingSelector:@selector(compareForSequence:)]; //damit wichtigste felder vorne sind
for(i=0,j=[allTVAttr count];i<NUM_OF_COL_TO_SHOW && i<j;i++){ [visibleTVAttr addObject:[allTVAttr oai:i]];
}
}
[self buildUpTV:visibleTVAttr];
a = [[lifDict allKeys]sortedArrayUsingSelector:@selector(compareBySecondIntField:)];
attrC = 0;
[boxDict removeAllObjects];
[boxNameArray removeAllObjects];
assoIDCounter = 0;
[clearOnSelObjChanged removeAllObjects];
[refreshOnSelObjChanged removeAllObjects];
[[self _subcomponents] removeAllObjects];
[fassos removeAllObjects]; // sind schon TV cAssos drin, die wir nicht wollen
portletIndex = 0;
for(i=0,j=[a count];i<j;i++){ //box names k = [a oai:i];
if([k iE:SC_LIF_Unres] || [k iE:SC_LIF_Unknown] || [k iE:SC_LIF_TV] || [k iE:@"soseq"] || [k iE:SC_LIF_SS] ){ continue;
}
lifa = [lifDict ofk:k];
[self filterAttrNames:lifa pa:pa]; //in pa stehen dann nur noch die bekannten, die es als attribute auch gibt
attrC += [pa count]; //feststellen, ob Felder verbaut werden
[self buildUpFields:pa forTitle:[self nameForLifdictKey:k]];
}
if(!attrC){ //bisher wurden keine Felder verbaut -> wahrscheinlich neues Modul, kein Lif, daher alle bekannten verbauen [self buildUpFields:[[allAttr allValues]sortedArrayUsingSelector:@selector(compareForSequence:)] forTitle:@"Felder"];
}
[self rebuildFassosByName];
[_APP executeScriptNamed:[NSSWF @"%@/didBuildUp",nameForScript] datasource:self parmDict:parmDict];
[boxNameArrayBak removeAllObjects];
[boxNameArrayBak addObjectsFromArray:boxNameArray];
[registerActionsBak removeAllObjects];
[registerActionsBak addObjectsFromArray:registerActions];
}
- (void)removeRegisterActionWithGuiName:(NSString *)s;
{ int i;
for(i=[registerActions count]-1;i>=0;i--){ PBActionO *pbaction = [registerActions oai:i];
if([[pbaction guiName]iE:s])[registerActions removeObjectAtIndex:i];
}
}
- (void)restoreBoxNameArray;
{ [boxNameArray removeAllObjects];
[boxNameArray addObjectsFromArray:boxNameArrayBak];
[registerActions removeAllObjects];
[registerActions addObjectsFromArray:registerActionsBak];
}
- (void)createStdScripts;
{ LOGI(@"neu machen wie in Workbench; auch Edit-Buttons der Workbench");
}
- (NSString *)printFormAuflistung;
{ NSString *s = EON;
int ii,jj;
NSArray *a1 = [myTable plainAttributes];
s = [s stringByAppendingString:@"// %selObj hat diese Attribute:\n"];
for(ii=0,jj=[a1 count];ii<jj;ii++){ PBDDAttribute *pba = [a1 oai:ii];
s = [s stringByAppendingFormat:@"gosub checkPage\nv $sp1,$ty,l,'%@\nv $sp2,$ty,l,%%*.%@\n$ty,+,$cr\n",[pba guiName],[pba dbName]];
if([pba hasVL]){ int i1,j1;
for(i1=0,j1=[[pba vl]count];i1<j1;i1++){ PBVLO *pbvlo = [[pba vl]oai:i1];
s = [s stringByAppendingFormat:@"//\t\t%@\t%@\n",[pbvlo value],[pbvlo bez]];
}
}
}
return s;
}
- (void)addNamedIconsToAllTVAttr;
{//alle im lifDict vorkommenden namedIcons auch in allTVAttr als dummy-Attribute rein
//damit koennen Sie in visibleTVAttr ruebergeklickt werden und werden in lifTV gespeichert
//und es koennen TV-Assos daraus gemacht werden, um die NamedIcons auch anzuzeigen in der richtigen Spalte
NSArray *lifDictArrays = [lifDict allObjects];
int i,j;
for(i=0,j=[lifDictArrays count];i<j;i++){ NSArray *a = [lifDictArrays oai:i];
int i1,j1;
if(![a isKindOfClass:[NSArray class]])continue; // soseq ist string, gibt's aber nimmer
for(i1=0,j1=[a count];i1<j1;i1++){ NSString *s = [a oai:i1];
PBDDAttribute *pba;
if(![s hasSecurePrefix:NI_PREFIX])continue;
pba = [MYDD minimalAttributeNamed:s];
[pba setGuiName:s];
[pba setLength:1];
[allTVAttr addObjectUniq:pba];
}
}
}
- (void)redrawAfterLeaveConfig;
{ [self setTempl:nil];
[self determineRegisterActions];
[self buildUpTVAndRegisters];
[self didSetUpWithBundle];
}
- (void)buildUpTV:(NSArray *)aa;
{ int i,j,nocts = NUM_OF_COL_TO_SHOW;
PBDDAttribute *pba;
NSString *dbn;
PBWOAsso *pbas;
PBWOTVCCol *column;
//columns aufbauen
//reentrant f. redrawAfterLeaveConfig
//LOGS(@"builduptv");
//reihenfolge beibehalten aus LIF
[columns removeAllObjects];
for(i=0,j=[aa count];i<j;i++){ BOOL isNI;
pba = [aa oai:i];
if(!FILLED(pba))continue; //wg. EON
dbn = [pba dbName];
isNI = [dbn hasSecurePrefix:NI_PREFIX]; //named Icon
if(!isNI){ if([pba targetTyp] != ATTVCSELOBJ)continue;
if(![pba isVisible]){ continue;
}
}
if([columns count] >= nocts)break;
if(isNI){ pbas = [self assoForNIFrom:dbn];
[pbas setWidth:LINEHEIGHT]; //masse vom lif interessieren hier nicht
[pbas setHeight:LINEHEIGHT];
}else{ pbas = [[PBWOAsso alloc]initWith:self andAttr:pba];
}
column = [[PBWOTVCCol alloc]initWithWOAsso:pbas];
[columns addObject:column];
[pbas release];
[column release];
}
}
- (PBWOTVCCol *)columnWithName:(NSString *)s;
{// zum einfachen umkonfigurieren in scripts
int i,j;
if(!FILLED(s))return nil;
for(i=0,j=[columns count];i<j;i++){ PBWOTVCCol *col = [columns oai:i];
if([[col dbName]iE:s])return col;
}
return nil;
}
- (void)dealloc
{ [fieldsOrControls release];
[selectedFields release];
[selectedFieldsOrControls release];
[colWidthDict release];
[fieldsInSelectedRegister release];
[currentRegister release];
[selectedRegister release];
[disabledFieldNames release];
[portletDict release];
[stateArray release];
[changedInRequest release];
[enabledFieldNames release];
[hiddenFieldNames release];
[registerActions release];
[lifFieldDict release];
[selectedRegisterModify release];
[newRegisterName release];
[commonBox release];
[suchabfrButtons release];
[nameForScript release];
[currentFieldItem release];
[clearOnSelObjChanged release];
[refreshOnSelObjChanged release];
[fieldTargetPos release];
[lifEditArea release];
[lastLifPath release];
[selectedField release];
[currentFieldInSelectedRegister release];
[parmDict release];
[allAttr release];
[errorAssos release];
[fassos release];
[fassosByName release];
[boxNameArray release];
[boxNameArrayBak release];
[registerActionsBak release];
[boxDict release];
[lifDict release];
[myTable release];
[guiName release];
[selectedBoxName release];
[currentAction release];
[bundle release];
[templ release];
[waitingForName release];
[masterEO release];
[tvcSortCol release];
[positionsTabellen release];
[customWidthTF release];
[lastCombinedQ release];
[suchFelderQ release];
[staticQ release];
[visibleTVAttr release];
[allTVAttr release];
[callingMQ release];
[masterEntityName release];
[duplicatedObj release];
[ma release];
[soa release];
[externalFieldToFocusOn release];
[selectedObjects release];
[selObj release];
[columns release];
[filterQs release];
[combiSuchContent release];
[tvNewSearchInSortCol release];
[soseq release];
[super dealloc];
}
- (BOOL)mayOffsetWeiter;
{ if(needsSave || ![self paNon])return NO;
if([ma count] == fetchLimit)return YES;
return NO;
}
- (NSString *)offsetS;
{ return NSS(maOffset);
}
- (int)maOffset; { return maOffset;}- (int)countCombinedQ; { return countCombinedQ;}- (NSString *)offsetWeiterS;
{ return TRANSLATION(@"weitere Seiten");
}
- (NSString *)offsetZurueckS;
{ return TRANSLATION(@"vorherige Seiten");
}
- (void)offsetWeiter;
{ if(![self mayOffsetWeiter])return;
LOG_ACTION;
maOffset += fetchLimit;
[self neuSuchen]; //mit lastCombinedQ
}
- (BOOL)mayOffsetZurueck;
{ if(needsSave || ![self paNon])return NO;
if(maOffset >= fetchLimit)return YES;
return NO;
}
- (void)offsetZurueck;
{ if(![self mayOffsetZurueck])return;
LOG_ACTION;
maOffset -= fetchLimit;
[self neuSuchen]; //mit lastCombinedQ
}
- (NSString *)callingModulName;
{ NSString *s = [[self callingModul] guiName];
if(isPosition){ if(masterEO){ if(!FILLED(s)){ return [NSSWF @"(%@)",[masterEO primaryKey]];
}else{ return [NSSWF @"(%@ %@)",s,[masterEO primaryKey]];
}
}else{ if(!FILLED(s)){ return @"---";
}else{ return [NSSWF @"(%@ ---)",s];
}
}
}else{ if(!FILLED(s))return EON;
return [NSSWF @"(%@)",s];
}
}
- (BOOL)ruecksprung_ButtonIsDisabled;
{ return (![self paNon] || callingModul == nil);
}
- (BOOL)suche_ButtonIsDisabled;
{ return ![self paNon];
}
- (BOOL)recentlyChanged_BuIsDisabled;
{ return !hasStatisticFields;
}
- (BOOL)create_ButtonIsDisabled;
{ return (create_ButtonIsDisabled || ![self paNon] || [self anzeigemodus] || (isPosition && needsMasterEO && !masterEO));
}
- (BOOL)duplicate_ButtonIsDisabled;
{ return (duplicate_ButtonIsDisabled || ![self paNon] || [self anzeigemodus] || (isPosition && needsMasterEO && !masterEO) || selObj==nil);
}
- (BOOL)delete_ButtonIsDisabled;
{// wenn geaendert, wuerde bei will/didDelete mit ungesicherten Eingabewerten gearbeitet werden;
// z.B. LS-Pos, menge veraendern, nicht sichern, loeschen -> Lagerbestand stimmt nicht mehr
return (delete_ButtonIsDisabled || pendingAction == pa_upd || [self anzeigemodus] || (isPosition && needsMasterEO && !masterEO) || [[self selectedObjects] count] == 0);
}
- (BOOL)save_ButtonIsDisabled;
{ return (!selObj || [self anzeigemodus]);
}
- (BOOL)undo_ButtonIsDisabled;
{ return !needsSave;
}
- (BOOL)bookmark_ButtonIsDisabled;
{ return ( ![self paNon] || ([selectedObjects count]==0));
}
- (BOOL)refetchEO_ButtonIsDisabled;
{ return (![self paNon] || !selObj);
}
- (void)bookmark; //selObj bookmarken, falls EO
{ int i,j;
if([self bookmark_ButtonIsDisabled])return;
LOG_ACTION;
j = [selectedObjects count];
for(i=0;i<j;i++){ PBEO *eo = [selectedObjects oai:i];
if([eo isKindOfClass:[PBEO class]]){// hier pasteboard satz schreiben; keine Doubletten
PBEO *pb;
NSString *pk = [eo primaryKey],*qf;
if(!FILLED(pk))continue;
qf = [NSSWF @"eo_pk = '%@' and eo_entityname = '%@' and modul = '%@'",pk,[eo entityName],[self name]];
if(testExistQf(@"pasteboard",qf))continue;
pb = NEW_EO(@"pasteboard");
[pb tvfk(pk,@"eo_pk")];
[pb tvfk([eo entityName],@"eo_entityname")];
[pb tvfk([eo descri],@"eo_descr")];
[pb tvfk([self name],@"modul")];
[pb tvfk([self guiName],@"modulgui")];
[pb tvfk([myTable guiName],@"eo_tablegui")];
INSRT(pb);
}
}
}
- (void)setCallingModul:(PBWOEditor *)m;
{//macht uebernMode aus
//setzt callingMQ auf nil
//dieser muss danach, falls benoetigt gesetzt werden
[self setUebernMode:UEB_NONE];
[self setCallingMQ:nil];
if(m==self)return;
if(m != callingModul){ [callingModul release];
callingModul = [m retain];
}
[callingModul ensureAwakeInContext:[self context]];
}
- (void)addEo:(PBEO *)someObject;
{ //interne Methode;
[self setPendingAction:pa_ins];
[ma addObject:someObject];
[self positionTo:BOT];
[self setNeedsSave:YES];
}
- (void)_selObjChanged;
{ // im prinzip nix zu tun, da alles dynamisch bestimmt wird, insbes. prepareData
// in subClasses evt. f. Cacheing-Funktionalitaet nutzen, z.B. bei dynamic Editoren
// PRINTCURRENTSTACK;
[parmDict setSecureObject:selObj forKey:@"p_eo"];
[_APP executeScriptNamed:[NSSWF @"%@/selObjChanged",nameForScript] datasource:self parmDict:parmDict];
[clearOnSelObjChanged makeObjectsPerformSelector:@selector(clear)]; // cleared Portlets, die sich dafuer registriert haben
[refreshOnSelObjChanged makeObjectsPerformSelector:@selector(refresh)]; // refreshed Portlets, die sich dafuer registriert haben
}
- (void)ausZwischenablage;
{// such-Qualifier weg und neu bilden aus Saetzen, die in zwischenablage liegen fuer die Tabelle
// Schluessel besorgen
NSArray *a = [_APP getStringArrayAsResultFrom:[NSSWF @"select eo_pk from pasteboard where eo_entityname = '%@'",[myTable dbName]]];
if([a count]){ PBSQLQualifier *q = [PBSQLQualifier orQualiFromArray:a forDbName:[myTable primaryKeyName]];
[self suchInternalQ:q];
}else{ LOGI(TRANSLATION(@"nichts geeignetes in Pasteboard"));
}
}
- (void)ausHistorie;
{// such-Qualifier weg und neu bilden aus Saetzen, die in session.$table_keys liegen fuer die Tabelle
// Schluessel besorgen
NSArray *a = [[_SESSION parmDict]ofk:[NSSWF @"%@_keys",[myTable dbName]]];
if([a count]){ PBSQLQualifier *q = [PBSQLQualifier orQualiFromArray:a forDbName:[myTable primaryKeyName]];
{// entspricht suchinternal
[self setSuchFelderQ:q];
[filterQs removeAllObjects];
[self evaluateQualifiers];
{// aufruffolge noch setzen
int i,j;
for(i=0,j=[ma count];i<j;i++){ PBEO *eo = [ma oai:i];
[eo tvfk((NSS([a indexOfObject:[eo primaryKey]])),@"aufruffolge")];
}
}
}
}
}
- (void)ruecksprung;
{//reiner ruecksprung zu callingmodul
if([self ruecksprung_ButtonIsDisabled])return;
LOG_ACTION;
if([self callingModul]){ [callingModul refetchEO]; //prueft selbst pa_non; autom. aktualisieren;
[callingModul setExternalFieldToFocusOn:[callingModul waitingForName]];
[callingModul setWaitingForName:nil];
[self bringToFront:callingModul];
[self setCallingModul:nil]; //cleared auch callingMQ
}
}
- (void)determineAttributes;
{ [allAttr removeAllObjects];
[allAttr addEntriesFromDictionary:[NSDictionary lookupDictForArray:[myTable plainAttributes] key:@"dbName"]];
//evt. noch weitere attr. hier dazu nehmen aus best. abstract tables oder im bundle angegebene
//evt. irgendwelche davon wegnehmen
//statisch invisible auf jeden Fall raus
[allAttr removeObjectsForKeys:[myTable dbNamesNotVisible]];
}
/*
obsolet; war nicht so toll;
- (NSArray *)allFilledAttr;
{// nur Attribute aus allAttr, die auch was in der DB haben
NSArray *a = [allAttr allValues];
LMA;
int i,j;
unsigned int total;
double min_perc = 0.05; //mindestens soviel muessen gefuellt sein, damit das Feld angezeigt wird
double filled_perc;
if(![myTable isRealTable])return a;
total = [[_APP getSingleValueAsResultFrom:[NSSWF @"select count(*) from %@",[myTable dbName]]]intValue];
if(!total)return a; //table ganz leer
for(i=0,j=[a count];i<j;i++){ PBDDAttribute *pba = [a oai:i];
int tt = [pba targetTyp];
int dt = [pba dataTyp];
int filled;
if(tt==ATBU || tt==ATTVCPD || tt==ATPORTLET){ [lma addObject:pba];
continue;
}
if(![pba isDB]){ [lma addObject:pba];
continue;
}
if(dt==DT_CHAR || dt==DT_BOOL || dt==DT_CHAR_FIX){ filled = [[_APP getSingleValueAsResultFrom:[NSSWF @"select count(*) from %@ where (%@ <> '' and %@ is not null)",[myTable dbName],[pba dbName],[pba dbName]]]intValue];
}else if(dt==DT_MONEY || dt==DT_INT || dt==DT_FLOAT || dt==DT_DATE || dt==DT_DATETIME){ filled = [[_APP getSingleValueAsResultFrom:[NSSWF @"select count(*) from %@ where (%@ <> 0 and %@ is not null)",[myTable dbName],[pba dbName],[pba dbName]]]intValue];
}else{ filled = 0;
}
filled_perc = (double)filled / (double)total;
// LOGS(([NSSWF @"%@ filled %i of %i (%0.2f %%)",[pba dbName],filled,total,filled_perc * 100]));
if(filled_perc < min_perc)continue;
[lma addObject:pba];
[pba setCustom:NSS(filled)];
}
return lma;
}
*/
- (void)createDefaultLayout;
{ LMA;
LMAN(lmatv);
int i,j;
NSArray *a = [allAttr allValues];
PBDDTable *ago = [MYDD tableNamedCheap:@"_AGENERAL_O"];
PBDDTable *vid_g = [MYDD tableNamedCheap:@"_VID_GENERAL"];
for(i=0,j=[a count];i<j;i++){ PBDDAttribute *pba = [a oai:i];
NSString *s = [pba dbName];
int tt = [pba targetTyp];
//diese attribute ausnehmen; sie kommen ins System-Tab
if(![ago plainAttrNamed:s] && ![vid_g plainAttrNamed:s]){ [lma addObjectUniq:s];
if(tt==ATBU || tt==ATTVCPD || tt==ATPORTLET)continue;
if([lmatv count]<7)[lmatv addObjectUniq:s];
}
}
[lma sort];
[lmatv sort];
[lifDict setSecureObject:lma forKey:@"a|200|Detail-Ansicht"];
[self addScriptTab];
[lifDict setSecureObject:lmatv forKey:SC_LIF_TV];
[lifDict setObject:[NSMutableArray array] forKey:SC_LIF_COMMON];
[lifDict setObject:[NSMutableArray array] forKey:SC_LIF_SUCHABFR];
}
- (BOOL)hasEditierBerecht;
{ return hasEditierBerecht; //Editierberechtigung
}
- (void)setHasEditierBerecht:(BOOL)yn;
{ hasEditierBerecht = yn;
}
- (void)determineStaticBerecht;
{ hasEditierBerecht = YES; //schliesst moneyfields mit ein
//sonderflags ziehen staerker als ModulBerechtigungen
if(IS_ROOT){ return;
}
if([_SESSION readOnly]){ hasEditierBerecht = NO;
}
}
- (BOOL)notInserting;
{ return ((pendingAction != pa_ins));
}
- (NSString *)notInsertingS;
{// f. Scripting
return ([self notInserting]?@"J":@"N");
}
- (NSString *)insertingS;
{// f. Scripting
return ([self notInserting]?@"N":@"J");
}
- (BOOL)notRoot;
{ return !IS_ROOT;
}
- (void)setUebernMode:(int)i;
{ uebernMode = i;
}
- (int)uebernMode;
{ return uebernMode;
}
- (int)pendingAction;{return pendingAction;}- (void)setPendingAction:(int)v;
{ pendingAction = v;
}
- (BOOL)needsSave;{return needsSave;}- (void)aValueChanged;
{ if([self paNon]){ [self setPendingAction:pa_upd];
[self setNeedsSave:YES];
// PRINTCURRENTSTACK;
}
}
- (PBSQLQualifier *)rechercheQ;
{ LMA;
PBSQLQualifier *q;
if(suchFelderQ)[lma addObject:suchFelderQ];
if(staticQ)[lma addObject:staticQ];
if(![lma count]){ q = nil;
}else{ q = [PBSQLQualifier andQualifierWithArray:lma];
}
return q;
}
- (PBSQLQualifier *)combinedQ;
{ return [self combinedQWith:suchFelderQ];
}
- (PBSQLQualifier *)combinedQWith:(PBSQLQualifier *)sfq;
{//wann immer gesucht wird, wird es mit diesem Qualifier getan; er wird ueber suchFelderQ oder callingMQ indirekt beeinflusst
LMA;
PBSQLQualifier *q;
// normalerweise dynamisch gesetzt
if(sfq)[lma addObject:sfq]; // kann auch PBNOTHINGQualifier oder PBALLQualifier sein
if(callingMQ)[lma addObject:callingMQ];
// in init oder setupWithBundle gesetzt
if(staticQ)[lma addObject:staticQ];
// Filter dazu
[lma addObjectsFromArray:filterQs];
if(![lma count]){ q = PBALLQ;
}else{ q = [PBSQLQualifier andQualifierWithArray:lma];
}
return q;
}
- (void)setEffectiveCombinedQ:(PBSQLQualifier *)q;
{ if(!q)return;
[self setLastCombinedQ:q]; //fuer neuSuchen
[stateArray addObject:[PBWOEditorState stateOf:self]];
while([stateArray count]>10)[stateArray removeObjectAtIndex:0];
}
- (void)suche_zurueck;
{// das Ergebnis der letzten Suche anzeigen
// besser: letzte treffermenge mit seite und selObj wiederherstellen
[stateArray secureRemoveLastObject];
if([stateArray count]){ PBWOEditorState *state = [stateArray lastObject];
[ma removeAllObjects];
[ma addObjectsFromArray:[state ma]];
[self setLastCombinedQ:[state lastCombinedQ]];
maOffset = [state maOffset];
countCombinedQ = [state countCombinedQ];
[self gatherSelectedObjects];
}
}
- (BOOL)hasStatisticFields;
{ return hasStatisticFields;
}
- (void)determineRegisterActions;
{// haben nichts mit normalen Actions zu tun
// sind positions-Register Actions
int i,j;
[registerActions removeAllObjects];
for(i=0,j=[positionsTabellen count];i<j;i++){ NSString *dbName = [positionsTabellen oai:i];
NSString *actionName = [NSSWF @"gotoPositionen_%@",dbName];
NSString *actionGuiName = [NSSWF @">%@",[[MYDD tableNamedCheap:dbName]guiName]];
PBActionO *_action = [PBActionO actionWithName:actionName gui:TRANSLATION(actionGuiName)];
if(_action){ [registerActions addObject:_action];
}
}
}
- (void)setAktiv;
{ LOG_ACTION;
[self setAktivTo:SC_BOOL_TRUE];
}
- (void)setInaktiv;
{ LOG_ACTION;
[self setAktivTo:SC_BOOL_FALSE];
}
- (void)setAktivTo:(NSString *)s;
{ NSArray *a;
int i,j;
PBEO *eo=nil;
if(![self hasEditierBerecht])return;
if(![self paNon])return;
a = [self selectedObjects];
for(i=0,j=[a count];i<j;i++){ eo = [a oai:i];
[eo tvfk(s,NAME_OF_AKTIV_FLAG)];
if(![self ceoh_will:@"willUpdate:" eo:eo])continue;
[eo tvfk(s,NAME_OF_AKTIV_FLAG)];
UPDAT(eo);
}
[_APP executeScriptNamed:[NSSWF @"%@/selObjChanged",nameForScript] datasource:self parmDict:parmDict];
}
- (void)refetchEO;
{ if(![self refetchEO_ButtonIsDisabled]){ LOG_ACTION;
[_APP refetchEO:selObj]; //fetched nochmal alle attr., laesst das PBEO aber als solches;
}
[self _selObjChanged];
}
- (void)neuSuchen;
{//aufgerufen von offsetWeiter/zurueck und nach Sortierungsaenderung, wenn treffermenge > fetchlimit
//kein rebuildSoa, damit evt. temporaeres verwendet wird
NSArray *a;
a = [_APP getEOs:[myTable dbName] qualifier:lastCombinedQ offset:maOffset count:fetchLimit soa:soa];
if(![a count]){ LOGI(TRANSLATION(@"nichts gefunden"));
}
isMaximized = YES;
[self takeObjects:a];
countCombinedQ = [self countQ:lastCombinedQ];
// nicht mastereo ruecksetzen, da auch bei umsortierung und weiterblaettern aufgerufen
}
- (int)countQ:(PBSQLQualifier *)q;
{//feststellen, wieviel saetze der Qualifier liefert
NSString *sql;
NSString *wc = [q string];
if([myTable isRealTable]){ if(FILLED(wc)){ sql = [NSSWF @"select count(*) from %@ where %@",[myTable dbName],wc];
}else{ sql = [NSSWF @"select count(*) from %@",[myTable dbName]];
}
return [[_APP getSingleValueAsResultFrom:sql]intValue];
}
return 0;
}
- (BOOL)suchSuccessfulExternalQ:(PBSQLQualifier *)q;
{//von modulen ausserhalb aufzurufen
//liefert YES, wenn etwas gefunden wurde
//typischerweise Ergebnisse von Verarbeitungsvorgaengen uebergeben
//wurde nichts gefunden, vorherigen Stand wieder herstellen
PBSQLQualifier *callingMQBackup,*cqc;
int i;
LMAN(filterBackup);
if(![self paNon]){ LOGI(([NSSWF TRANSLATION(@"%@ hat ungespeicherte Aenderungen."),guiName]));
return NO;
}
callingMQBackup = [[callingMQ copy]autorelease];
[filterBackup addObjectsFromArray:filterQs];
[self setCallingMQ:nil];
[filterQs removeAllObjects];
cqc = [self combinedQWith:q];
i = [self countQ:cqc];
if(!i){//vorherigen zustand wieder herstellen
[self setCallingMQ:callingMQBackup];
[filterQs addObjectsFromArray:filterBackup];
LOGI(TRANSLATION(@"nichts gefunden"));
return NO;
}else{ [self setSuchFelderQ:q];
[self setEffectiveCombinedQ:cqc];
}
maOffset = 0;
currentPage = 0;
[self neuSuchen];
[self setCallingModul:nil]; //cleared auch callingMQ; uebernehmen geht dann nimmer;
[self setMasterEO:nil];
return YES;
}
- (void)evaluateQualifiers;
{ [self setEffectiveCombinedQ:[self combinedQ]];
maOffset = 0;
currentPage = 0;
[self neuSuchen];
[self setMasterEO:nil];
}
- (void)suchInternalQ:(PBSQLQualifier *)q;
{//nur intern aufrufen
//suchfelderq setzen; callingModulq belassen; eos immer nehmen, auch wenn nix gefunden
//bei combi-suche, recentlyChanged
[self setSuchFelderQ:q];
[filterQs removeAllObjects];
[self evaluateQualifiers];
}
- (void)executeCallingMQ:(PBSQLQualifier *)q;
{//bei Preselection verwenden
//callingMQ setzen, suchfelderQ leeren aber nicht auf stack, eos auf jeden fall nehmen, auch wenn keine gefunden
//Modul bleibt im callingMQ gefangen, kommt nicht aus eigener Kraft heraus;
//nur noch bei PBWOLookup
[self setCallingMQ:q];
[self setSuchFelderQ:nil];
[filterQs removeAllObjects];
[self evaluateQualifiers];
}
- (void)create;
{ PBEO *newEO;
// if([self create_ButtonIsDisabled])return; doch zulassen von scripts; nur nicht ueber oberflaeche; z.B. bei LS
LOG_ACTION;
if(!(newEO = [_APP createEOforEN:[myTable dbName]]))return;
wasDuplicate = NO;
[newEO retain];
if(isPosition && masterEO){ // posEO if(![[[_APP configDict]ofk:@"no_duplicate"]iE:@"J"]){ // gleichlautende Values uebernehmen, die duplicate=J haben
// evt. initialwerte werden ueberschrieben!
// hat ein masterEO gleichlautende Summen-Felder, sollten diese auf duplicate=N gesetzt werden;
[newEO takeValuesOfSameNameFromEo:masterEO];
}
//von masterEO den primaryKey als masterKey nehmen
[newEO tvfk([masterEO primaryKey],@"masterkey")];
}
[self _didCreate:newEO];
[self addEo:newEO];
[newEO release];
// auf 1. Register
[self gotoFirstBox];
}
- (void)duplicate; //Ko
{ PBEO *newEO,*oldEO;
if([self duplicate_ButtonIsDisabled])return;
LOG_ACTION;
if(!(newEO = [_APP createEOforEN:[myTable dbName]]))return;
[newEO retain];
oldEO = selObj;
[newEO takeValuesFromDictionaryToDuplicate:[oldEO values]];
if(isPosition && masterEO){ //posEO;nur den masterkey uebernehmen; [newEO tvfk([masterEO primaryKey],@"masterkey")];
}
[self setDuplicatedObj:oldEO];
[self _didCreate:newEO];
[self addEo:newEO];
wasDuplicate = YES;
[newEO release];
[parmDict setSecureObject:newEO forKey:@"p_eo"];
[_APP executeScriptNamed:[NSSWF @"%@/didDuplicate",nameForScript] datasource:self parmDict:parmDict];
// das neue EO ist noch nicht inserted, daher koennen die Positionen noch nicht kopiert werden; das geht erst im didInsert
// auf 1. Register
[self gotoFirstBox];
}
- (void)delete;
{ LOG_ACTION;
//sofort loeschen; aus eos rausnehmen; tv refresh;
if(pendingAction == pa_ins){ [self setPendingAction:pa_non];
[self _delete];
wasDuplicate = NO;
[self setNeedsSave:NO];
return;
}
if([self delete_ButtonIsDisabled])return;
if([_APP verifyDelete]){ NSString *s = [parmDict ofk:@"delete_confirmed"];
if(FILLED(s)){ if([s iE:@"N"]){ LOGI((TRANSLATION(@"Abbruch.")));
[parmDict removeObjectForKey:@"delete_confirmed"];
return;
}
}else{ [_APP executeScriptNamed:@"verifyDelete" datasource:self parmDict:parmDict];
return;
}
}
[parmDict removeObjectForKey:@"delete_confirmed"];
if(pendingAction == pa_upd || [self paNon]){ NSAutoreleasePool *mp = [NSAutoreleasePool new];
int i,j;
int newSelection=[ma indexOfObject:[selectedObjects firstObject]];
//positionen autom. mitloeschen
//Berechtigungsprinzip: wer das mastereo loeschen darf, darf auch die positionen mit loeschen
for(i=0,j=[selectedObjects count];i<j;i++){ PBEO *eo = [selectedObjects oai:i];
[self setSelObj:eo]; //weil mehrere auf einmal geloescht werden koennen u. die will/did u. Scripts immer auf selObj gehen;
// setSelObj ist hier gefahrlos, weil damit kein Seiteneffekt ausgeloest wird und danach in _delete ohnehin neu positioniert wird
// in Zukunft $p_eo nehmen in scripts
if(![self _willDelete:eo])continue;
[_APP deleteEO:eo];
if(positionsTabellen){ int ii,jj;
NSString *pk = [eo primaryKey];
for(ii=0,jj=[positionsTabellen count];ii<jj;ii++){ NSString *sql = [NSSWF @"delete from %@ where masterkey = '%@'",[positionsTabellen oai:ii],pk];
SQL(sql);
}
}
[self _didDelete:eo];
countCombinedQ--;
newSelection = [ma indexOfObject:eo];
[ma removeObject:eo];
if ((i+1)%50 == 0) { [mp release];
mp = [NSAutoreleasePool new];
}
}
[mp release];
[self setPendingAction:pa_non];
// hinter zuletzt geloeschtes EO positionieren; nicht mehr mit _delete, weil einzelne EOs vielleicht nicht geloescht wurden aufgrund srciptRC;
if(newSelection<0)newSelection=0;
if(newSelection>=[ma count])newSelection=[ma count]-1;
[self gotoRow:newSelection];
wasDuplicate = NO;
[self setNeedsSave:NO];
}
}
- (void)save;
{ NSMutableDictionary *returnDict;
//pending Action mit pending EO ausfuehren;
if([self save_ButtonIsDisabled])return;
LOG_ACTION;
if(!needsSave || [self anzeigemodus])return;
if([errorAssos count])return;
[parmDict setSecureObject:selObj forKey:@"p_eo"];
returnDict = [_APP executeScriptNamed:[NSSWF @"%@/willSave",nameForScript] datasource:self parmDict:parmDict];
if([[returnDict ofk:@"scriptRC"] iE:@"N"])return;
[self handlePidimage]; //filneame versorgen
if(pendingAction == pa_upd){ if(![self _willUpdate:selObj])return;
if([_APP updateEO:selObj]){ //manuell immer mit Pruefungen [self noChanges];
[self _selObjChanged];
wasDuplicate = NO;
[self _didUpdate:selObj];
[parmDict setObject:@"update" forKey:@"p_operation"];
[_APP executeScriptNamed:[NSSWF @"%@/didSave",nameForScript] datasource:self parmDict:parmDict];
return;
}
}else{ if(![self _willInsert:selObj])return;
if([_APP insertEO:selObj]){ [self noChanges];
[self _selObjChanged];
countCombinedQ++;
[self _didInsert:selObj];
wasDuplicate = NO; // muss in didInsert noch festgestellt werden koennen, um positionen zu kopieren;
[parmDict setObject:@"insert" forKey:@"p_operation"];
[_APP executeScriptNamed:[NSSWF @"%@/didSave",nameForScript] datasource:self parmDict:parmDict];
return;
}else{ NSString *pk = [selObj primaryKey];
if(!FILLED(pk)){ LOGI(TRANSLATION(@"Insert fehlgeschlagen, Schluessel ist nicht gefuellt."));
}else{ LOGI(([NSSWF TRANSLATION(@"Insert fehlgeschlagen, Satz mit Schluessel %@ schon vorhanden"),pk]));
}
}
}
}
- (NSString *)isInserting;
{ return ((pendingAction == pa_ins)?@"J":@"N");
}
- (BOOL)ceoh_will:(NSString *)s eo:(PBEO *)eo;
{//willInsert, willUpdate, willDelete
NSMutableDictionary *returnDict;
[parmDict setSecureObject:eo forKey:@"p_eo"];
returnDict = [_APP executeScriptNamed:[NSSWF @"%@/%@",nameForScript,[s stringWithoutLastChar]] datasource:self parmDict:parmDict];
if([[returnDict ofk:@"scriptRC"] iE:@"N"])return NO;
return YES;
}
- (BOOL)_willInsert:(PBEO *)eo;
{ if(![self _validate:eo])return NO;
if(![self ceoh_will:@"willInsert:" eo:eo])return NO;
return YES;
}
- (BOOL)_willDelete:(PBEO *)eo;
{ if(![self ceoh_will:@"willDelete:" eo:eo])return NO;
return YES;
}
- (BOOL)_willUpdate:(PBEO *)eo;
{ if(![self _validate:eo])return NO;
if(![self ceoh_will:@"willUpdate:" eo:eo])return NO;
return YES;
}
- (void)_didCreate:(PBEO *)eo;
{ [parmDict setSecureObject:eo forKey:@"p_eo"];
[_APP executeScriptNamed:[NSSWF @"%@/didCreate",nameForScript] datasource:self parmDict:parmDict];
}
- (void)_didInsert:(PBEO *)eo;
{ [parmDict setSecureObject:eo forKey:@"p_eo"];
// moduluebergreifende EO-Events
if(wasDuplicate && [positionsTabellen count]){ int i,j;
for(i=0,j=[positionsTabellen count];i<j;i++){ NSString *posen = [positionsTabellen oai:i];
if(![[MYDD tableNamedCheap:posen] plainAttrNamed:@"__no_duplicate"]){ // damit laesst sich das mitduplizieren einzelner Positionstabellen unterdruecken [_APP copyPosFrom:duplicatedObj to:eo posEn:posen]; // ruft auch Script will/didCopyPos auf
}
}
}
[_APP executeScriptNamed:[NSSWF @"%@/didInsert",nameForScript] datasource:self parmDict:parmDict];
if(masterEO)[_APP refetchEO:masterEO]; //fetched nochmal alle attr., laesst das PBEO aber als solches;
[self setDuplicatedObj:nil];
}
- (void)_didUpdate:(PBEO *)eo;
{ [parmDict setSecureObject:eo forKey:@"p_eo"];
// moduluebergreifende EO-Events
[_APP executeScriptNamed:[NSSWF @"%@/didUpdate",nameForScript] datasource:self parmDict:parmDict];
if(masterEO)[_APP refetchEO:masterEO]; //fetched nochmal alle attr., laesst das PBEO aber als solches;
}
- (void)_didDelete:(PBEO *)eo;
{ [parmDict setSecureObject:eo forKey:@"p_eo"];
// moduluebergreifende EO-Events
[_APP executeScriptNamed:[NSSWF @"%@/didDelete",nameForScript] datasource:self parmDict:parmDict];
if(masterEO)[_APP refetchEO:masterEO]; //fetched nochmal alle attr., laesst das PBEO aber als solches;
}
- (void)undo;
{ if([self undo_ButtonIsDisabled])return;
LOG_ACTION;
switch(pendingAction){ case pa_upd:
[selObj undo]; //aus snapshot wieder in variablen
[self noChanges];
break;
case pa_ins: //einfach loeschen;
[self delete];
break;
}
}
- (void)noChanges;
{ [self setPendingAction:pa_non];
[self setNeedsSave:NO];
}
- (void)empty;
{// ma leer machen; sinnvoll, wenn ein Modul per scripting ferngesteuert wird und man einen definierten Ausgangspunkt herstellen will; z.B. um sicherzugehen, dass das Modul nicht auf einem inaktiven/stornierten selObj steht und daher anzeigemodus aktiv ist;
[self takeObjects:nil];
countCombinedQ = 0;
}
- (void)awake;
{ [self setNextModul:nil];
[_APP setCurrentComponent:self];
[self resetErrorAssos];
}
- (void)prepareBoxesforDisplay;
{ int i,j;
for(i=0,j=[[self selectedBox] count];i<j;i++){ PBWOAsso *pbas = [[self selectedBox] oai:i];
[pbas targetToVal]; //Assos holen Values von ihren targets
}
for(i=0,j=[commonBox count];i<j;i++){ PBWOAsso *pbas = [commonBox oai:i];
[pbas targetToVal]; //Assos holen Values von ihren targets
}
}
- (void)refreshDisplay;
{// f. Scripts, die etwas am selObj veraendert haben; auch TV neu zeichnen
[self _selObjChanged]; // loest Feld/Button-Steuerung aus
}
- (void)markPrepareTVDataForDisplay;
{}
- (void)prepareDataForDisplay;
{ [self prepareBoxesforDisplay]; // um in PBWOPosEditor besser ueberschreiben zu koennen
}
- (NSString *)tvAsString;
{ LMAN(alles);
int i,j,i1,j1,count=0;
// background-color:#C0C255;
// color: white;
NSString *positionFieldf = @"<td bgColor=\"%@\"><a name=\"tvNewPositionField%i\" id=\"%@\" onClick=\"sbm('tvNewRowClicked%i');\" href=\"#\" onBlur=\"style.backgroundColor='%@';\" onFocus=\"style.backgroundColor='#C0C255';\">></a></td>";// eocolor, count, assoID, count, eocolor
// style setzen tut nicht!!!
// NSString *rowf = @"<td style=\"backgroundColor:'%@'; color:'%@';\" onClick=\"sbm('tvNewRowClicked%i');\" onMouseOver=\"style.backgroundColor='#C0C255'; style.color='#FFFFFF';\" onmouseout=\"style.backgroundColor='%@';style.color='%@';\">";// eocolor, fontcolor, count, eocolor, fontcolor
NSString *rowf = @"<td bgColor='%@' onClick=\"sbm('tvNewRowClicked%i');\" onMouseOver=\"style.backgroundColor='#C0C255';\" onmouseout=\"style.backgroundColor='%@';\">";// eocolor, count, eocolor
NSString *cellf = @"<span class=\"TVCell\" style=\"color:%@; width:%i; text-align:%@; %@\">%@ </span>";
// fontcolor,width,left/right,strike,wodVal
NSString *headerf = @"<span class=\"%@\" style=\"width:%i; text-align:%@;\"><a title=\"nach %@ sortieren\" href=\"#\" class=\"PBActionLinkTVHeader\" onClick=\"sbm('actionTableElement_%@');\">%@</a></span>";// style,width, alignment, guiNameSort, dbName, guiName
[alles addObject:@"<tr><td class=\"titleBar\" width=1%></td><td class=\"titleBar\">"];
for(i1=0,j1=[columns count];i1<j1;i1++){ PBWOTVCCol *column = [columns oai:i1];
PBWOAsso *cAsso = [column cAsso];
NSString *style;
if(column == tvcSortCol){ style = @"TVHeaderSorted"; // Highlighten f. Positionierspalte
}else{ style = @"TVHeader";
}
[alles addObject:[NSSWF headerf,style,[column width],[cAsso alignment],[cAsso guiName],[cAsso dbName],[column tvNewGuiNameSort]]];
}
[alles addObject:@"</td></tr>"];
i = currentPage * [self pageLeng];
j = MIN((i+[self pageLeng]),[ma count]);
for(;i<j;i++){ PBEO *eo = [ma oai:i];
NSString *fontColor,*color=@"FFFFFF",*pfcolor=@"FFFFFF",*assoID;
NSString *strike = @"";
NSString *s = [eo eoColor];
if(FILLED(s))pfcolor = s;
if(IS_CHECKED(eo)){ color = @"#C0C255";
fontColor = @"#FFFFFF";
assoID = @"target52";
}else{ if(FILLED(s))color = s;
fontColor = @"#000000";
assoID = @"target53";
}
if(isInActive(eo))strike=@"text-decoration:line-through;";
[alles addObject:@"<tr>"];
[alles addObject:[NSSWF positionFieldf,pfcolor,count,assoID,count,pfcolor]];
// eocolor, count, eocolor
[alles addObject:[NSSWF rowf,color,count,color]];
for(i1=0,j1=[columns count];i1<j1;i1++){ PBWOTVCCol *column = [columns oai:i1];
PBWOAsso *cAsso = [column cAsso];
PBDDAttribute *pba = [cAsso pba];
NSString *s=@"",*s1 = [cAsso dbName],*wodVal=@"";
int tt = [pba targetTyp];
if(tt==ATTVCSELOBJ){ s = [eo vfk:s1];
}else if(tt==ATTVCPD){ s = [[self parmDict] ofk:s1];
}
if([cAsso isNI]){ if(!FILLED(s)){ wodVal=GIF_1A;
}else{ wodVal = [NSSWF @"%@/Images/%@_%@.gif",[_APP resourceURL],s1,s];
}
}else if([cAsso hasVL]){ wodVal = [pba bezeichnungForValue:s];
}else{ wodVal = [cAsso formatOut:s];
}
if(!wodVal)wodVal = @"";
if(![pba html]){ wodVal = [wodVal htmlEscapedString]; // html kann invalid werden, wenn man was abschneidet
}else{ wodVal = [wodVal abbreviated80String]; // wg. memofeldern in tv
}
// fontcolor,width,left/right,strike,wodVal
[alles addObject:[NSSWF cellf,fontColor,[column width],[cAsso alignment],strike,wodVal]];
}
[alles addObject:@"</td>"];
[alles addObject:@"</tr>"];
count++;
}
return [alles componentsJoinedByString:@""];
}
- (BOOL)hasPidImage; /*" f. ViewPage in CMS"*/
{ if(!selObj)return NO;
return ([myFM fileExistsAtPath:[self pidImagePath]]);
}
- (NSString *)namedIconSrc;
{ NSString *s;
if(!selObj)return GIF_1A; //kein eo, kein Bild
s = [selObj vfk:[currentAsso dbName]];
if(!FILLED(s))return GIF_1A;
//muss einfach da sein
return [NSSWF @"%@/Images/%@_%@.gif",[_APP resourceURL],[currentAsso dbName],s];
}
- (NSString *)tnPidImageUrl;
{ return [NSSWF @"%@/documents/%@_tn.jpg",[_APP resourceURL],[[selObj pidimagefnJpg]stringByDeletingPathExtension]];
}
- (NSString *)pidImageUrl;
{ return [NSSWF @"%@/documents/%@",[_APP resourceURL],[selObj pidimagefnJpg]];
}
/////////////////////////////
- (WOElement *)allSelection;
{ int i,j;
LMAN(oso);
[self setSelObj:nil];
[oso addObjectsFromArray:selectedObjects];
for(i=0,j=[ma count];i<j;i++){ SET_CHECKED([ma oai:i]);
}
[selectedObjects removeAllObjects];
[selectedObjects addObjectsFromArray:ma];
if(([selectedObjects count]==1)){ [self setSelObj:[selectedObjects firstObject]];
}
if(![oso iE:selectedObjects]){ //selektion hat sich geaendert [self _selObjChanged];
}
return self;
}
- (WOElement *)multiSelOn; // in Multiselection Modus wechseln
{ multiSelect = YES;
return self;
}
- (WOElement *)multiSelOff; // Multiselection Modus beenden
{ multiSelect = NO;
return self;
}
- (WOElement *)multiSelToggle; // Multiselection Modus umschalten
{ multiSelect = !multiSelect;
return self;
}
- (NSString *)multiSelString;
{ if(multiSelect)return @"M";
return @"1";
}
- (WOElement *)editLine:(int)line columnName:(NSString *)columnName;
{ int absRowIndex = currentPage * [self pageLeng] + line;
if(absRowIndex >= [ma count])absRowIndex = [ma count]-1;
if(absRowIndex < 0)return self;
if(multiSelect){ // Satz den selectedObjects zufuegen oder rausnehmen
PBEO *eo = [ma oai:absRowIndex];
if(IS_CHECKED(eo)){ [selectedObjects removeObject:eo];
SET_UNCHECKED(eo);
}else{ [selectedObjects addObject:eo];
SET_CHECKED(eo);
}
[self gatherSelectedObjects];
}else{ isMaximizedDetail = YES;
[self gotoRow:absRowIndex];
}
return self;
}
- (WOElement *)pageBack;
{ if(currentPage > 0){ currentPage--;
}else{ if(maOffset){ [self offsetZurueck];
currentPage = [self numOfPages]-1;
}
}
isMaximized=YES;
return self;
}
- (WOElement *)pageForward;
{ if(currentPage < [self numOfPages]-1){ currentPage++;
}else{ if([ma count] == fetchLimit){ [self offsetWeiter];
if([ma count]){ currentPage = 0;
}else{ [self offsetZurueck];
}
}
}
isMaximized=YES;
return self;
}
/////////////////////////////
//parameter, die von wod geschrieben werden
/////////////////////////////
- (NSArray *)currentBox;
{ return [boxDict ofk:currentBoxName];
}
- (BOOL)mayGotoBoxTitle;
{ return ![currentBoxName iE:selectedBoxName];
}
- (void)df;
{//datenfreigabe und default-action der form, wenn mit javascript form.submit() aufgerufen wird
//bei klick auf einen boxname wird ein js ausgefuehrt, das den boxname setzt in der der form in submitter und die form submitted;
//damit werden die eingegebenen werte uebernommen, wenn die box verlassen wird
NSString *submitter = [[[self context] request] formValueForKey:@"submitter"];
NSString *clickedColumnName = [[[self context] request] formValueForKey:@"clickedColumnName"];
if([_APP log_changes])LOGS(([NSSWF @"submitter=%@",submitter]));
if([submitter hasSecurePrefix:@"action_gotoCurrentLaunchedModule"]){ // Klick auf ein Register in den geoeffneten Modulen
[self gotoCurrentLaunchedModuleNr:[[submitter substringFromIndex:[@"action_gotoCurrentLaunchedModule" length]]intValue]];
return;
}
if([submitter hasSecurePrefix:@"action_gotoPositionen_"]){ // Positionseditor aufrufen
if(![self selObj]){ LOGI(TRANSLATION(@"bitte genau einen Satz auswaehlen"));
return;
}else{ PBWOPosEditor *e;
if([[callingModul name]iE:@"PBWOPosEditor"]){ // kleiner Hack, um mehrfache PosEditoren haben zu koennen e = MODUL(@"PBWOPosEditor1"); // muss als Modul angelegt werden, identisch wie PBWOPosEditor
}else{ e = MODUL(@"PBWOPosEditor");
}
if(!e){ LOGI(TRANSLATION(@"PBWOPosEditor nicht bekommen"));
return;
}
if(![self paNon]){ [self save];
}
if(![self paNon]){ LOGI(TRANSLATION(@"bitte zuerst vervollstaendigen und sichern"));
return;
}
[e setCallingModul:self];
[e setMyTable:[MYDD tableNamedCheap:[submitter substringFromIndex:[@"action_gotoPositionen_" length]]] andMasterEO:[self selObj]];
[self bringToFront:e];
// noch anzeige modus setzen...
return;
}
}
// Portlet-Actions durchrouten; Name des Portlets ist hinten angehaengt
if([submitter hasSecurePrefix:@"action_portletRefresh_"]){ [[portletDict ofk:[submitter substringFromIndex:[@"action_portletRefresh_" length]]] refresh];
return;
}
if([submitter hasSecurePrefix:@"action_portlet_currentLine"]){ PBWOPortlet *po = [portletDict ofk:[submitter substringFromIndex:[@"action_portlet_currentLineXActed_" length]]];
SEL sel = SECURE_SELECTOR_FROM_STRING([[submitter substringFromIndex:[@"action_portlet_" length]]substringToIndex:[@"currentLineXActed" length]]);
if(sel)[po performSelector:sel];
return;
}
if([submitter hasSecurePrefix:@"action_script_"]){ // direkt das Script aufrufen; muss im Modul-Verzeichnis liegen; geht ohne Berechtigung, ohne Attribut-Button;
[_APP executeScriptNamed:[NSSWF @"%@/%@",nameForScript,[submitter substringFromIndex:[@"action_script_" length]]] datasource:self parmDict:parmDict];
return;
}
if([submitter hasSecurePrefix:@"action_"]){ // PBActionLinks verwenden dies
SEL sel = SECURE_SELECTOR_FROM_STRING([submitter substringFromIndex:7]);
if(sel)[self performSelector:sel];
return;
}
if([submitter hasSecurePrefix:@"attributeButton_"]){ // emuliert den Klick auf den Button;
[self attributeButtonActed:[submitter substringFromIndex:[@"attributeButton_" length]]];
return;
}
if([submitter hasSecurePrefix:@"confirm_"]){ // Actions in Confirm-Mode; nicht die Ja/Nein Buttons [_APP continueScript];
}
if([submitter hasSecurePrefix:@"gotoBox_"]){ NSString *s = [submitter substringFromIndex:8];
[self setSelectedBoxName:s];
return;
}
if([submitter hasSecurePrefix:@"tvNewRowClicked"] && [self paNon]){ int index = [[submitter substringFromIndex:[@"tvNewRowClicked" length]]intValue];
if([self paNon])[self editLine:index columnName:clickedColumnName];
return;
}
if([submitter hasSecurePrefix:@"actionTableElement_"]){ // sortierung umstellen;
// column fuer den dbName ermitteln
NSString *dbName = [submitter substringFromIndex:[@"actionTableElement_" length]];
int i,j;
for(i=0,j=[columns count];i<j;i++){ PBWOTVCCol *column = [columns oai:i];
if([[column dbName]iE:dbName]){ if([[[column cAsso]pba]isDB]){ if([column tvNewSortMode]==SORTMODE_A){ // -> D [self setSoseq:[NSSWF @"%@:d",dbName]]; // konfiguriert die Spalten neu, macht soa
}else{ [self setSoseq:dbName];
}
[self saveSoseq];
tvNewRowOffset = 0;
currentPage = 0;
maOffset = 0;
[self neuSuchen]; // immer serverside sort
}
}
}
}
}
- (void)takeString:(NSString *)s;
{// bei Uebernahme aus Kalender oder der primary Key eines EO aus einem Lookup
PBDDAttribute *pba = [waitingForName pba];
PBEO *targetObject;
if(!pba)return; // wir wollen nix haben
if(!s || ![waitingForName inputAllowed]){ [self setWaitingForName:nil];
return;
}
if([pba targetTyp]==ATTVCPD){ targetObject = (PBEO *)parmDict;
}else{ targetObject = selObj;
}
if(targetObject){ [targetObject tvfk(s,[pba dbName])];
[self didValToTargetPba:pba];
[self setExternalFieldToFocusOn:waitingForName];
// [self bringToFront:self]; //falls das callingmodul das vergessen hat zu tun
}
[self setWaitingForName:nil];
}
- (NSString *)namedIconAlt;
{ NSString *s = [currentAsso wodVal];
if(!s)s = EON;
return [NSSWF @"%@ = %@",[currentAsso guiName],s];
}
- (NSArray *)selectedBox;
{ //Assos der selectedBox
return [boxDict ofk:selectedBoxName];
}
/////////////////////////////
//parameter, die von wod gelesen werden
/////////////////////////////
- (int)pageLeng;
{ int pl;
pl=[[parmDict ofk:@"pageLeng"]intValue]; // in didBuildUp Script zu konfigurieren
if(pl)return pl;
if(isMaximizedDetail){ pl = [[[_APP configDict]ofk:@"rowsonpage"]intValue];
if(!pl)pl=10;
}else{ pl = [[[_APP configDict]ofk:@"rowsonpagel"]intValue];
if(!pl)pl=20;
}
return pl;
}
- (int)numOfPages;
{ return ([ma count]+[self pageLeng]-1)/[self pageLeng];
}
- (int)colCount;
{ return [columns count];
}
- (BOOL)hasTV;
{ return ( [self colCount]>0);
}
- (BOOL)hasPages;
{ return [self numOfPages]>1;
}
- (BOOL)mayPageBack;
{ return currentPage > 0 || maOffset > 0;
}
- (BOOL)mayNotPageBack;
{ return ![self mayPageBack];
}
- (BOOL)mayPageForward;
{ return currentPage < [self numOfPages]-1 || [ma count]==fetchLimit;
}
- (BOOL)mayNotPageForward;
{ return ![self mayPageForward];
}
- (void)gatherSelectedObjects;
{ [self gatherSelectedObjectsAndGoto:YES];
}
- (void)gatherSelectedObjectsAndGoto:(BOOL)gotoSelObj;
{//aufgrund von isCheckedPBEO das selObj und die selectedObjects in richtiger Reihenfolge bestimmen;
//dabei feststellen, ob sich selektion geaendert hat
//gotoSelObj steuert, ob auf Seite des selObj positioniert wird
int i,j;
LMAN(oso);
[self setSelObj:nil];
[oso addObjectsFromArray:selectedObjects];
[selectedObjects removeAllObjects];
for(i=0,j=[ma count];i<j;i++){ PBEO *eo = [ma oai:i];
if(IS_CHECKED(eo)){ [selectedObjects addObject:eo];
selRow = i;
}
}
if(([selectedObjects count]==1)){ [self setSelObj:[selectedObjects firstObject]];
if(gotoSelObj)currentPage = selRow / [self pageLeng];
}
if((pendingAction == pa_ins) || ![oso iE:selectedObjects]){ //selektion hat sich geaendert [self _selObjChanged];
}
}
- (void)appendToResponse:(WOResponse *)aResponse inContext:(WOContext*)aContext
{ [self prepareDataForDisplay];
// LOGS(([NSSWF @"tvNewRowOffset=%i currentPage=%i numOfPages=%i",tvNewRowOffset,currentPage,[self numOfPages]]));
fieldsInSelectedRegisterIndex=0;
if(isConfigMode)[lifFieldDict removeAllObjects];
[super appendToResponse:aResponse inContext:aContext];
if([_APP log_changes])LOG(@"------- [changedInRequest removeAllObjects] -----");
[changedInRequest removeAllObjects];
}
- (void)takeObjects:(NSArray *)someObjects;
{//fuellt das ma neu, mit EOs, die z.B. gefetched wurden
if(![self paNon]){ LOGI(([NSSWF TRANSLATION(@"%@ hat ungespeicherte Aenderungen und konnte daher die Objekte nicht annehmen."),guiName]));
return;
}
[ma removeAllObjects];
[ma addObjectsFromArray:someObjects];
// vor dem sortieren aufrufen, damit script die Sortierung noch beeinflussen kann
[_APP executeScriptNamed:[NSSWF @"%@/didTakeObjects",nameForScript] datasource:self parmDict:parmDict];
[self positionTo:TOP];
[[stateArray lastObject]updateStateFrom:self];
}
- (void)positionTo:(int)posMode;
{ int i = selRow;
switch(posMode){ case TOP:
[self gotoRow:0];
break;
case KEEP:
[self gotoRow:i];
break;
case BOT:
[self gotoRow:[ma count]-1];
break;
}
}
- (void)gotoObject:o;
{//auf ein best. Objekt positionieren, von dem man meint, es sei im ma
int i;
if(!o)return;
i = [ma indexOfObject:o];
if(i != NSNotFound)[self gotoRow:i];
}
- (void)_delete;
{// alle selectedObjects aus ma und aus selectedObjects raus
// auf erstes eo nach dem letzten geloeschten positionieren
if([selectedObjects count]){ int newSelection = [ma indexOfObject:[selectedObjects lastObject]];
PBEO *newEO=nil;
if(newSelection != NSNotFound){ newSelection++;
if(newSelection < [ma count])newEO = [[ma oai:newSelection]retain];
}
[ma removeObjectsInArray:selectedObjects];
if(newEO){ newSelection = [ma indexOfObject:newEO];
[newEO release];
}else{ newSelection=[ma count]-1;
}
if(newSelection<0)newSelection=0;
if(newSelection>=[ma count])newSelection=[ma count]-1;
[self gotoRow:newSelection];
}
}
- (NSMutableArray *)errorAssos;
{ return errorAssos;
}
- (int)selRow;
{ return selRow;
}
- (void)executeDidTakeValuesFromRequest;
{// in diesem Event koennen alle Editierungen abschliessend begutachtet werden
// oldValues des selObj
[parmDict setSecureObject:selObj forKey:@"p_eo"];
[_APP executeScriptNamed:[NSSWF @"%@/didTakeValuesFromRequest",nameForScript] datasource:self parmDict:parmDict];
[parmDict removeObjectForKey:@"p_eo"];
}
- (void)takeValuesFromRequest:(WORequest *)aRequest inContext:(WOContext *)aContext;
{ [super takeValuesFromRequest:aRequest inContext:aContext];
[self executeDidTakeValuesFromRequest];
}
- (void)didValToTargetPba:(PBDDAttribute *)pba;
{ NSString *value=nil,*dbName;
if(!pba)return;
dbName = [pba dbName];
if([pba targetTyp]==ATTVCSELOBJ){ if(selObj){ value = [selObj vfk:dbName];
[self aValueChanged];
}
}else{ value = [parmDict ofk:dbName];
}
if(!value)value = EON;
[parmDict setSecureObject:selObj forKey:@"p_eo"];
[changedInRequest setObject:value forKey:dbName]; // sammeln f. didTakeValuesFromRequest
[parmDict setObject:dbName forKey:@"p_didValToTargetName"];
[parmDict setObject:value forKey:@"p_didValToTargetValue"];
[_APP executeScriptNamed:[NSSWF @"%@/didValToTarget",nameForScript] datasource:self parmDict:parmDict];
[parmDict removeObjectForKey:@"p_didValToTargetName"];
[parmDict removeObjectForKey:@"p_didValToTargetValue"];
[parmDict removeObjectForKey:@"p_eo"];
// f. Debugging, wenn ein EO ploetzlich meint, es sei geaendert worden
if([_APP log_changes] && ([pba targetTyp]==ATTVCSELOBJ) && selObj && [selObj isKindOfClass:[PBEO class]])LOGS(([NSSWF @"Feld:%@ (%@)\nneu:>%@<\nalt:>%@<\nneuHex:>%@<\naltHex:>%@<",[pba guiName],dbName,value,[[selObj oldValues]ofk:dbName],[value hexFormat],[[[selObj oldValues]ofk:dbName]hexFormat]]));
}
- (void)didSetValueForKey:(NSString *)dbName;
{// aufzurufen, wenn man an der Asso vorbei von aussen einen Wert gesetzt hat; z.B. in scripts;
// geht auch, wenn es gar keine Asso gibt
// ein PBDDAttribute muss es allerdings geben
if(!dbName)return;
[self didValToTargetPba:[myTable plainAttrNamed:dbName]];
}
- (void)handlePidimage;
{// Filename eines evt. gestzten Pid-Image Dokuments beschaffen beim Speichern
if([myTable hasPidimage]){ NSString *s = [selObj vfk:@"pidimage"];
if(FILLED(s)){ PBEO *doc = getEOPkValue(@"document",s);
if(doc){ [selObj tvfk([doc vfk:@"filename"],@"pidimagefn")];
[selObj setPidimagefnJpg:[doc vfk:@"filename"]];
}else{ [selObj tvfk(EON,@"pidimagefn")];
[selObj setPidimagefnJpg:@"1a.jpg"];
}
}else{ [selObj tvfk(EON,@"pidimagefn")];
[selObj setPidimagefnJpg:@"1a.jpg"];
}
}
}
- (NSMutableArray *)selectedObjects;
{ return selectedObjects;
}
- (NSString *)objCountS;
{ int i;
if(![self paNon])return EON;
if(selObj)return [NSSWF TRANSLATION(@"%i. von %i / %i"),(maOffset + selRow)+1,countCombinedQ,[stateArray count]];
if((i=[selectedObjects count]))return [NSSWF @"%i markiert von %i / %i",i,countCombinedQ,[stateArray count]];
return NSS(countCombinedQ);
}
- (NSString *)fieldIDToFocusOn;
{ PBWOAsso *pbas;
int i,j;
NSArray *a = [self selectedBox];
if([_SESSION dialogMode]){ return @"confirm_ja";
}
if(![self isMaximizedDetail])return @"target49";
if([self isConfigMode]){ if([self isConfigModeDetail]){ if([[parmDict ofk:@"p_lastAction"]iE:@"removeField"])return @"fieldsInSelectedRegister";
if([[parmDict ofk:@"p_lastAction"]iE:@"addField"])return @"fieldsOrControls";
if([[parmDict ofk:@"p_lastAction"]iE:@"selectFieldForEdit"])return @"selectedFieldTextField";
}
return nil;
}
if([errorAssos count])return [[errorAssos firstObject]assoID];
if([externalFieldToFocusOn isKindOfClass:[PBWOAsso class]]){ return [externalFieldToFocusOn assoID];
}
if(waitingForName)return [waitingForName assoID];
for(i=0,j=[a count];i<j;i++){ pbas = [a oai:i];
if([pbas inputAllowed]){ return [pbas assoID];
}
}
return @"target49";
}
- (BOOL)isMaximized;
{// TV
return isMaximized;
}
- (WOElement *)maximize;
{// TV
isMaximized = YES;
return self;
}
- (WOElement *)minimize;
{// TV
isMaximized = NO;
return self;
}
- (BOOL)isMaximizedDetail;
{ if([self needsSave])return YES;
return isMaximizedDetail;
}
- (WOElement *)maximizeDetail;
{ isMaximizedDetail = YES;
currentPage *= 2;
return self;
}
- (WOElement *)minimizeDetail;
{ if([self needsSave])return nil;
isMaximizedDetail = NO;
currentPage /= 2;
return self;
}
- (BOOL)mayNextBox;
{ if([boxNameArray count]<=1)return NO;
return ![selectedBoxName iE:[boxNameArray lastObject]];
}
- (BOOL)mayPrevBox;
{ if([boxNameArray count]<=1)return NO;
return ![selectedBoxName iE:[boxNameArray firstObject]];
}
- (BOOL)mayNotPrevBox;
{ return ![self mayPrevBox];
}
- (BOOL)mayNotNextBox;
{ return ![self mayNextBox];
}
- (WOElement *)nextBox;
{ int i;
if(![self mayNextBox])return self;
i = [boxNameArray indexOfObject:selectedBoxName];
if(NSNotFound == i)return self;
i++;
if(i>=[boxNameArray count])return self;
[self setSelectedBoxName:[boxNameArray oai:i]];
return self;
}
- (void)gotoFirstBox;
{ [self setSelectedBoxName:[boxNameArray firstObject]];
}
- (WOElement *)prevBox;
{ int i;
if(![self mayPrevBox])return self;
i = [boxNameArray indexOfObject:selectedBoxName];
if(NSNotFound == i)return self;
i--;
if(i<0)return self;
[self setSelectedBoxName:[boxNameArray oai:i]];
return self;
}
- (BOOL)hasSelObj;
{ return selObj != nil;
}
//-------------------------------------------------------------------
- (NSString *)pidImagePath;
{ return [NSSWF @"%@/tables/%@/%@.jpg",RESOURCEPATH,[selObj entityName],[selObj primaryKey]];
}
- (NSString *)pidImageTNPath;
{ return [NSSWF @"%@/tables/%@/%@_tn.jpg",RESOURCEPATH,[selObj entityName],[selObj primaryKey]];
}
- (BOOL)_validate:(PBEO *)eo;
{ int i,j;
BOOL rc = YES;
NSArray *assos = fassos;
if([self paNon])return YES;
for(i=0,j=[assos count];i<j;i++){ PBWOAsso *pbas = [assos oai:i];
NSString *dbName = [pbas dbName];
PBDDAttribute *pba = [pbas pba];
int dt;
NSString *s;
if(![pbas inputAllowed])continue; //user kann sowieso nichts aendern
if(!(pendingAction == pa_ins) && ![[eo oldValues] ofk:dbName])continue; // update u. Feld nicht geaendert
if([[pbas pba]targetTyp]==ATTVCSELOBJ){ s = [eo vfk:dbName];
}else if([pba targetTyp]==ATTVCPD){ s = [parmDict ofk:dbName];
}else{ continue;
}
if([pbas isMandatory]){ dt = [pbas dataTyp];
if(((dt == DT_FLOAT || dt == DT_MONEY || dt == DT_INT) && [s doubleValue]==0.0) || !FILLED(s)){ LOGI(([NSSWF TRANSLATION(@"%@ ist ein Pflichtfeld."),[pbas guiName]]));
[pbas markError];
rc = NO;
continue;
}
}
if(pba && [pba isFK]){ PBDDTable *t;
PBEO *feo;
NSString *fpk;
if(!(t = [pba relationTable]))continue;
fpk = [t primaryKeyName];
if(!FILLED(s))continue; //gar nicht gefuellt
if([[t primaryKeyAttr]dataTyp]==DT_INT && ![s intValue])continue; //Relation auf integer-Key und es steht 0 drin
if(!(feo = getEOPkValue([t dbName],s))){ LOGI(([NSSWF TRANSLATION(@"%@ %@ ist nicht vorhanden."),[t guiName],s]));
[pbas markError];
rc = NO;
continue;
}
if(isInActive(feo)){// LOGS([[feo values]description]);
LOGI(([NSSWF TRANSLATION(@"%@ %@ nicht aktiv"),[t guiName],s]));
[pbas markError];
rc = NO;
continue;
}
}
}
return rc;
}
- (WOElement *)gotoConfigModeListe;
{ configMode = CONFIGMODE_Liste;
return self;
}
//-------------------------------------------------------------------
// LIF
ACCESSm(lifEditArea,setLifEditArea);
ACCESSm(lastLifPath,setLastLifPath);
//-------------------------------------------------------------------
// TV
ACCESSm(tvNewSearchInSortCol,setTvNewSearchInSortCol);
- (void)setTvNewRowOffsetUI:(NSString *)s;
{// UI ist immer 1 groesser, damit es bei 1 anfaengt
[self setTvNewRowOffset:s];
tvNewRowOffset--;
if(tvNewRowOffset<0)tvNewRowOffset=0;
}
- (int)tvNewRowOffsetUI;
{ return [self tvNewRowOffset] +1;
}
- (void)setTvNewRowOffset:(NSString *)s;
{ if(!s){ tvNewRowOffset = 0;
}else{ if([s hasSecurePrefix:@"+"]){ tvNewRowOffset += [[s substringFromIndex:1]intValue];
return;
}
if([s hasSecurePrefix:@"-"]){ tvNewRowOffset -= [[s substringFromIndex:1]intValue];
if(tvNewRowOffset<0)tvNewRowOffset=0;
return;
}
tvNewRowOffset = [s intValue];
}
}
- (int)tvNewRowOffset;
{ return maOffset + (currentPage * [self pageLeng]);
}
- (void)tvNewRowOffsetActed;
{//zu dem satz springen; dort seite beginnen
BOOL maOffsetChanged = NO;
if(needsSave || ![self paNon]){ tvNewRowOffset = maOffset + (currentPage * [self pageLeng]);
return;
}
if(tvNewRowOffset>countCombinedQ)tvNewRowOffset=countCombinedQ - [self pageLeng]; //obere grenze
if(tvNewRowOffset<0)tvNewRowOffset=0;
// offset innerhalb countCombinedQ; muss noch richtig gemacht werden
// feststellen, ob innerhalb der gefetchten saetze
if(!((tvNewRowOffset >= maOffset) && (tvNewRowOffset < (maOffset + fetchLimit)))){// neues maOffset bestimmen und fetchen
maOffset = (int)(tvNewRowOffset / fetchLimit) * fetchLimit;
[self neuSuchen]; //mit lastCombinedQ
maOffsetChanged = YES;
}
currentPage = (tvNewRowOffset - maOffset) / [self pageLeng];
tvNewRowOffset = maOffset + (currentPage * [self pageLeng]);
if(![selectedObjects count] || maOffsetChanged)[self editLine:0 columnName:nil]; //immer auf erste zeile der seite, wenn nix markiert
}
- (void)tvNewSearchInSortColActed;
{// erstmal versuchen innerhalb ma zu positionieren
// schlaegt das fehl, neu fetchen
// wenn Spalte aufsteigend: den Satz, dessen Wert in der Sortierspalte >= dem Suchwert ist
// wenn Spalte absteigend: den Satz, dessen Wert in der Sortierspalte <= dem Suchwert ist
// numerisch, Datum, string
// eigentlich sollte man hier binary-search machen
int i,j,sm=0,dt;
NSString *dbName;
double compValNum=0.0;
long compValDate=0;
NSString *compValChar=nil,*compValSQL,*sql;
double eoValNum=0.0;
long eoValDate=0;
NSString *eoValChar;
BOOL hasVL;
BOOL found;
PBDate *pbd;
if(![self paNon])return;
if(!tvcSortCol)return; // irgendwie keine sortierspalte
dbName = [[tvcSortCol cAsso]dbName];
dt = [[tvcSortCol cAsso]dataTyp];
hasVL = [[tvcSortCol cAsso]hasVL];
sm = [tvcSortCol tvNewSortMode];
if(!tvNewSearchInSortCol)[self setTvNewSearchInSortCol:@""];
if(hasVL){ compValChar = [tvNewSearchInSortCol lowercaseString];
}else{ if(dt == DT_MONEY || dt == DT_INT || dt == DT_FLOAT){ compValNum = [tvNewSearchInSortCol doubleValue];
}else if(dt == DT_DATE || dt == DT_DATETIME){ pbd = [PBDate dateWithFreeString:tvNewSearchInSortCol];
if(!pbd){ LOGI(TRANSLATION(@"kein gueltiges Datum"));
return;
}
[self setTvNewSearchInSortCol:[pbd dateAsUIString]];
compValDate = [pbd dateAsLong];
}else{ compValChar = [tvNewSearchInSortCol lowercaseString];
}
}
found = NO;
for(i=0,j=[ma count];i<j;i++){ PBEO *eo = [ma oai:i];
NSString *eoVal = [eo vfk:dbName];
if(dt == DT_MONEY || dt == DT_INT || dt == DT_FLOAT){ eoValNum = [eoVal doubleValue];
if((sm == SORTMODE_A && (eoValNum >= compValNum)) || (sm == SORTMODE_D && (eoValNum <= compValNum)))found=YES;
}else if(dt == DT_DATE || dt == DT_DATETIME){ eoValDate = [[PBDate dateWithDBString:eoVal] dateAsLong];
if((sm == SORTMODE_A && (eoValDate >= compValDate)) || (sm == SORTMODE_D && (eoValDate <= compValDate)))found=YES;
}else{ NSComparisonResult cr;
eoValChar = [eoVal lowercaseString];
cr = [eoValChar compare:compValChar];
if((sm == SORTMODE_A && (cr != NSOrderedAscending)) || (sm == SORTMODE_D && (cr != NSOrderedDescending)))found=YES;
}
if(found)break;
}
if(!found || (maOffset > 0 && i<=1)){// nicht gefunden bzw. aufsatzpunkt liegt vor maOffset: fetchen;
NSString *wc;
if(hasVL){// den key zur Bez finden
compValSQL = [[[tvcSortCol cAsso]pba] valueForBezeichnung:tvNewSearchInSortCol];
}else{ if(dt == DT_MONEY || dt == DT_INT || dt == DT_FLOAT){ compValSQL = tvNewSearchInSortCol;
}else if(dt == DT_DATE || dt == DT_DATETIME){ compValSQL = NSS(compValDate);
}else{ compValSQL = compValChar;
}
}
wc = [lastCombinedQ string]; //bei letzter Suche mit test=NO gesetzt
if(!wc)wc=@"";
if(FILLED(wc))wc=[wc stringByAppendingString:@" and "];
sql = [NSSWF @"select count(*) from %@ where %@ %@ %@ '%@'",[myTable dbName],wc,dbName,((sm == SORTMODE_A)?@"<":@">"),compValSQL];
tvNewRowOffset = [[_APP getSingleValueAsResultFrom:sql]intValue];
}else{ tvNewRowOffset = maOffset + i;
}
[self tvNewRowOffsetActed];
}
- (BOOL)showTV;
{ return [self paNon];
}
- (void)gotoRow:(int)r;
{// absolut in ma
int i,j;
// LOGS(([NSSWF @"r=%i ma.count=%i",r,[ma count]]));
for(i=0,j=[ma count];i<j;i++){ SET_UNCHECKED([ma oai:i]);
}
if([ma count]){ if(r>=[ma count])r=[ma count]-1;
if(r<0)r=0;
SET_CHECKED([ma oai:r]);
}
[self gatherSelectedObjects];
}
- (BOOL)mayPrevRow;
{ return ([self paNon]) && [ma count] && (selRow > 0 || maOffset);
}
- (BOOL)mayNextRow;
{ return ([self paNon]) && [ma count] && (selRow < [ma count]-1 || [ma count]==fetchLimit);
}
- (BOOL)mayNotNextRow;
{ return ![self mayNextRow];
}
- (WOElement *)nextRow;
{ if(![self mayNextRow])return self;
if(selRow == [ma count]-1 && [ma count]==fetchLimit){ [self offsetWeiter];
if([ma count]){ [self gotoRow:0];
}else{ [self offsetZurueck];
[self gotoRow:selRow];
}
}else{ [self gotoRow:selRow+1];
}
return self;
}
- (WOElement *)prevRow;
{ if(![self mayPrevRow])return self;
if(!selRow && maOffset){ [self offsetZurueck];
[self gotoRow:[ma count]-1];
}else{ [self gotoRow:selRow-1];
}
return self;
}
- (BOOL)mayNotPrevRow;
{ return ![self mayPrevRow];
}
- (int)pageLengOrLess;
{ int i = [ma count];
int j = [self pageLeng];
int k = (currentPage+1) * j;
if(i < k)i = i%j;
if(j < i)i= j;
return i; //nur notwendige Zeilen zeichnen
}
- (void)copyLif;
{ [self saveLif:lifDict path:@"/tmp/lif_pasteboard.txt"];
}
- (void)pasteLif;
{ [self loadLif:@"/tmp/lif_pasteboard.txt"];
[self redrawAfterLeaveConfig];
[self saveLif];
}
@end
//-------------------------------------------------------------------
@implementation PBWOViewer
- (BOOL)anzeigemodus;
{ return YES;
}
@end