- •Введение
- •1 Анализ предметной области
- •1.1 Постановка задачи
- •1.2 Обзор аналогов
- •2 Программная документация
- •2.1 Техническое задание на программное обеспечение
- •2.1.1 Назначение разработки
- •2.1.2 Терминология
- •2.1.3 Требования к функциональным характеристикам
- •2.1.4 Требования к надежности
- •2.1.5 Требования к составу и параметрам технических средств
- •2.1.6 Требования к информационной и программной совместимости
- •2.1.7 Требования к результатам работы
- •2.1.7.1 Требования к комплектации решения
- •2.1.7.2 Требования к документации
- •2.1.8 Перечень работ по этапам
- •2.2 Пояснительная записка
- •2.2.1 Назначение и область применения
- •2.2.2 Описание разработанной технологии создания программ для распределенных микроконтроллерных систем
- •2.2.2.1 Схема оборудования
- •2.2.2.2 Недостатки диаграммы Бара для проектирования микроконтроллерных программ управления
- •2.2.2.3 Концепции диаграммы задач
- •2.2.2.4 Семантика отображаемых на диаграмме задач связей
- •2.2.2.5 Синхронные и асинхронные вызовы функций задач
- •2.2.2.6 Синхронный вызов функции пакета
- •2.2.2.7 События и подписки
- •2.2.2.8 Текстовый язык
- •2.2.2 Технические характеристики
- •2.2.2.1 Описание структуры программной системы
- •2.2.2.1.1 Платформа разработки
- •2.2.2.1.2 Подсистема редактирования
- •2.2.2.1.3 Разработка графических редакторов
- •2.2.2.1.4 Разработка текстового редактора
- •2.2.2.1.5 Описание языка
- •2.2.2.1.6 Семантический анализ пользовательской программы
- •2.2.2.1.7 Генерация кода на целевом языке
- •2.2.2.1.8 Генерация кода редактора текстового языка
- •2.2.2.1.9 Проектирование отладчика
- •2.2.2.1.10 Регистрация конфигурации запуска
- •2.2.2.1.11 Модель отладки
- •2.2.2.1.12 Виртуальная машина
- •2.2.2.1.13 Моделирование
- •2.2.2.1.14 Концепция параметризированных сигналов
- •2.2.2.1.15 Функциональное моделирование блоков устройств
- •2.2.3 Ожидаемые технико-экономические показатели
- •2.3 Описание программы
- •2.3.1 Описание логической структуры
- •2.3.1.2 Типичный поток событий в графическом редакторе
- •2.3.2 Входные и выходные данные
- •2.3.3 Используемые технические средства
- •2.4 Программа и методика испытаний
- •2.4.1 Программа испытаний
- •2.4.2 Методика испытаний
- •3 Руководство пользователя
- •3.2 Условия выполнения программного комплекса
- •3.3 Установка программы
- •3.4 Текстовый редактор
- •3.5 Графический редактор
- •4 Акт испытаний программного продукта
- •5 Экономическая часть
- •Заключение
- •Список использованных источников
Заключение
В ходе выполнения дипломной работы были изучены следующие технологии: технология GEF построения графических редакторов, библиотека Draw2D для отображения фигур на SWT-холсте, технология Xtext построения текстовых редакторов, технология Google Guice инжекции зависимостей, платформа TypeSystem для проверки совместимости типов объектов систем, технология разработки приложения на базе платформы Eclipse.
Это позволило разработать технологию описания программ для миконконтроллерных систем и систему интегрированной среды разработки программ, включающую графические и текстовый редакторы.
Проект имеет высокую экономическую эффективность, что показывают соответствующие расчеты в разделе 5 пояснительной записки.
Список использованных источников
1 Павлова Е. А. Технологии разработки современных информационных систем на платформе Microsoft.NET: Учебное пособие. – М.: Интернет-Университет Информационных Технологий; БИНОМ.Лаборатория Знаний, 2009.
2 Гуров В. В. Архитектура микропроцессоров. – М.: Интернет-Университет Информационных Технологий; БИНОМ.Лаборатория Знаний, 2010.
3 http://www.databeans.net.
4 Чистяков В. Ю. СОМ // Журнал «Технология Клиент-сервер», №2000-2.
5 Шопырин Д. Г., Шалыто А. А. Синхронное программирование // Информационно-управляющие системы, 2004. - № 3, с. 35-42.
6 Berry G., Gonthier G. The Esterel synchronous programming language: Design, semantics, implementation. Sci. Comput. Program., vol. 19, Nov. 1992. - pp. 87-152.
7 Caspi P., Pilaud D., Halbwachs N., Plaice J.A. LUSTRE: A declarative language for programming synchronous systems // In ACM Symp. Principles Program. Lang. (POPL), Munich, Germany, 1987, - pp. 178-188.
8 Benveniste A., Guemic P. Hybrid dynamical systems theory and the SIGNAL language // IEEE Trans. Automat. Contr., vol. AC-35, May 1990. - pp. 535-546.
9 ISO, IS 9074, Information Processing Systems - Open Systems Interconnection. - Estelle (Formal Description Technique based on an Extended State Transition Model), 1988.- p.180.
10 ISO - Information Processing Systems - Open Systems Interconnection. - LOTOS - A Formal Description Technique Based on the Temporal Ordering of Observational Behaviour, DIS 8807, 1987.
11 Saraco R., P. Tilanus A. J. CCITT SDL: Overview of the Language and its Applications // Computer Networks and ISDN Systems 13, 1987.- pp 65-74.
12 http://www.atmel.com/microsite/avr_studio_5/default.aspx.
13 http://winavr.sourceforge.net/.
14 http://www.hpinfotech.ro/html/cvavr.htm.
15 http://www.atmanecl.net/atmanavr/.
16 http://gcc.gnu.org/.
17 http://www.iar.com/en/Products/IAR-Embedded-Workbench/.
18 http://www.mikroe.com/eng/categories/view/97/mikroc/.
19 https://www.imagecraft.com/.
20 http://www.codeblocks.org/.
21 http://algrom.net/russian.html.
22 http://www.mcselec.com/index.php?option=com_content&task=view& id=14&Itemid=41.
23 http://cq.cx/ladder.pl.
24 http://www.ti.com/tool/ccstudio.
25 http://www.eclipse.org/.
26 http://www.microchip.com/pagehandler/en-us/family/mplabx/.
27 http://netbeans.org/.
28 http://www.mathworks.com/.
29 http://www.st.com/internet/com/software/ides_mcu.jsp.
30 http://www.atollic.com/index.php/truestudio.
31 http://www.matrixmultimedia.com/flowcode.php.
32 http://www.oracle.com/technetwork/java/index.html.
33 Бар Р. Язык Ада в проектировании систем: Пер. с англ. – М.: Мир, 1988.
34 http://www.microsoft.com/visualstudio/11/ru-ru.
35 http://www.borland.com/.
36 http://xtext.itemis.com/.
37 http://www.eclipse.org/gef/.
38 http://www.eclipse.org/swt/.
39 http://www.draw2d.org/draw2d/.
40 http://msdn.microsoft.com/en-us/library/ff649643.aspx.
41 http://www.eclipse.org/modeling/emf/.
42 http://code.google.com/p/google-guice/.
43 http://www.antlr.org/.
44 http://code.google.com/a/eclipselabs.org/p/xtext-typesystem/.
45 http://www.eclipse.org/xtend/.
46 http://www.lua.ru/.
47 http://www.keplerproject.org/luajava/.
48 http://www.labcenter.com/index.cfm.
49 http://www.eclipse.org/osgi/.
50 http://www.pic24.ru/doku.php/en/osa/ref/intro.
51 http://www.smlnj.org/doc/ML-Yacc/index.html.
52 Кустова Т. Н., Коновал О. В. Методические рекомендации по технико-экономическому обоснованию дипломных работ студентов специальности 220400 Программное обеспечение вычислительной техники и автоматизированных систем. – Рыбинск: РГАТА, 2003.
53 http://sourceforge.net/projects/winavr/files/stats/timeline?dates=2011-05-16+to+2012-05-16
54 http://www.eetimes.com/design/microcontroller-mcu/4218776/Standardization-in-software-tools-boosts-development-of-next-generation-applications.
55 ГОСТ 12.1.009-76 - Система стандартов безопасности труда. Электробезопасность. Термины и определения.
56 ГОСТ 12.1.019-79 - Система стандартов безопасности труда. Электробезопасность. Общие требования и номенклатура видов защиты.
57 ГОСТ 12.1.038-82 - Система стандартов безопасности труда. Электробезопасность. Предельно допустимые значения напряжений прикосновения и токов.
58 ГОСТ 12.1.030-81 - Система стандартов безопасности труда. Электробезопасность. Защитное заземление, зануление.
Приложение А
Параметры аналогов разрабатываемого программного средства
Таблица А.1 – Параметры аналогов разрабатываемого программного средства
Продукт |
Программируемые архитектуры МК |
Стоимость |
Характеристика |
IAR Embedded Workbench Prof. |
AVR, PIC, ARM |
€1295- €2395 |
IDE устаревшая, язык С, эффективный компилятор |
Code Сomposer Studio |
Все от Texas Instruments |
$495-$795 |
IDE современная, язык С |
Atollic True Studio |
ARM, AVR UC3, Toshiba TX |
€995 |
IDE современная, язык С |
ICC8 |
AVR |
$99-$549 |
Компилятор, язык С |
MicroC / Pascal /Basic PRO |
AVR, PIC, 8051, ARM |
$199 - $249 |
IDE современная, язык С, Pascal, Basic |
CodeVisionAVR |
AVR |
€150 |
IDE устаревшая, язык С |
Flowcode |
AVR, PIC |
€39- €149 |
IDE современная, блок-схемы |
AtmanAVR |
AVR |
$120 |
IDE – современная, язык С |
BASCOM-AVR |
AVR |
$79-$85 |
IDE устаревшая, язык Basic |
AVR Studio |
AVR |
Бесплатен |
IDE современная, язык С, исп-ет WinAVR |
Microchip MPLAB X IDE |
PIC |
Бесплатен |
IDE-современная, язык С |
WinAVR |
AVR |
Бесплатен |
Пакет, включающий компилятор языка С |
Algorithm Builder |
AVR |
Бесплатен |
IDE устаревшая, блок-схемы + ассемблер, не поддерживается с 2009 года |
Приложение Б
Грамматика текстового языка в нотации Xtext
grammar org.xtext.example.mydsl.MyDsl hidden(WS, ML_COMMENT, SL_COMMENT, LINE_COMMAND)
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Model: tu = translation_unit;
// Terminal Fragments
terminal fragment EscapeSequence: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') | OctalEscape;
terminal fragment OctalEscape:
'\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
terminal fragment HexDigit : ('0'..'9'|'a'..'f'|'A'..'F');
terminal fragment IntegerTypeSuffix: ('u'|'U') | ('l'|'L') | ('u'|'U') ('l'|'L') | ('l'|'L') ('u'|'U');
terminal fragment Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+;
terminal fragment FloatTypeSuffix : ('f'|'F'|'d'|'D') ;
terminal fragment LETTER: '$' | 'A'..'Z' | 'a'..'z' | '_';
// Terminals
terminal CHARACTER_LITERAL: "'" ( EscapeSequence | !("'"|'\\') ) "'" ;
terminal STRING_LITERAL: '"' ( EscapeSequence | !('"' | '\\') )* '"';
terminal fragment UnicodeEscape: '\\' 'u' HexDigit HexDigit HexDigit HexDigit;
terminal ID: LETTER (LETTER|'0'..'9')*;
terminal HEX_LITERAL: '0' ('x'|'X') HexDigit+ IntegerTypeSuffix? ;
terminal DECIMAL_LITERAL : ('0' | '1'..'9' '0'..'9'*) IntegerTypeSuffix? ;
terminal OCTAL_LITERAL : '0' ('0'..'7')+ IntegerTypeSuffix? ;
terminal FLOATING_POINT_LITERAL:
('0'..'9')+ '.' ('0'..'9')* Exponent? FloatTypeSuffix?
| '.' ('0'..'9')+
| '.' ('0'..'9')+ Exponent
| '.' ('0'..'9')+ FloatTypeSuffix
| '.' ('0'..'9')+ Exponent FloatTypeSuffix
| ('0'..'9')+ Exponent
| ('0'..'9')+ FloatTypeSuffix
| ('0'..'9')+ Exponent FloatTypeSuffix
;
terminal WS: (' ' | '\t' | '\r' | '\n')+;
terminal ML_COMMENT: '/*'->'*/';
terminal SL_COMMENT: '//' !('\n' | '\r')* ('\r'? '\n')?;
terminal LINE_COMMAND: '#' !('\n'|'\r')* '\r'? '\n';
translation_unit:
{translation_unit} (ext_decls += external_declaration)*
;
external_declaration:
(=> declaration)
| function_definition
| isr_definition
| package_definition
;
function_definition:
decl_specs = declaration_specifiers?
declrtor = declarator
//(decl += declaration)+ compound_stment = compound_statement| // K&R style
compound_stment = compound_statement // ANSI style
;
isr_definition:
'ISR' '(' isr_id = ID ')'
compound_stment = compound_statement // ANSI style
;
package_definition:
'package' name = ID
('for' target = ID)?
( "imports" imprt += [package_definition | ID])*
'{'
(tasks += task_definition)*
'}'
;
task_definition:
'task' name = ID
(refs += calls_definition)*
compound_stment = task_compound_statement
;
calls_definition:
'calls' task_ref = [task_definition | ID] '.' func_ref = ID
;
declaration:
type_def
| event_decl
| usual_decl
;
type_def:
('typedef' (specs = declaration_specifiers)? init_decl_list = init_declarator_list ';' )
;
usual_decl:
specs = declaration_specifiers init_decl_list = init_declarator_list? ';'
;
event_decl:
'event' event_decl = direct_declarator ';'
;
declaration_specifiers:
( stor_cs += storage_class_specifier
| type_specs += type_specifier
| type_quals += type_qualifier
)+
;
init_declarator_list:
decls += init_declarator (',' decls += init_declarator)*
;
init_declarator:
decl = declarator ('=' init = initializer)?
;
storage_class_specifier:
'extern' {extern_storage}
| 'static' {static_storage}
| 'auto' {auto_storage}
| 'register' {register_storage}
;
type_specifier returns type_specifier:
'void' {ts_void}
| 'char' {ts_char}
| 'short' {ts_short}
| 'int' {ts_int}
| 'long' {ts_long}
| 'float' {ts_float}
| 'double' {ts_double}
| 'signed' {ts_signed}
| 'unsigned' {ts_unsigned}
| struct_or_union_specifier
| enum_specifier
;
struct_or_union_specifier:
(str_or_un = struct_or_union name = ID ('{' decl_list = struct_declaration_list '}')?)
//| '{' decl_list = struct_declaration_list '}'
;
enum struct_or_union:
STRUCT = 'struct'
| UNION = 'union'
;
struct_declaration_list:
(decls += struct_declaration)+
;
struct_declaration:
sq_list = specifier_qualifier_list sd_list = struct_declarator_list ';'
;
specifier_qualifier_list:
( type_quals += type_qualifier
| type_specs += type_specifier
)+
;
struct_declarator_list:
decl += struct_declarator (',' decl += struct_declarator)*
;
struct_declarator:
decl = declarator (':' expr = constant_expression)?
| ':' expr = constant_expression
;
enum_specifier:
'enum' '{' enum_list = enumerator_list '}'
| 'enum' name = ID '{' enum_list = enumerator_list '}'
| 'enum' name = ID
;
enumerator_list:
enums += enumerator (',' enums += enumerator)*
;
enumerator:
name = ID ('=' expr ?= constant_expression)?
;
type_qualifier:
{const_tq} 'const'
| {volatile_tq} 'volatile';
abstract_declarator:
point = pointer (dir_ab_decl = abstract_direct_declarator)?
| dir_ab_decl = abstract_direct_declarator
;
abstract_direct_declarator:
( '(' abstract_declarator ')' | suffixes += abstract_declarator_suffix )
(suffixes += abstract_declarator_suffix)*
;
abstract_declarator_suffix:
'[' {ab_decl_suf_emptyarray} ']'
| '[' {ab_decl_suf_emptyarray} bound_expr = constant_expression ']'
| '(' {ab_decl_suf_empty} ')'
| '(' {ab_decl_suf_paramlist} param_list = parameter_type_list ')'
;
declarator:
point = pointer (dir_decl = direct_declarator)?
| dir_decl = direct_declarator
;
direct_declarator:
('(' declarator ')' | name = ID)
(suffixes += declarator_suffix)*
;
declarator_suffix returns declarator_suffix:
'[' {decl_suf_emptyarray} ']'
| '[' {decl_suf_fullarray} bound_expr = constant_expression ']'
| '(' {decl_suf_empty}')'
| '(' {decl_suf_param_list} param_list = parameter_type_list ')'
;
pointer:
{pointer} '*' (type_quals += type_qualifier)+ subpoint = pointer?
| {pointer}'*' subpoint = pointer
| {pointer} '*'
;
parameter_type_list:
parameter_list (',' '...')?
;
parameter_list:
decls += parameter_declaration (',' decls += parameter_declaration)*
;
parameter_declaration:
specs = declaration_specifiers
(
decl = declarator
)
;
type_name:
spec_qual_list = specifier_qualifier_list
ab_decl = abstract_declarator?
;
initializer:
'{' init_list = initializer_list ','? '}'
| assignment_expression
;
initializer_list:
inits += initializer (',' inits += initializer)*
;
// Expressions
expression:
assigns += assignment_expression (',' assigns += assignment_expression)*
;
constant_expression: conditional_expression;
argument_expression_list:
assign_expr += assignment_expression (',' assign_expr += assignment_expression)*
;
assignment_expression:
=> (left_expr = unary_expression op = assignment_operator)
right_expr = assignment_expression
| cond = conditional_expression
;
assignment_operator returns assignment_operator:
{AssignOP} '='
| {AssignMultOp} '*='
| {AssignDivOp} '/='
| {AssignModOp} '%='
| {AssignPlusOp} '+='
| {AssignMinusOp} '-='
| {AssignLeftShiftOp} '<<='
| {AssignRightShiftOp} '>>='
| {AssignAndOp} '&='
| {AssignXorOp} '^='
| {AssignOrOp} '|='
;
conditional_expression returns arithmetic_expr:
logical_or_expression ( '?' {CondExpr.expr = current} left_expr = expression ':' right_expr = conditional_expression)?
| was_called_expression
;
was_called_expression:
func_ref = ID '?'
;
logical_or_expression returns arithmetic_expr:
logical_and_expression ('||' {LogicOrExpr.left = current} right = logical_and_expression)*
;
logical_and_expression returns arithmetic_expr:
inclusive_or_expression ('&&' {LogicAndExpr.left = current} right = inclusive_or_expression)*
;
inclusive_or_expression returns arithmetic_expr:
exclusive_or_expression ('|' {InclOrExpr.left = current} right = exclusive_or_expression)*
;
exclusive_or_expression returns arithmetic_expr:
and_expression ('^' {ExclOrExpr.left = current} right = and_expression)*
;
and_expression returns arithmetic_expr:
equality_expression ('&'{AndExpr.left = current} right = equality_expression)*
;
equality_expression returns arithmetic_expr:
relational_expression (
('=='{EqualExpr.left = current}
|'!=' {NotEqualExpr.left = current}
)
right = relational_expression
)*
;
relational_expression returns arithmetic_expr:
shift_expression (
('<' {LessExpr.left = current}
|'>' {MoreExpr.left = current}
|'<='{LessEqualsExpr.left = current}
|'>='{MoreEqualsExpr.left = current}
)
right = shift_expression
)*
;
shift_expression returns arithmetic_expr:
additive_expression (
('<<'{LeftShiftExpr.left = current}
|'>>'{RightShiftExpr.left = current}
)
right = additive_expression
)*
;
additive_expression returns arithmetic_expr:
substraction_expression ('+' {Plus.left = current} right = substraction_expression)*
;
substraction_expression returns arithmetic_expr:
multiplicative_expression ('-' {Minus.left = current} right = multiplicative_expression)*
;
multiplicative_expression returns arithmetic_expr:
cast_expression
('*' {Mult.left = current} right = cast_expression
| '/' {Div.left = current} right = cast_expression
| '%' {DivPers.left = current} right = cast_expression
)*
;
cast_expression returns arithmetic_expr:
'(' type_n = type_name ')' right = cast_expression
| unary_expression
;
unary_expression returns arithmetic_expr:
postfix_expression
| '++' {IncPrefix} right = unary_expression
| '--' {DecPrefix} right = unary_expression
| unary_operator right = cast_expression
| 'sizeof' {SizeOfExprPrefix} right = unary_expression
| 'sizeof' '(' type_name ')'
| 'send' right = postfix_expression
;
postfix_expression returns arithmetic_expr:
primary_expression
('[' {indexing_expression.left = current} expr = expression ']'
| '(' {emptymethod_expression.left = current} ')'
| '(' 'void' {emptymethod_expression.left = current} ')'
| '(' {fullmethod_expression.left = current} arglist = argument_expression_list ')'
| '.' {structcast_expression.left = current} structcast = ID
| '->' {structcast_expression.left = current} structcast = ID
| '++' {inc_op_expression.left = current}
| '--' {dec_op_expression.left = current}
)*
;
unary_operator:
'&' {AndOpPrefix}
| '*' {PointOpPrefix}
| '+' {AddOpPrefix}
| '-' {MinusOpPrefix}
| '~' {XorOpPrefix}
| '!' {NotOpPrefix}
;
primary_expression returns arithmetic_expr:
{ID_expression} value = ID
| {const_expression} value = constant
| '(' expression ')'
;
constant:
HEX_LITERAL
| OCTAL_LITERAL
| DECIMAL_LITERAL
| CHARACTER_LITERAL
| STRING_LITERAL
| FLOATING_POINT_LITERAL
;
// S t a t e m e n t s
statement:
labeled_statement
| compound_statement
| wait_called_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
;
labeled_statement returns labeled_statement:
ID {LabelStment} ':' stment = statement
| 'case' {CaseStment} const_expr = constant_expression ':' stment = statement
| 'default' {DefaultStment} ':' stment = statement
;
task_compound_statement:
'{' {task_compound_statement}
(=> decls += declaration)*
(funcs += function_definition)*
('body' body_cmpst = compound_statement)
'}'
;
compound_statement:
'{' {compound_statement}
(decls += declaration)*
(stment += statement)*
'}'
;
expression_statement:
(=> expr = expression ';')
| {expression_statement} ';'
;
wait_called_statement:
func = ID '!' ';'
;
selection_statement:
'if' {ifStment} '(' expr = expression ')' then_stment = statement => ('else' else_stment = statement)?
| 'switch' {SwitchStment} '(' expr = expression ')' stment = statement
;
iteration_statement:
'while' {WhileStment} '(' expr = expression ')' stment = statement
| 'do' {DoWhileStment} stment = statement 'while' '(' expr = expression ')' ';'
| 'for' {ForStment} '(' (expr_stment1 = expression_statement | decl = declaration) expr_stment2 = expression_statement inc_expr = expression? ')' body_stment = statement
;
jump_statement:
'goto' {GotoStment} target = ID ';'
| 'continue' {ContinueStment} ';'
| 'break'{BreakStment} ';'
| 'return'{EmptyReturnStment} ';'
| 'return' {ReturnExprStment} expr = expression ';'
;
Приложение В
Дополнительные иллюстрации
#include <avr/io.h>
package package1 for atmega8
{
task task1
calls task2.func2
calls task3.func4
{
event myevent(int x, int y);
int a, b = 3;
void func1() {}
body
{
myevent += send task2.func1;
while (true)
{
task2.func2();
delay_ms(1000);
send task3.func4();
myevent(5, 6);
}
myevent -= send task2.func1;
}
}
task task2
{
void func1(int x, int y)
{
PORTA = low(x);
PORTB = low(y);
PORTB[0] = 0;
}
void func2() {}
body
{
while (true)
{
if (func2?)
func2!;
}
}
}
task task3
{
void func4(){}
body
{
task4.stop();
}
}
task task4
{
body
{
while (true){}
}
}
}
Рисунок Б.1 – Пример программы на разработанном текстовом языке с подсветкой синтаксиса
Рисунок Б.2 – Типичный ход событий при возникновении события от пользователя в графическом редакторе
Приложение Г
Исходный код контролера ContainerShapeEditPart на языке Java
package org.eclipse.gef.examples.shapes.parts;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.OrderedLayout;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gef.examples.shapes.figures.MyRoundedRectangle;
import org.eclipse.gef.examples.shapes.model.ContainerElem;
import org.eclipse.gef.examples.shapes.model.Elem;
import org.eclipse.gef.examples.shapes.model.NodeElem;
import org.eclipse.gef.examples.shapes.model.PackageElem;
import org.eclipse.gef.examples.shapes.model.TaskElem;
import org.eclipse.gef.examples.shapes.policies.MyFlowLayoutEditPolicy;
import org.eclipse.gef.examples.shapes.policies.ShapeComponentEditPolicy;
import org.eclipse.swt.graphics.Font;
public class ContainerShapeEditPart extends AbstractGraphicalEditPart implements PropertyChangeListener
{
private ConnectionAnchor anchor;
public void activate()
{
if (!isActive())
{
super.activate();
((Elem) getModel()).addPropertyChangeListener(this);
}
}
protected void createEditPolicies()
{
// чтобы можно было удалять
installEditPolicy(EditPolicy.COMPONENT_ROLE, new ShapeComponentEditPolicy());
// чтобы к нему можно было добавлять и перемещать свойства
installEditPolicy(EditPolicy.LAYOUT_ROLE, new MyFlowLayoutEditPolicy());
}
protected IFigure createFigure()
{
MyRoundedRectangle f = (MyRoundedRectangle) createFigureForModel();
f.setOpaque(true); // non-transparent figure
f.setCornerDimensions(new Dimension(10, 10));
Label label = new Label("Container");
label.setFont(new Font(null, "", 10, 1));
label.setForegroundColor(ColorConstants.blue);
f.add(label, 0);
ToolbarLayout layout = new ToolbarLayout(false);
layout.setStretchMinorAxis(true);
layout.setMinorAlignment(OrderedLayout.ALIGN_CENTER);
f.setLayoutManager(layout);
f.setBackgroundColor(ColorConstants.white);
return f;
}
private IFigure createFigureForModel()
{
if (getModel() instanceof TaskElem)
{
return new MyRoundedRectangle();
}
else if (getModel() instanceof PackageElem)
{
return new MyRoundedRectangle();
}
else
{
throw new IllegalArgumentException();
}
}
public void deactivate()
{
if (isActive())
{
super.deactivate();
((Elem) getModel()).removePropertyChangeListener(this);
}
}
private ContainerElem getCastedModel()
{
return (ContainerElem) getModel();
}
protected List getModelSourceConnections()
{
return getCastedModel().getSourceConnections();
}
protected List getModelTargetConnections()
{
return getCastedModel().getTargetConnections();
}
@Override
protected List getModelChildren()
{
return getCastedModel().getChildren();
}
public void propertyChange(PropertyChangeEvent evt)
{
String prop = evt.getPropertyName();
if (NodeElem.SIZE_PROP.equals(prop) || NodeElem.LOCATION_PROP.equals(prop))
{
refreshVisuals();
}
else if (ContainerElem.CHILD_ADDED_PROP.equals(prop) || ContainerElem.CHILD_REMOVED_PROP.equals(prop))
{
refreshChildren();
refreshVisuals();
}
else if (NodeElem.SOURCE_CONNECTIONS_PROP.equals(prop))
{
refreshSourceConnections();
}
else if (NodeElem.TARGET_CONNECTIONS_PROP.equals(prop))
{
refreshTargetConnections();
}
else if (NodeElem.NAME_PROP.equals(prop))
{
refreshVisuals();
}
}
protected void refreshVisuals()
{
IFigure figure = getFigure();
NodeElem model = (NodeElem)getModel();
((Label)(figure.getChildren().get(0))).setText(model.getName());
Rectangle bounds = new Rectangle(getCastedModel().getLocation(), getCastedModel().getSize());
((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), bounds);
}
}