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