terça-feira, 21 de fevereiro de 2006

Understanding Delphi's codetemplate

For those who don’t know code templates we can say that they are models of codes made to improve the process of development time.

When you are writing your code just press the Ctrl+J to show the code templates list or type the code template name and press Space, the Delphi IDE will write the template code to be edited. Code templates can be made to appear in Delphi’s code completition.

So let’s create our code template.

1º - Go to View -> Templates, it will open a lateral bar with all of Delphi installed templates.
2º - Click at the new button, located at the top of the templates names.

A new document called template1.xml will be created with the follow tags:

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns=" http://schemas.borland.com/Delphi/2005/codetemplates " version="1.0.0">
<template name="" invoke="manual">
<description>
</description>
<author>
</author>
<code language=""><![CDATA[]]> </code>
</template>
</codetemplate>

The first and the second line it’s just xml markup tags and it doesn’t need to be edited.
The template tag has a property called name, here you have to specify the name of our template (The name that will be displayed in IDE) and the property invoke that is used for:
Invoke = “auto”: The IDE will automatic load the template when it’s been typed.
Invoke = “manual”: The IDE will load the template after you typed and press the Tab Key.
Invoke = “none”: The template will be load just after press Ctrl+J and selecting from the list or pressing Ctrl+Space and selecting from the list.
The descripition tagis used to describe what this template is used for, like showed:
<description> This is a test template </description>
The autor tag is used for identify the templates autor ;) like showed:
<autor> Diego M. Garcia </autor>

Before we go to the code tag we have to know another tag called point that is used to identify the points of the code that should be navigable through the Tab Key.
The point tag should always have its name seted to be used in the code tag, so write your point tag like below:
<point name=”test”></point>

Now we should expecifie the text that will be displayed by the IDE inside the editor, to do that, add a tag named text inside the point tag like bellow:
<point name=”test”>
<text> TextToBeChanged </text>
</point>

It’s possible to add the tag called hint to display a hint when the mouse cursor is over the text.
Ex.:

<point name=”test”>
<text> TextToBeChanged </text>
<hint> This is a test Hint Text </hint>
</point>
Ps.: The code template can have more than one point tag.
We still have one tag to see before go to the code tag, that tag is the script tag that is used to call different types of services through IDE like declare a variable and other ones, to know a little more about it take a look at the code templates that come with Delphi. The script tag have a property called language that must be specified or Delphi wouldn’t know. In our case it would be Delphi, the script tag can have two properties to specify when the script will be triggered, the first is onenter=”true” that calls the script when the code template is loaded and the second is onleave=”true” that is called when the user end edit the code template.
Ex.:
<script language=” Delphi” onenter=”false” onleave=”true”>
</script>
The DeclareVariable command can be used in the script tag and it should reference an point tag that has the variable name definition in its text tag like below:
<point name="InternalVarName">
<text>
TypeAnIntegerValue</text>
<hint>
Variable to be used. </hint>
</point>

<script language="Delphi" onenter="false" onleave="true">
DeclareVariable(InternalVarName);
</script>

Ps.: The characters “|” (Pipes) are used before and after the name of the point tag, they are delimiters.

Until now I haven’t found a way to especify the type of an variable, because the editor automatic assumes the type passed to it.
The code tag write the code to the IDE editor our code template, it has the property language that works like the one in the script tag and the property delimiter that is used to identify the point tag names, in our case it will be the “|” pipe character, take a look above:
<code language=”Delphi” delimiter=””>
<![CDATA[]]>
</code>
Take a look at the automaticaly generated tag called CDATA, pay attention, the code to be displayed must be inside the characters [] or your code wouldn’t be displayed.
Lets write an code template to convert some value to Integer.
To do that add the code inside the CDATA tag.
InternalVarName := Convert.ToInt32(test);
 

Here is the full code template code:

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns=" http://schemas.borland.com/Delphi/2005/codetemplates " version="1.0.0">
<template name="TestTemplate" invoke="manual">
<description> This is a test template </description>
<author>
Diego M. Garcia
</author>
<point name=”test”>
<text> TextToBeChanged </text>
<hint> This is a test Hint Text </hint>
</point>
<point name="InternalVarName">
<text>TypeAnIntegerValue</text>
<hint>Variable to be used. </hint>
</point>
<script language="Delphi" onenter="false" onleave="true">
DeclareVariable(InternalVarName);
</script>
<code language="Delphi" delimiter=””><![CDATA[InternalVarName := Convert.ToInt32(test);]]> </code>
</template>
</codetemplate>
Save and Execute your template through Ctrl + J or in case you have changed the invoke to auto, then just type the name of the template and press Space.
Ps.: Sometimes Delphi gives some errors when editing inside its editor, if it happens you have to close the IDE an open it again.

Take a look at the templates that comes with Delphi to discover other tags and other properties.

I Hope you guys have liked ;)

Regards,
Diego.

sexta-feira, 17 de fevereiro de 2006

Entendendo Code Templates do Delphi

Para quem não conhece os codetemplates são modelos de códigos feitos para facilitar e agilizar o processo de desenvolvimento na hora em que você está escrevendo seu código.

Basta você pressionar Ctrl+J para que os codetemplates sejão exibidos ou digite o nome de seu codetemplate pressione espaço, que o delphi escrevera todo o código do seu template para que ele seja alterado. Os codetemplates podem também ser configurados para aparecerem no codecompletition do delphi.

Bom chega de papo furado vamos criar nosso codetemplate.

1º - Vá no menu View->Templates abrira uma barra lateral com todos os templates instalados no delphi.

2º - Clique no botão New que fica em cima dos nomes dos templates.

Será criado um novo documento chamado template1.xml com as seguintes tags:

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns=" http://schemas.borland.com/Delphi/2005/codetemplates " version="1.0.0">
<template name="" invoke="manual">
<description>
</description>
<author>
</author>
<code language=""><![CDATA[]]> </code>
</template>
</codetemplate>

As duas primeiras linhas são apenas de identificação do xml e do codetemplate não precisão ser modificadas. A tag template possui uma propriedade chamada name e é nela que você especificará o nome do seu template, (O que aparecera na IDE) e a propriedade invoke que server para:

invoke="auto": a IDE deverá acionar automaticamente seu template quando o mesmo for digitado.

invoke="manual": será acionado quando for digitado o nome do template e pressionar a tecla TAB ou apenas pressionar Ctrl+J ou Ctrl+Espaço e selecionar da lista de templates.

invoke="none": será acionado apenas quando o usuário pressionar Ctrl+J ou Ctrl+Espaço e selecionar da lista de templates.

*Obrigado pela dica do invoke="none" Leonel :).

A tag description server para você colocar uma descrição sobre o seu template, como abaixo:
<description> Template de teste </description>

E a tag autor serve para você colocar o nome do autor do template, ficando assim:
<autor> Diego M. Garcia </autor>

Antes de entrarmos na tag code temos que conhecer uma outra tag chamada point que serve para indicar os pontos que serão navegáveis através da tecla tab do teclado para que o usuário mude o conteúdo rapidamente.

A tag point deve sempre conter a propriedade name para que na seção code você possa referenciar a tag point, para isso escreva sua tag point como abaixo:

<point name="teste"></point>

Agora precisamos especificar o conteúdo que irá aparecer na tag point escrito no editor, para isso adicione a tag text dentro da tag point como abaixo:

<point name="teste"><text> TextoAserSubstituido </text></point>

é possível também colocar uma outra tag chamada hint para exibir um hint quando o cursor do mouse estiver em cima do texto.
Ex.: <point name="teste">
<text> TextoAserSubstituido
</text>
<hint>Esse é um texto de teste.</hint>

Obs.: seu codetemplate pode ter mais de uma tag point.

Ainda temos mais uma tag que deve ser abordada antes da tag code, esta tag é a script que é utilizada para que a IDE realize diversos tipos de serviços como declarar uma variável e outros, para saber um pouco mais olhe os templates que já vem com o delphi. A tag script possui uma propriedade chamada language que deve ser especificado para que o delphi reconheça o comando, no nosso caso o language será Delphi, na tag script você pode especificar também se o script será executado quando o codetemplate for acionado, setando sua propriedade onenter="true" ou quando o usuário terminar de utilizar o codetemplate setando sua propriedade onleave="true", ficando assim:

<script language=" Delphi" onenter="false" onleave="true">
</script>

O comando DeclareVariable que pode ser utilizado na tag script deve sempre referenciar uma tag point que contenha a definição do nome desta variável em sua tag text como abaixo:
<point name="NomeInternoDaVariavel">
<text>DigiteUmValorInteiro</text>
<hint>Variável que será utilizada.</hint>
</point>

<script language=" Delphi" onenter="false" onleave="true">
DeclareVariable(NomeInternoVariavel);

</script>

Obs.: os caracteres “ “ (Pipes) são utilizados antes e depois do nome da tag point, são delimitadores.

Até o momento não achei um jeito de especificar o tipo da variável, pois o editor automaticamente assume o tipo que foi passado a ele.

A tag code por sua vez é a responsável para que finalmente sejam escritos no editor todo nosso template, ela possui a propriedade language que funciona exatamente como a da tag script e a propriedade delimiter que serve para que você especifique o delimitador que será utilizado na separação dos nomes das tags point, no nosso caso o caractere “” (Pipe), ficando como abaixo:
<code language=”Delphi” delimiter=””>
<![CDATA[]]>
</code>

Repare na tag em gerada automaticamente pela IDE que esta em azul chamada CDATA preste atenção o código a ser exibido na IDE devera ser colocado entre os caracteres [] ou seu código não será exibido.

Vamos então escrever um template para converter um determinado valor para integer.

Para isso adcione o código dentro do CDATA
NomeInternoVariavel := Convert.ToInt32(teste);

Nosso template completo ficou assim:

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns=" http://schemas.borland.com/Delphi/2005/codetemplates " version="1.0.0">
<template name="TestTemp" invoke="manual">
<description>
Template de teste
</description>
<author>
Diego M. Garcia
</author>
<point name="teste">
<text> TextoAserSubstituido </text>
<hint>Esse é um texto de teste.</hint>
</point>
<point name="NomeInternoDaVariavel">
<text>DigiteUmValorInteiro</text>
<hint>Variável que será utilizada.</hint>
</point>
<script language=" Delphi" onenter="false" onleave="true">
DeclareVariable(NomeInternoVariavel);
</script>
<code language="Delphi" delimiter=””><![CDATA[NomeInternoVariavel := Convert.ToInt32(teste);]]> </code>
</template>
</codetemplate>

Salve e veja seu template na IDE através da tecla Ctrl+J ou caso tenha configurado o invoke como auto digite o nome de seu template e tecle espaço.

Obs.: As vezes o delphi da alguns erros se você estiver editando direto nele e é necessário finalizar o delphi e abri-lo novamente para que suas modificações estejam disponíveis.

Examine os templates do delphi para conhecer outras propriedades disponíveis das tags.

Abraços e espero que tenham gostado,

Diego M. Garcia.

quinta-feira, 16 de fevereiro de 2006

Class Attributes with OCL (Derivation OCL)

Its amazing how ECO let us solve some requests with just a few minutes. Today I have to add an field that calculates an sugested value for the products of my client in its entry form, so the solution was simple, I added an derived attribute in my Product class with the follow OCL:

self.BuyOrderItem.BuyOrder->orderBy(InsertedDate)->last.BuyOrderItem->Select(ee.Product = self).Value + (self.BuyOrderItem.BuyOrder->orderBy(InsertedDate)->last.BuyOrderItem->Select(ee.Product = self).Value / 100.safeCast(Decimal) * self.Profit)

Model Description: The model has a class called Product that has an attribute called Profit and has an relationship with class BuyOrderItem that has the product payed value and has an relationship with the class BuyOrder that has an attribute called InsertedDate.

OCL Explanation:
We have accessed trought the Product class (self) the Buy Orders (BuyOrder) and have order it by its Inserted Date (InsertedDate), after that we get its last BuyOrder and select its BuyOrderItem that has our product (->Select(ee.Product = self) and get its payed value.
Ok now we have calc the sugested value so lets sum that value plus that value div by 100 multiplied by the product profit attribute that we have in our product class. To do that just sum the first value that we have get, the OCL should be like that:

self.BuyOrderItem.BuyOrder->orderBy(InsertedDate)->last.BuyOrderItem->Select(ee.Product = self).Value + (self.BuyOrderItem.BuyOrder->orderBy(InsertedDate)->last.BuyOrderItem->Select(ee.Product = self).Value

Now we divide by 100 and multiply by our Profit value, so it will be like that:
self.BuyOrderItem.BuyOrder->orderBy(InsertedDate)->last.BuyOrderItem->Select(ee.Product = self).Value + (self.BuyOrderItem.BuyOrder->orderBy(InsertedDate)->last.BuyOrderItem->Select(ee.Product = self).Value / 100.safeCastDecimal * self.Profit)

Ps.: 100.safeCast was used becuse ECO still has some bugs when working with decimal types, dont forget to get the decimal suport unit at the borland website.

The objective was to do that the product class has an calculated attribute tha get the las value payed of a product plus the profit value that the client has especified for the product.

so the problem was Solved ;)

Atributos de classe com Ocl (DerivationOcl)

É impressionante a facilidade que o ECO nos permite ter para resolver alguns tipos de requisitos do dia a dia. Hoje tinha que criar um campo que calculasse o valor sugerido do produto na tela de cadastro de produtos de um de meus clientes, a solução foi simples, criei um atributo derivado em minha classe produto com a seguinte OCL:

self.ItemPedidoCompras.PedidoCompra->orderBy(DataInclusao)->last.ItemPedidoCompras->Select(ee.Produto = self).Valor + (self.ItemPedidoCompras.PedidoCompra->orderBy(DataInclusao)->last.ItemPedidoCompras->Select(ee.Produto = self).Valor / 100.safeCast(Decimal) * self.Lucro)


Descrição do Modelo: O modelo possui uma classe Produto que contem um atributo chamado lucro e possui um relacionamento com a classe ItemPedidoCompra que contem o valor que foi pago este produto e possui um relacionamento com a classe PedidoCompra que por sua vez contem o atributo data de inclusão. Ufa !!!

Explicação da OCL:
Acessamos atravez da classe Produto (self) os pedidos de compras (PedidoCompra) e ordenamos por Data de Inclusão (DataInclusao) depois pegamos o ultimo PedidoCompra acessamos seus Itens (ItemPedidoCompras) e selecionamos (->Select(ee.Produto = self)) o Item que contem o valor do Produto,
ok até aqui tudo bem vamos agora adcionar lucro que é um valor em porcentagem. Ou seja teremos que pegar este valor que achamos até agora e dividir por 100 e depois multiplicar pelo nosso atributo lucro da classe Produto. Para isso basta entao somar o mesmo valor que já achamos ficando nossa OCL assim:
self.ItemPedidoCompras.PedidoCompra->orderBy(DataInclusao)->last.ItemPedidoCompras->Select(ee.Produto = self).Valor +
(self.ItemPedidoCompras.PedidoCompra->orderBy(DataInclusao)->last.ItemPedidoCompras->Select(ee.Produto = self).Valor

Agora dividimos por 100 e multiplicamos pelo nosso lucro, ficando assim:

self.ItemPedidoCompras.PedidoCompra->orderBy(DataInclusao)->last.ItemPedidoCompras->Select(ee.Produto = self).Valor + (self.ItemPedidoCompras.PedidoCompra->orderBy(DataInclusao)->last.ItemPedidoCompras->Select(ee.Produto = self).Valor / 100.safeCast(Decimal) * self.Lucro)

Obs.: 100.safeCast(Decimal) foi utilizado pelo fato do ECO ainda conter alguns bugs ao trabalhar com valores Decimais, não se esqueça tambem de pegar no site da borland o suporte aos calculos de decimais.

O Objetivo foi fazer com que a classe produto calculasse o ultimo valor (que foi pago) deste produto mais o lucro que o cliente quer ter em cima deste produto.


Resolvido o problema ;)

quarta-feira, 15 de fevereiro de 2006

Creating AutoIncrement Fields with ECO

To Create auto incremented field with ECO II you have to set its class attribute type to integer and its property PMapper to AutoInc (Write exactle like that or ECO should complain) then change the property SaveAction to DBAssign.

If you are using ECO III just set the type of your class attribute to AutoInc and set its SaveAction to DBAssign.

The SaveAction seted to DBAssign makes ECO reread the attribute after persisted to the DataBase.

The SaveActions are:
None: its a normal attribute.
Freeze: It cannot be modified after saved inside DB.
DBAssign: Reread the attribute after persisted to the Database.

Criando campos AutoIncremento no ECO

Para criar campos auto incrementaveis no eco II você devera setar o tipo do atributo da classe para integer e sua propriedade PMapper para AutoInc (Escreva exatamente desse geito ou o ECO ira reclamar) e mude a propriedade SaveAction para DBAssign.

Se você estiver utilizando ECO III tera apenas que setar o tipo do atributo da classe para AutoInc e a propriedade SaveAction para DBAssign.

A propriedade SaveAction setada para DBAssign faz com que o ECO após persistir o objeto no banco de dados execute uma consulta para pegar aquele valor de volta !

As propriedades do SaveAction são:
None: indica que é um atributo normal.
Freeze: Não pode ser modificada após ser salva a primeira vez no banco.
DBAssign: Faz o ECO ler o campo novamente após salvar no banco para pegar seu novo valor.

É isso ai ;)

Welcome

Welcome to the software development Blog.
I will pass some of my knowledges by this Blog.

Keep eye on ;)

Bem Vindo

Bem vindo ao Blog sobre desenvolvimento de Softwares.
Irei passar alguns de meus conhecimentos atravez deste Blog.

Fique atento ;)