1 /******************************************************************************
2 *
3 * Copyright (C) 2004-2007, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: visedit.manrpops 09.08.07 0.0.A.
11 *
12 * Author: Alexander Krivonogov ( gentee )
13 *
14 ******************************************************************************/
15 define {
16 PROP_LOADAFTERCHILD = 0x1 //PropFlags - загрузить данной свойство после создания дочерних элементов
17 PROP_LOADAFTERCREATE = 0x2 //PropFlags - загрузить данное свойство после создания всего дерева объектов
18
19 PI_SIMPLE = 0x000
20 PI_UPDOWN = 0x001
21 PI_DLG = 0x002
22 PI_SEL = 0x100
23
24 PI_DEFVAL = 0x1000000
25 PI_LIST = 0x1000
26 }
27 //Описание возможного числового значения
28 type CompEnumVal {
29 str Name //Имя значения
30 uint Val //Непосредственное значение
31 }
32
33 //Описание свойства
34 type CompProp {
35 str PropName //Имя свойства
36 uint PropType //Тип свойства
37 uint PropFlags //Флаги свойства
38 uint AddrGet //Адрес get метода
39 uint AddrSet //Адрес set метода
40 uint Vals //Список возможных значений если нужен - arr of CompEnumVal
41 ustr DefVal //Значение по умолчанию
42 }
43
44 //Описание события
45 type CompEvent {
46 str EventName //Имя события
47 str EventType //Тип события
48 uint EventId
49 }
50
51 //Описание компонента
52 type CompDescr{
53 uint TypeId //Тип компонента
54 str TypeName //Имя типа
55 str File //Имя модуля содержащее данный компонент
56 uint VisComp //Данный компонент будет отображаться в списке добавляемых компонентов
57 arr Props of CompProp //Список свойств
58 arr Events of CompEvent //Список событий
59 }
60
61 //Менеджер свойств
62 type VEManProps{
63 arr Descrs of CompDescr //Список компонентов
64 }
65
66 type EventDescr{
67 //uint idmethod //Идентификатор метода
68 str MethodName //Имя метода
69 str EventType //Тип параметра сообщения
70 uint CompCount //Количество подключенных компонентов
71 }
72 //Менеджер событий
73 type VEManEvents{
74 arr Descrs of EventDescr
75 }
76
77 //Элемент списка свойств/событий
78 type PropItem
79 {
80 ustr Name //Имя свойства/события
81 ustr Value //Значение свойства/события
82 uint Flags //Флаги PI_*
83 }
84
85
86 global {
87 VEManProps cm
88 VEManEvents ManEvents
89 }
90
91
92 extern {
93 method str CompProp.GetVal <result> ( vComp comp )
94 }
95
96 //Найти описание компонента по идентификатору типу
97 method CompDescr VEManProps.GetCompDescr( uint typeid )
98 {
99 uint descr
100 uint i
101
102 fornum i = 0, *this.Descrs
103 {
104 descr as this.Descrs[i]
105 if descr.TypeId == typeid
106 {
107 return descr
108 }
109 }
110 return 0->CompDescr
111 }
112
113 func int sortstr( CompProp left right )
114 {
115
116 //return scmpignore( left.Name.ptr(), right.Name.ptr())
117 return strcmpign( left.PropName.ptr(), right.PropName.ptr() )
118 }
119
120 //Найти событие в данном описании
121 method CompEvent CompDescr.FindEvent( str Name )
122 {
123 uint i
124 fornum i=0, *this.Events
125 {
126 if this.Events[i].EventName == Name
127 {
128 return this.Events[i]
129 }
130 }
131 return 0->CompEvent
132 }
133
134 //Найти свойство в данном описании
135 method CompProp CompDescr.FindProp( str Name )
136 {
137 //int i
138 //for i= *this.Props - 1, i >=0, i--
139 uint i
140 fornum i=0, *this.Props
141 {
142 if this.Props[i].PropName == Name
143 {
144 return this.Props[i]
145 }
146 }
147 return 0->CompProp
148 }
149
150
151
152 //Добавить новый тип компонента
153 method VEManProps.AddComp( uint typeid, uint viscomp, str group, str file )
154 {
155 uint i
156 uint fnc
157 uint descr as this.Descrs[this.Descrs.expand(1)]
158 uint typedef as gettypedef( typeid )
159 descr.TypeName = typedef.TypeName
160 descr.TypeId = typeid
161 descr.VisComp = viscomp
162 descr.File = file
163
164 //Получение свойств наследуемых свойств объекта
165 while typedef
166 {
167 uint inhtypeid, inh
168 if inhtypeid = typedef.InheritTypeId
169 {
170 uint inh as this.GetCompDescr( inhtypeid )
171 if inh
172 {
173 descr.Props.expand( *inh.Props )
174 fornum i=0, *inh.Props
175 {
176 uint left as descr.Props[i]
177 uint right as inh.Props[i]
178 left.PropName = right.PropName
179 left.PropType = right.PropType
180 left.PropFlags = right.PropFlags
181 left.AddrGet = right.AddrGet
182 left.AddrSet = right.AddrSet
183 //left.Vals = right.Vals
184 if right.Vals
185 {
186 left.Vals = new( arr, CompEnumVal, 0 )
187 uint lar as left.Vals->arr of CompEnumVal
188 uint rar as right.Vals->arr of CompEnumVal
189 lar.expand( *rar )
190 uint j
191 fornum j = 0, *lar
192 {
193 lar[j].Name = rar[j].Name
194 lar[j].Val = rar[j].Val
195 }
196 }
197 left.DefVal = right.DefVal
198 }
199 descr.Events.expand( *inh.Events )
200 fornum i=0, *inh.Events
201 {
202 uint left as descr.Events[i]
203 uint right as inh.Events[i]
204 left.EventName = right.EventName
205 left.EventType = right.EventType
206 left.EventId = right.EventId
207 }
208 break
209 }
210 typedef as gettypedef( inhtypeid )
211 }
212 else
213 {
214 break
215 }
216 }
217 /*
218 if typedef.InheritTypeId
219 {
220 uint inh as this.GetCompDescr( typedef.InheritTypeId )
221 if inh
222 {
223 descr.Props.expand( *inh.Props )
224 fornum i=0, *inh.Props
225 {
226 uint left as descr.Props[i]
227 uint right as inh.Props[i]
228 left.PropName = right.PropName
229 left.PropType = right.PropType
230 left.AddrGet = right.AddrGet
231 left.AddrSet = right.AddrSet
232 left.Vals = right.Vals
233 left.DefVal = right.DefVal
234 }
235 descr.Events.expand( *inh.Events )
236 fornum i=0, *inh.Events
237 {
238 uint left as descr.Events[i]
239 uint right as inh.Events[i]
240 left.EventName = right.EventName
241 left.EventType = right.EventType
242 left.EventId = right.EventId
243 }
244 }
245
246 }*/
247
248 /*fnc = getid( "mRegProps", 1, %{TypeId, uint, VEManProps} )
249 if fnc : fnc->func( 0, TypeId, this )
250 */
251 //Сортировка
252
253 // fnc = getid( "getevents", 1, %{TypeId, uint, VEManProps} )
254 // if fnc : fnc->func( 0, TypeId, this )
255 // descr.Events.sort(&sortstr)
256
257 //Получение значений свойств по умолчанию
258 uint excomp = new( typeid )//&newcomp( TypeId, 0->vComp ) //создание временного объекта
259 //print( "descr \(typeid) \(*descr.Props )\n" )
260 fornum i = 0, *descr.Props
261 {
262 //print( "add3 \(i) \(*descr.Props) \(excomp) \( descr.Props[i].GetVal( excomp->vComp ))\n" )
263 descr.Props[i].DefVal = descr.Props[i].GetVal( excomp->vComp )
264 }
265 destroy( excomp ) //удаление временного объекта
266
267 }
268
269
270 method VEManProps.AddComp( uint typeid )
271 {
272 this.AddComp( typeid, 0, "", "" )
273 }
274
275 //Добавить свойства
276 method VEManProps.AddProps( uint TypeId, collection col )
277 {
278 uint comp as this.GetCompDescr( TypeId )
279 uint prop
280 uint i
281 if &comp
282 {
283 i = 0
284 while i < *col
285 {
286 prop as cm.GetCompDescr( TypeId ).FindProp( col[i]->str )
287 if !&prop : prop as comp.Props[comp.Props.expand(1)]
288 prop.PropName = col[i++]->str
289 prop.PropType = col[i++]
290 prop.PropFlags = col[i++]
291 prop.AddrGet = getid( prop.PropName, 1, %{TypeId} )
292 prop.AddrSet = getid( prop.PropName, 1, %{TypeId, prop.PropType} )
293 //print( p.Name + " \(p.TypeId)\n" )
294 }
295 //print( "START SORT \(*descr.Props)\n" )
296 comp.Props.sort(&sortstr)
297 }
298 }
299
300 //Добавить перечисление возможных значений
301 method VEManProps.AddPropVals( uint TypeId, str propName, collection col )
302 {
303
304 uint comp as this.GetCompDescr( TypeId )
305 if &comp
306 {
307 uint prop as comp.FindProp( propName )
308 if &prop
309 {
310 if !prop.Vals
311 {
312 prop.Vals = new( arr, CompEnumVal, 0 )
313 //prop.Vals->arr.oftype( CompEnumVal )
314 uint ar = prop.Vals
315 ar as (arr[] of CompEnumVal)
316 ar.expand( *col>>1 )
317 uint i, j
318 while i < *col
319 {
320 //print( "col=\(col.Val(i)->str)\n" )
321 ar[j].Name = col[i++]->str
322 ar[j++].Val = col[i++]
323 }
324 }
325 }
326 }
327 }
328
329
330 //Добавить события
331 method VEManProps.AddEvents( uint TypeId, collection col )
332 {
333 uint comp as this.GetCompDescr( TypeId )
334 uint event
335 uint i
336 if &comp
337 {
338 i = 0
339 uint id = *comp.Events
340 while i < *col
341 {
342 event as comp.Events[comp.Events.expand(1)]
343 event.EventName = col[i++]->str
344 event.EventType = col[i++]->str
345 event.EventId = id++
346 //print( "addevents " + event.Name + " \(event.evtype)\n" )
347 }
348 }
349 }
350
351
352 method CompProp.delete
353 {
354 if this.Vals
355 {
356 destroy( &(this.Vals->arr[] of CompEnumVal) )
357 }
358 }
359
360 //Получить имя значения перечисления
361 method str CompProp.GetEnumName <result>( uint Val )
362 {
363 if this.Vals
364 {
365 uint ar = this.Vals
366 uint i
367 ar as (arr[] of CompEnumVal)
368 fornum i=0, *ar
369 {
370 if ar[i].Val == Val
371 {
372 result = ar[i].Name
373 return
374 }
375 }
376 }
377 }
378
379 //Получить значение перечисления по имени
380 method uint CompProp.GetEnumVal ( str Name, uint res )
381 {
382 if this.Vals
383 {
384 uint ar = this.Vals
385 uint i
386 ar as (arr[] of CompEnumVal)
387 fornum i=0, *ar
388 {
389 if ar[i].Name == Name
390 {
391 res->uint = ar[i].Val
392 return 1
393 }
394 }
395 }
396 return 0
397 }
398
399 //Установить значение свойства
400 method CompProp.SetVal ( vComp comp, ustr val )
401 {
402 if .AddrSet
403 {
404 switch .PropType
405 {
406 case uint, int
407 {
408 uint z = val.str().uint()
409 if .Vals
410 {
411 if .GetEnumVal( val.str(), &z ) : .AddrSet->func( comp, z )
412 }
413 else : .AddrSet->func( comp, z)
414 }
415 case ustr
416 {
417 .AddrSet->func( comp, val )
418 }
419 case str
420 {
421 .AddrSet->func( comp, val.str() )
422 }
423 default
424 {
425 if *val
426 {
427 uint link as comp.GetForm()->vComp.FindComp( val.str() )
428 if &link && link.TypeIs( .PropType )
429 {
430 .AddrSet->func( comp, link )
431 }
432 }
433 else
434 {
435 .AddrSet->func( comp, 0 )
436 }
437 }
438 }
439 }
440 }
441
442 //Получить значение свойства
443 method ustr CompProp.GetVal <result> ( vComp comp )
444 {
445 // print( "GetVal \(.PropName ) \(.PropType)\n" )
446 if this.AddrGet
447 {
448 switch this.PropType
449 {
450 case ustr
451 {
452 result = (this.AddrGet->func( comp, "" ))->ustr
453 }
454 case uint, int
455 {
456 int z = (this.AddrGet->func( comp ))
457 if this.Vals
458 {
459 result = this.GetEnumName(z)
460 }
461 else
462 {
463 result = "\(z)"
464 }
465
466 }
467 case str
468 {
469 result = (this.AddrGet->func( comp, "" ))->str
470 }
471 default
472 {
473 if this.PropType == vComp || type_isinherit( this.PropType, vComp )
474 {
475 uint link as this.AddrGet->func( comp )->vComp
476 if &link
477 {
478 uint checklink as App.FindComp( link )
479 if &checklink && checklink.TypeIs( .PropType )
480 {
481 result = link.Name
482 }
483 else
484 {
485 result = "".ustr()
486 .SetVal( comp, result )
487
488 }
489 }
490 }
491 }
492 }
493 }
494 }
495
496
497 method ustr CompEvent.GetVal <result> ( vComp comp )
498 {
499 //print( "event.GetVal 1 \(this.EventId)\n" )
500 uint index = comp.des1->arr of uint[this.EventId]
501 //print( "event.GetVal 2 \(index)\n" )
502 if index
503 {
504 result = ManEvents.Descrs[index].MethodName
505 }
506 //print( "event.GetVal 10\n" )
507 }
508
509 define
510 {
511 EVENT_DEL = 1
512 EVENT_NEW = 2
513 EVENT_RENAME = 4
514 }
515 method uint CompEvent.SetVal( vComp comp, ustr val )
516 {
517 uint setres
518 //print( "event.SetVal 1\n" )
519 if val != .GetVal( comp )
520 {
521 uint newindex = 0
522 uint oldindex
523 uint i
524 fornum i = 1, *ManEvents.Descrs
525 {
526 uint descr as ManEvents.Descrs[i]
527 if descr.MethodName == val.str()
528 {
529 if descr.EventType == .EventType
530 {
531 newindex = i
532 break
533 }
534 return 0
535 }
536 }
537
538 oldindex = comp.des1->arr of uint[this.EventId]
539
540 //index = findevent( val, .EventType )
541 if *val
542 {
543 if !newindex
544 {
545 if oldindex
546 {
547 newindex = oldindex
548 oldindex = 0
549 setres |= $EVENT_RENAME
550 }
551 else
552 {
553 newindex = ManEvents.Descrs.expand( 1 )
554 setres |= $EVENT_NEW
555 //comp.des1->arr of uint[this.EventId] = newindex
556 //ManEvents.Descrs[newindex].CompCount++
557 }
558 ManEvents.Descrs[newindex].MethodName = val
559 ManEvents.Descrs[newindex].EventType = .EventType
560 }
561 //else
562 if !( setres & $EVENT_RENAME )
563 {
564 comp.des1->arr of uint[this.EventId] = newindex
565 ManEvents.Descrs[newindex].CompCount++
566 }
567 }
568 else
569 {
570 comp.des1->arr of uint[this.EventId] = 0
571 }
572 if oldindex
573 {
574 ManEvents.Descrs[oldindex].CompCount--
575 if !ManEvents.Descrs[oldindex].CompCount
576 {
577 setres |= $EVENT_DEL
578 }
579 }
580 }
581 return setres
582 //print( "event.SetVal 10\n" )
583 }
584
585
586 //Получить список свойств для данной компоненты
587 method VEManProps.GetPropList( vComp comp, arr arp of PropItem, arr are of PropItem )
588 {
589 arp.clear()
590 are.clear()
591 uint descr as this.GetCompDescr( comp.TypeId )
592 if &descr
593 {
594 arp.expand( *descr.Props )
595 uint i
596 foreach item, arp
597 {
598 uint prop as descr.Props[i++]
599 item.Name = prop.PropName
600 item.Value = prop.GetVal( comp )
601 if item.Value == prop.DefVal
602 {
603 item.Flags |= $PI_DEFVAL
604 }
605 if prop.Vals ||
606 ( prop.PropType == vComp || type_isinherit( prop.PropType, vComp ))
607 {
608 item.Flags |= $PI_LIST
609 }
610
611 }
612 are.expand( *descr.Events )
613 //print( " GETEVENT\n" )
614 i = 0
615 foreach item, are
616 {
617
618 uint event as descr.Events[i]
619 item.Name = event.EventName
620 //print( "eventname = \(event.EventName)\n" )
621
622 item.Value = event.GetVal( comp )
623 /*if item.Value == prop.DefVal
624 {
625 item.Flags |= $PI_DEFVAL
626 }*/
627 item.Flags |= $PI_LIST
628
629 i++
630 }
631 }
632 }
633
634
635