sexta-feira, 27 de maio de 2016

SyntaxHighlighter #3 - Identidade visual


E ai pessoal, esse é o terceiro post sobre SyntaxHighlighter (SHL), e nesse post vamos aprender a alterar a cor da nossa ferramenta, vamos personalizar a identidade visual.

SyntaxHighlighter #3 - Identidade visual

Bom é muito simples! No post anterior eu expliquei cada um dos arquivos necessários para o SHL funcionar corretamente, e um desses arquivos era referente a cor da nossa ferramenta, que por default e no exemplo anterior usamos esse arquivo css aqui: shThemeDefault.css


<!-- configuracao do tema, css usado, default, branco, inicio -->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>

Para o blog DevIsComing eu achei que essa identidade era a adequada e a que mais combinava com o restante do site, mas nos temos vários opções:

NomeArquivo
DefaultshThemeDefault.css
DjangoshThemeDjango.css
EclipseshThemeEclipse.css
EmacsshThemeEmacs.css
Fade To GreyshThemeFadeToGrey.css
MidnightshThemeMidnight.css
RDarkshThemeRDark.css

Clicando em um dos itens na coluna "Nome" será possível ver o resultado da sua ferramenta quando aplicado o css localizado na coluna "Arquivo".

E para facilitar, caso tenha optado por hospedar o SHL no seu servidor, clicando em um dos itens da coluna "Arquivo", você será redirecionado para a CDN onde estão localizados os arquivos .css, dessa forma basta clicar com botão direito na página, selecionar "Salvar como" e com um cliente FTP enviar o arquivo .css para o seu servidor e realizar as alterações no seu fonte. 

<!-- configuracao do tema, css usado, midnight, azul escuro, inicio -->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeMidnight.css' rel='stylesheet' type='text/css'/>

A vantagem de ter nesse momento os arquivos no seu servidor e não estar usando a CDN do SHL, é que caso deseje alterar alguma coisa, basta editar o arquivo css e será possível customizar ainda a identidade da sua ferramenta.

Sobre a identidade visual é isso!
No próximo post eu vou estar explicando sobre o atributo class, os parâmetros que podemos estar passando para nossa ferramenta e algumas configurações no script de inicialização do SHL.

Até a próxima!

quinta-feira, 26 de maio de 2016

Ferramentas #5 - SlimDrivers


Se você já formatou um computador e não tinha o CD com os drivers necessários, sabe o sofrimento que é ficar procurando esses arquivos na internet.
Existem alguns fabricantes que ainda disponibilizam uma lista com os drivers necessáros de cada modelo do seu produto, o que facilita bastante o trabalho. Mas, não todos!

Ferramentas #5 - SlimDrivers


Atualmente existem centenas se softwares que listam o nome dos drive que a sua máquina utiliza, mas poucos são os software decentes que listam os drivers para download.
Drive é a peça física da sua máquina, enquanto que Driver é o software necessário para que seu drive funcione. Para facilitar o entendimento, driver em uma tradução ao pé da letra significa motorista, e é exatamente essa a sua função "digirir", controlar o drive.
Atualmente eu tenho utilizado o SlimDrivers, que é um software muito bom, para localizar e fazer download dos seus drivers não instalados ou de atualizações dos drivers já instalados.
O software tem uma interface bastante simples, o que facilita o trabalho, não possui aquelas propagandas pra todo lado, ou links que direcional pra sites de parceiros, não tem limite de download tanto de tamanho do arquivo quanto quantidade de drivers atualizados, não faz download de arquivo nenhum para a sua máquina, ele localiza o driver necessário e instala e o mais importante é FREE... enfim o melhor software que encontrei para esse fim.

Anteriormente eu usava o DriverMax, no entanto, é necessário cadastro, agora possui limite de atualização de drivers, propaganda... 

Caso precisem pra baixar ou atualizar algum driver da sua máquina, fica a dica de utiliza o SlimDriver.

Até a próxima!

quarta-feira, 25 de maio de 2016

GO GO! Semana intensiva de Games


Mais um evento sobre games e dessa vez é um INTENSIVO DE GAMES.
Serão 07 palestras totalmente online e gratuitas que acontecerá dos dias 30/05 á 07/06 ás 08:00 horas da noite. Se prepara ai pra não perder nenhuma palestra.

GO GO! Semana intensiva de Games

Para participar basta acessar esse link aqui, clicar no botão "Eu quero assistir as palestras" preencher um formulário com seu nome e email e pronto! Só aguardar...

O evento vai ser bastante interessante, os palestrantes vão abordar temas como design, animação, modelagem 2D e 3D, Unity, Unreal entre outros.

Caso sua semana seja corrida ou tenha tenha interesse em um tema mais que em outro poderá acompanhar a agenda que eles preparam com informações do palestrante e o tema abordado. Confira!

GO GO! Semana intensiva de Games


É isso ai pessoal!
Até a próxima..

terça-feira, 24 de maio de 2016

SyntaxHighlighter #2 - Instalação


Pessoal...

No post anterior eu expliquei o que era o SHL - SyntaxHighlighter, você pode conferir aqui. Apresentação feita, agora vamos iniciar a configuração da nossa ferramenta. Mas, para isso precisamos decidir se teremos o nosso código salvo em um servidor próprio ou se usaremos uma CDN para acessar os arquivos necessários para seu funcionamento.


SyntaxHighlighter #2 - Instalação

Caso tenha optado por ter o código em um servidor próprio, acesse o site oficial SyntaxHighlighter, localize no menu o link para download. Atualmente a "current version" é a 3.0.83, mas você pode optar por escolher versões anteriores.
Nesse post vamos trabalhar com a versão atualizada.

Aguarde o download do arquivo finalizar, acesse seu servidor usando FileZilla ou outro cliente FTP que preferir, e faça o upload do SLH compactado para seu servidor, extraia os arquivos e mantenha-os em um diretório que preferir.

A partir de agora, independente da forma escolhida (CDN ou servidor próprio) os passos deverão ser realizados.
Primeiro vamos adicionar em nosso código fonte o caminhos onde nossos arquivos se encontram. Se você acompanha o blog deve ter visto o post onde relato o problema que tivemos ao usar a CDN do Google, e como solução adotamos a CDN do próprio criados da ferramenta SHL.

Exatamente antes da tag "</body>" vamos adicionar esse código aqui:

<!-- inicio configuracao do Syntax Highlighting -->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>

<!-- configuracao do tema, css usado, default, branco, inicio -->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>

<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
 
<!-- adicionando Script para SyntaxHighlighter -->
<script type='text/javascript'>
  SyntaxHighlighter.config.bloggerMode = true;
  SyntaxHighlighter.all();
</script>
 
<!-- configuracao de linguagens usadas, inicio -->
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDelphi.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
<!-- configuracao de linguagens usadas, fim -->
 
<!-- fim configuracao do Syntax Highlighting -->


Caso você tenha optado por salvar os arquivos no seu servidor, será necessário alterar esses caminhos para o local onde você hospedou a ferramenta.

Para facilitar a explicação e entender o que é cada um desses arquivos que adicionamos, fiz marcações no código (que também irei ensinar):
Linha 2 e 7 são arquivos relacionados ao core do SHL, são arquivos necessários para renderizar a ferramenta (css default) e para o funcionamento da ferramenta;
Linha 5 é o arquivo .css onde você da identidade visual para sua ferramenta SHL. Existem algumas identidades prontas e vou mostrar quais são e como configura-las; 
O trecho referente a linha 9 é o script para inicializar a ferramenta;
A partir da linha 15 são arquivos que permitem você utilizar o SHL para formatar código fonte das respectivas linguagens. Caso você tenha um código Java, pretende formata-lo usando o SHL é necessário que esse arquivo "shBrushJava.js' esteja adicionado no seu código.
As configurações necessárias estão prontas, nesse ponto já podemos utilizar o SHL e formatar nossos códigos em posts diversos. Mas para isso a ferramenta precisa de um marcador, e o marcador utilizado é a tag "<pre>".
No entanto essa tag por si só não será suficiente para formatar seu código, sendo necessário adicionar o atributo class="brush: java, xhtml, xml, sql"que é o minimo necessário para que nosso código fique formatado.

Para um exemplo simples, clique em criar um novo post, normalmente o editor esta no modo "Escrever", altere para o modo "HTML" e escreve o trecho de código abaixo:

<pre class="brush: java">
public class Devic {

    public static void main(String[] args) {

        System.out.println("Olá pessoas!");
    }
}
</pre>


O resultado do código acima é este:
public class Devic {

    public static void main(String[] args) {

        System.out.println("Olá pessoas!");
    }
}

Faça o teste no seu blog e veja o resultado.

No próximo post eu vou explicar sobre os atributos que você inserir na ferramenta e como alterar a identidade visual.
É isso, e até a próxima!

Ferramentas #4 - JSONLint


É comum hoje em dia falarmos em JSON como alternativa de uso do XML, e isso está agradando a muitos, se não todos os profissionais da área, pois é mais simples fácil e intuitivo seu uso. Em meio a alta usabilidade e facilidade do JSON, muitas ferramentas foram desenvolvidas com o objetivo de facilitar o desenvolvimento e uso desse subconjunto de linguagem de programação, por exemplo o Jackson.


Em alguns casos, em meio ao desenvolvimento, precisamos verificar se nosso JSON está correto para uso. Após efetuar algumas pesquisas achei este site muito interessante que auxilia de forma rápida e simples a verificação da integridade de nosso JSON.

O site chamado JSONLint, permite que você cole o conteúdo JSON gerado ou recebido e valida se está corretamente formatado. Seu uso é muito simples, basta colar o conteúdo dentro do único campo texto e clique em Validate JSON em poucos segundos você receberá o retorno da validação.

Exemplo



Vou inserir o conteúdo abaixo com uma vírgula faltando:


{
 "carro": [

  {
   "id": 1,
   "Modelo": "Celta",
   "Placa": "RRR1303"
  }

  {
   "id": 2,
   "Modelo": "Palio",
   "Placa": "RRR0903"
  }

 ]
}

 Veja a seguir o retorno do site com relação a este erro:



Espero tenham gostado dessa dica, é um site leve, simples e fácil de usar e que nos ajuda a encontrar um erro que as vezes é coisa boba e que não percebemos.

Até mais!

;)

Integração Advpl x Word #2


Fala galera!

Continuando o post sobre integração Advpl x Word, hoje vamos detalhar sobre a codificação da rotina. Vamos criar um novo programa no Developer Studio e nomeá-lo. Darei o nome de AdvplDoc.prw, mas você pode definir o nome que preferir.

Integração Advpl x Word #2


Primeiramente vamos dar uma olhada no código fonte e posteriormente passaremos ponto a ponto com uma breve explicação.

#include "protheus.ch"
#include "rwmake.ch"                 
#include "tbiconn.ch"
#include "msole.ch"
/**
_________________________________________________________________________________
¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
¦¦+---------------------------------------------------------------------------+¦¦
¦¦¦Programa  ¦ ADVPLDOC  ¦ Autor ¦ Renan Ramos              ¦ Data ¦ 19.05.16 ¦¦¦
¦¦¦----------+----------------------------------------------------------------¦¦¦
¦¦¦Descriçäo ¦ Realiza integração do Protheus com documentos Word.            ¦¦¦
¦¦+---------------------------------------------------------------------------+¦¦
¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*/
user function advplDoc  

local hWord 
local cTitulo1  := "Arquivo Word"
local cExtensao := "Modelo Word | *.dot | *.dotx"
local cFileOpen := ""

PREPARE ENVIRONMENT EMPRESA "99" FILIAL "01"
 
cFileOpen := cGetFile(cExtensao, cTitulo1,,,.T.)          
 
hWord := OLE_CreateLink()

OLE_SetProperty(hWord, oleWdVisible,   .T.)
OLE_SetProperty(hWord, oleWdPrintBack, .F.) 

OLE_NewFile(hWord, cFileOpen)

dbSelectArea("SA1")
dbSetOrder(1)                                                                                        
dbGoTop()
                                              
OLE_SetDocumentVar(hWord, "A1_COD"   ,SA1->A1_COD)
OLE_SetDocumentVar(hWord, "A1_NOME"  ,SA1->A1_NOME)
OLE_SetDocumentVar(hWord, "A1_END"   ,SA1->A1_END)
OLE_SetDocumentVar(hWord, "A1_BAIRRO",SA1->A1_BAIRRO)
OLE_SetDocumentVar(hWord, "A1_MUN"  ,SA1->A1_MUN)
OLE_SetDocumentVar(hWord, "A1_EST"   ,SA1->A1_EST) 

OLE_UpdateFields(hWord) 
OLE_saveFile(hWord)                                
OLE_PrintFile(hWord,"ALL",,,1)

cFileSave := subStr(cFileOpen,1,At(".",trim(cFileOpen))-1)
OLE_saveAsField(hWord, cFileSave+".doc")

OLE_closeLink(hWord)

return

Como podem perceber, é um fonte pequeno sem muitas linhas. Um ponto fundamental para conseguir realizar a comunicação é lembrar de incluir a biblioteca msole.ch, pois esta biblioteca permite que você possa utilizar as funções para efetuar a comunicação com o Word.

A biblioteca tbiconn.ch permite que você utilize o comando PREPARE ENVIRONMET EMPRESA, isto é muito útil, pois permite que você faça o teste da rotina sem ter a necessidade de acessar o Protheus e fazer todo o processo desde o login até a execução do programa. Para utilizá-lo, basta adicionar a empresa (no meu caso 99, pois é base teste) e a filial. Seu objetivo é inicializar o ambiente no qual será testada a rotina.

A método OLE_CreateLink() faz a conexão entre o Protheus e o MS-Office. Para verificar se a conexão foi realizada com sucesso, é indicado utilizar uma variável do tipo numérico (handle) para que receba o retorno desta função. Se o retorno da função for 0, a conexão ocorreu com sucesso, mas caso seja -1, houve problema na conexão.

Assim que a conexão estiver estabelecida, utilizaremos o método OLE_NewFile(nHandle, cPath) que possui dois parâmetros:

  • nHandle: é o valor retornado da método OLE_CreateLink();
  • cPath: é o diretório onde se encontra o arquivo que receberá os valores do Protheus.
Na parte seguinte do código, temos a conexão com banco (SA1), onde ordenamos e posicionamos nos registros satisfatórios.

Como em minha base tenho somente um cliente registrado, não foi necessário fazer um filtro e posicionar em um registro específico. Então, após posicionar ou filtrar no registro relacionado ao cliente desejado, vamos setar as variáveis com os valores correspondentes aos campos da tabela.

A método OLE_SetDocumentVar() define o conteúdo que será passado à variável que inserimos no documento no post anterior. Lembre-se que o nome da variável nesta função deve ser a mesma que foi inserida no documento Word, mas não necessariamente na mesma sequência.

Na sequencia temos três importantes métodos que são descritos a seguir:
  • OLE_UpdateFields: atualiza todas as variáveis do documento word criado;
  • OLE_saveFile: salva o documento atualizado;
  • OLE_PrintFile: executa a impressão do arquivo word. O parâmetro definido como "ALL" define que seja impresso todo documento.
Ao final do fonte, é chamado o método OLE_CloseLink() que é responsável por encerrar a conexão entre Protheus e Word.

Bom galera, espero que este post ajude vocês a desenvolverem uma rotina que facilite a vida do usuário. Acessem nosso GitHub, todos os códigos - inclusive o desse post - estão disponíveis para consultas e uso.

Até mais!

;)

segunda-feira, 23 de maio de 2016

Diferença entre String, StringBuilder e StringBuffer em Java #3


Dando continuidade na sequência de posts sobre "Diferença entre String, StringBuilder e StringBuffer", hoje vamos comparar a velocidade de processamento entre StringBuilder e StringBuffer. Sugiro dar uma olhada nos post anteriores, caso ainda não tenha visto, clicando aqui.

Diferença entre String, StringBuilder e StringBuffer em Java #3

StringBuilder e StringBuffer são muito rápidos para concatenação de Strings comum e exercem a mesma função, com a principal diferença que, enquanto o StringBuffer é sincronizado, o StringBuilder não!
Imagine várias threads lendo ou alterando a mesma String, e você precisa manter a consistência do do seu código, para esses casos o ideal é utilizar StringBuffer.

No teste a seguir você vai perceber que StringBuilder é mais rápido do que o StringBuffer. Veja o código abaixo:
  • Comparando performance de StringBuilder e StringBuffer
public class ConcatenaString {

    public static void main(String[] args) { 
              
        // Trecho de código para StringBuffer
        StringBuffer strBuffer = new StringBuffer();
        long tStart = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            strBuffer.append("f");
        }

        long tEnd = System.currentTimeMillis();
        long tResult = tEnd - tStart;
        System.out.println("Tempo de execução com StringBuffer = " + tResult + " ms"); 
        
        // Trecho de código para StringBuilder
        StringBuilder strBuilder = new StringBuilder();
        tStart = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            strBuilder.append("f");
        }

        tEnd = System.currentTimeMillis();
        tResult = tEnd - tStart;
        System.out.println("Tempo de execução com StringBuilder = " + tResult + " ms");
    }
}

Tempo de execução com StringBuffer = 5 ms
Tempo de execução com StringBuilder = 3 ms

Muito bem, vimos os problemas em usar String para concatenar utilizando o operador "+", as possíveis soluções para evitar problemas de processamento, vimos a principal diferença entre StringBuilder e StringBuffer, mas e aí? Quando eu devo utilizar o operador "+" para concatenar Strings? Existem situações em que o operador "+" é utilizado, e são aqueles onde queremos manter a qualidade do código em relação a identação, para facilitar a legibilidade do código, sem a necessidade de criar um novo objeto, que também é conhecido como "mult-line Strings".
Veja o código:

public class ConcatenaString {

    public static void main(String[] args) {

        /**
         * Apenas melhorando a legibilidade, sem criar novos objetos
        */
        String strFinal = "Pessoal "
                            + "seja bem vindo "
                            + "ao blog "
                            + "DevIsComing!";

        /**
         * Outro exemplo de uso sem compromoter o desempenho
        */
        int a = 5;
        int b = 15;
        System.out.println("a é igual=" + a + " e b é igual=" + b + " certo!?");
    }
}


Pessoal acabamos por aqui.
Até a próxima!

Integração Advpl x Word #1


Fala galera!

Há um tempinho fiz um post sobre integração Advpl com o Excel (parte #1 , parte #2) e hoje vou passar para vocês umas dicas sobre integração Advpl e Word. Esta é uma integração muito útil para se aplicar em seu sistema, principalmente em casos onde tem a necessidade de preencher vários documentos.


Integração Advpl x Word #1



NOTA: informo que até a data de publicação deste post, a versão 2016 do Word ainda não foi homologada pela Totvs. Portanto, alguns casos de integração funcionam com esta versão (meu caso :D), mas para versões anteriores tudo funciona normalmente. A codificação é independente da versão.

Documento Word

Antes de iniciarmos com a programação, precisamos configurar o nosso arquivo word para receber os dados do Protheus. 

Vamos acessar o Word e criar um novo documento:

Integracao_Advpl_Word


Após o documento criado, vamos inserir as variáveis que receberão os valores enviado pelo Protheus.
Acesse a opção Inserir -> Partes Rápidas -> Campos:


Integracao_Advpl_Word

Vá até a opção DocVariable e no campo Novo Nome: insira o nome da variável que você utilizará no fonte da sua rotina. Neste caso, estou utilizando o nome dos campos da tabela.


Se você clicar com o botão direito no local que o cursor está posicionado, poderá visualizar a formatação onde está a variável.

Após estes passos seguidos, salve o arquivo em um diretório de sua preferência utilizando a extensão .dot ou .dotx.
No próximo post passaremos para a parte da codificação, onde será explicado detalhadamente cada parte do código.

Até mais!

;)

domingo, 22 de maio de 2016

[VAZOU] Download - Game Of Thrones SO06E05


Pessoal não é o foco desse blog, postar links para download de episódios, mas como um fã de GOT, não posso deixar de compartilhar esse episódio que vazou na internet.

[VAZOU] Download - Game Of Thrones SO06E05


Segue o link para fazer download do arquivo torrent:


E para facilitar a sua vida e conseguir a legenda, veja esse post onde explico a melhor forma de conseguir legenda para seus filmes e séries!

Eu ainda não assisti, fiz o download e parei aqui para compartilhar com vocês, mas dei uns cliques no episódio e realmente é um episódio original.

E por favor após assistir nada de spoilers hahahaha ou não [666]

Até a próxima!

quinta-feira, 19 de maio de 2016

Ferramentas #3 - CamScanner


Pessoal, conheci um aplicativo hoje e não pude deixar de compartilhar com vocês.
Foi uma amiga aqui da empresa que me mostrou!

Imagine você precisando digitalizar arquivos, e não possui um scanner! Ou seu scanner está estragado! que é o meu caso, mentira eu nem tenho um scanner rs
Você precisa ir até uma papelaria e toda aquela trabalheira.


Ferramentas #2 - CamScanner


Existe um aplicativo que se chama "CamScanner", que é muito eficiente e possui versão FREE!
Basta você posicionar o documento que será digitalizado sobre uma superfície e tirar uma foto usando o aplicativo, mas não se preocupe o que está do lado, no fundo... O aplicativo resolve isso pra você, e exatamente ai que ele é diferente de uma simples foto com seu celular, como poderiam estar pensando.

Após tirar a foto, o aplicativo identifica qual o foco principal e cria uma caixa de redimensionamento ao redor do arquivo, onde é possível fazer os ajustes necessários. Dessa forma tudo em volta do seu documento é removido!

Além de digitalizar o documento, é possível fazer ajustes de iluminação na imagem, clarear, preto e branco, escala de cinza. Feito isso você escolhe se possui mais documentos para ser digitalizado, criando assim uma página pra cada documento em um arquivo só, ou vários documentos em vários arquivos separados.

E finalmente enviar por email, compartilhar no google drive, whatsapp!

Espero que o aplicativo possa te ajudar, tanto quanto tem sido útil pra mim.
Pra baixar direto no Google Play, segue o link.

Até a próxima!

quarta-feira, 18 de maio de 2016

SyntaxHighlighter #1 - Sobre


SyntaxHighlighter é uma ferramenta que permite formatar texto para uma sintaxe definida de modo a facilitar a leitura e organização do texto. Muito usada por blogs de tecnologia, onde se faz necessário escrever trechos de códigos em diferente linguagens de programação e fazer marcações para facilitar a explicação do trecho de código.


SyntaxHighlight #1 - Sobre


Em resumo é esse carinha aqui:
public class Fibonacci {
 
    static long fibo(int n) {
        if (n < 2) {
            return n;
        } else {
            return fibo(n - 1) + fibo(n - 2);
        }
    }
 
    public static void main(String[] args) {   
 
    // Imprime os 20 primeiros termos       
    for (int i = 0; i < 20; i++) {
            System.out.print("(" + i + "):" + Fibonacci.fibo(i) + "\t");
        }
    }
}


As ferramentas mais conhecidas para este fim são:


E aqui no blog nos utilizamos o SyntaxHighlighter (vamos chamar se SHL), sem nenhum motivo em particular, tínhamos que escolher um e o SyntaxHighlighter possui maior quantidade de usuários o que facilita resolver problemas que venham a acontecer.

Mas essa ferramenta não é nativa do blogspot é necessário uma configuração.
Precisamos adicionar aquivos .css e .js para que o SHL funcione, além de adicionar uma marcação no texto para ser interpretado e formatado para a linguagem escolhida.

Para obter o resultado apresentando no inicio do post precisamos adicionar a marcação no corpo do nosso texto:
// o código que será formatado aqui
Nos próximos post eu vou ensinar onde conseguir os arquivos necessários para a configuração, como integra-lo ao seu blog, as linguagens que o SHL trabalha e alguns macetes rs

Até a próxima!

O que é uma CDN?


CDN (Content Delivery Network) é uma rede de distribuição de informação que permite fornecer conteúdo Web de uma forma mais rápida a um grande número de utilizadores, distribuindo o conteúdo por múltiplos servidores.

Essa explicação é simples e objetiva e também fácil de encontrar em qualquer canto da internet.
Mas eu gostaria de explicar minuciosamente o que é na verdade a CDN, e como ela "controla a internet que você usa".

O que é uma CDN?


Imagine por exemplo que a empresa DEVIC (Developer is Coming rs) libera uma atualização para um software e o servidor onde essa atualização está hospedada encontra-se na América. Até aqui tudo normal.
Agora imagine que para esse sistema temos vários usuários pelo mundo todo, e que a Europa é o principal usuário desse software, também precisa fazer o download dessa atualização. Dessa forma torna-se muito mais cômodo utilizar uma rede de distribuição de conteúdo com servidores localizados em vários pontos do mundo para permitir que os usuários Europeus tenham um acesso mais rápido a atualização.

Outro cenário: sua empresa cresceu muito, você exporta para a China, porém seu site em mandarim leva 40 segundos para ser exibido em Pequim. Você atende do sul ao norte mas a qualidade só é aceitável no sudeste. Sua empresa exporta para a Ásia, mas seu site só pode ser visto nas Américas.

E por último: quantos usuários eu espero para datas comemorativas, como dia das Mães e o Natal? Onde segundo pesquisas são os melhores períodos de venda.
Como prever a demanda?
Para suportar essa demanda eventual a infraestrutura do seu serviço precisa estar muito bem balanceada, mas o que devo considerar a mediana de acessos? a maior demanda?

Todo esse drama chega ao fim. Tudo está resolvido, e o aplicativo é um sucesso.
A proposta da rede distribuída de CDN é resolver todas os pontos citados de maneira, simples e elegante, sem que tenhamos alem dos problemas de desenvolvimento e infraestrutura que nos preocupar com o que não está no nosso controle: a internet.

Para o exemplo da atualização com clientes espalhados pelo mundo, teríamos o mesmo arquivo de atualização espalhados por vários servidores de forma que casa usuário possa acessar a atualização nos servidores mais próximos, onde um usuário Francês tenha o conteúdo ofertado por servidores na França, o usuário brasileiro recebe seu conteúdo também regionalizado. Isso significa:
  • ausência de infraestrutura própria para disponibilizar o conteúdo;
  • menor latência e maior banda para download.
Uma das primeiras e mais básicas funcionalidades da CDN é cachear o conteúdo para o usuário final, o mais próximo possível dele.



E para as datas comemorativas, como a CDN pode nos auxiliar?
O servidores onde estão hospedados os serviços, ficam responsáveis por subir máquinas ou desligar máquina, dessa forma você nunca terá máquinas ociosas, gastando uma fortunas para mante-las no ar, quando na verdade não está sendo necessário.
Ou seja, quando seu serviço tiver uma demanda baixa, poucas máquinas estarão ligadas disponibilizando serviço, quando a demanda aumenta, as máquinas passam a funcionar para suportar a quantidade de acessos.

Hoje a maior CDN do mundo é a Akamai e possui mais de 130mil servidores, reunindo vários nomes fortes do mundo da tecnologia em sua lista de clientes. Essa mesma rede suporta em dias normais 6Tb/seg de tráfego. Aproximadamente 30% de toda a internet mundial.

Até a próxima!

terça-feira, 17 de maio de 2016

Debug #8 - Android: teclado sobre o EditText



Fala galera!

Não sei se já comentei aqui no site, mas estou estudando desenvolvimento de aplicativos Android e confesso a vocês, é uma área sensacional. Vale muito se envolver com essa área de desenvolvimento.

Bom, e como todo iniciante (noob ainda rsrsrs) me deparei com um probleminha que custei para descobrir qual a possível solução, pelo menos a que atendeu ao que esperava.


Gostaria de já deixar claro que é aconselhável utilizar o Android Studio, pois é uma IDE completa para este fim e o Google não dá mais suporte para o Android Eclipse Tools (veja aqui).

A ideia é a seguinte, utilizo o Eclipse Mars para desenvolvimento de aplicativos e tenho uma activity chamada activity_main.xml, é uma tela simples com dois campos de texto (EditText) e um label (TextView) para cada (código abaixo).

<LinearLayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" android:scrollbarstyle="insideInset" xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView android:layout_gravity="center" android:layout_height="wrap_content" android:layout_margin="20dp" android:layout_width="wrap_content" android:text="@string/lbl_nova_tarefa">
                  
        <TextView android:id="@+id/lblTitulo" android:layout_ name="code"height="wrap_content" android:layout_margin="10dp" android:layout_width="match_parent" android:text="@string/lbl_titulo">

        <EditText android:id="@+id/edtTitulo" android:inputtype="text" android:layout_height="wrap_content" android:layout_margin="10dp" android:layout_width="match_parent" android:typeface="serif">
        
        <TextView android:id="@+id/lblDesc" android:layout_height="wrap_content" android:layout_margin="10dp" android:layout_width="match_parent" android:text="@string/lbl_descricao">
     
        <EditText android:id="@+id/edtDesc" android:inputType="textMultiLine" android:layout_height="wrap_content" android:layout_margin="10dp" android:layout_width="match_parent" android:scrollbars="vertical">         
</EditText></TextView></EditText></TextView></TextView></LinearLayout>


Pois bem, quando acessava o segundo EditText (@id/edtDesc), o teclado do android ficava sobre o campo, com isso, não era possível visualizar o que era digitado.

Ao acessar o developer.android.com, encontrei o atributo android:windowSoftInputMode. Este atributo, conforme descrito no site, afeta duas coisas:

  • O estado do teclado virtual - se ele está escondido ou visível - quando a atividade torna-se o foco da atenção do usuário.
  • O ajuste feito para a janela principal da atividade - se é redimensionada menores para dar espaço para o teclado virtual ou se o seu conteúdo deslocar para fazer o foco atual visível quando parte da janela é coberto pelo teclado virtual.
Então, para que pudesse solucionar meu problema, utilizei o valor "adjustPan", onde é responsável por redimensionar a janela da activity principal, deslocando o teclado para que o foco atual não seja escondida pelo usuário.
Dessa forma, basta somente adicionar o seguinte código ao seu arquivo AndroidManifest.xml:

android:windowSoftInputMode="adjustPan"

Bom galera, espero que tenham curtido essa dica. Ressalto que o plugin do android para Eclipse não está mais recebendo suporte, pois o Google agora possui uma IDE voltada somente para desenvolvimento Android, o Android Studio. Vale a pena dar uma olhada nessa IDE, possui muitas ferramentas que auxiliam no desenvolvimento do seu aplicativo.
Falarei disso em um próximo post.

Até mais!

;) 

Problemas com SyntaxHighlighter ao usar CDN do Google


Pessoal hoje tivemos um problema com nosso blog em relação ao uso do SyntaxHighlighterEssa ferramenta facilita a escrita em linguagens estruturadas como linguagens de programação ou linguagens de marcação (que é o caso do nosso blog), já que as estruturas e os erros de sintaxe são facilmente distinguidos.

O problema é que estávamos usando a CDN (Conten Delivery Network) do Google que era o link: http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shCore.js e vários outros links necessários para para que o SyntaxHighighliter funcionasse.


Problemas com SyntaxHighlighter ao usar CDN do Google


No entanto ao tentar acessar o link, você não tem mais a página (pode ser que já tenha voltado rs), mas até o momento a página se encontra fora do ar.

A solução foi alterar de CDN, onde antes apontávamos para a Google, agora estamos apontando para o próprio site da ferramenta:
"http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js"

Para fazer as alterações, usando blogspot, vá até o menu Modelo e clique em Editar HTML. Localize onde estão os scripts responsáveis pelo controle da ferramenta, para facilitar pesquise por "syntaxhighlighter" ou "
" e altere todos os caminhos, deixando da seguinte forma:
// Inicio configuracao do Syntax Highlighting
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
// configuracao do tema, css usado, default, branco, inicio
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
// configuracao do tema, css usado, default, branco, fim
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
 
// adicionando Script para SyntaxHighlighter
<script type='text/javascript'>
  SyntaxHighlighter.config.bloggerMode = true;
  SyntaxHighlighter.all();
</script>

// Configuracao de linguagens usadas, inicio
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDelphi.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'/>
// Configuracao de linguagens usadas, fim
 
// fim configuracao do Syntax Highlightinghttp://www.deviscoming.com/2016/05/problemas-com-syntaxhighlighter-ao-usar.html

segunda-feira, 16 de maio de 2016

Debug #7 - Tabelas sem permissão de acesso (Oracle)


Em uma aplicação onde uso o banco de dados Oracle, tive um problema ao tentar realizar um select na tabela e o erro retornado era "table or view does not exist".

Primeiro passo, abri meu gerenciador de banco de dados, a tabela estava lá, então ela existia. Mas além da possibilidade da tabela não existir (que é o que a mensagem descreve), esse erro acontece também quando o seu usuário não tem as permissões necessárias para uso da tabela. E esse era o meu problema!


Debug #8 - Tabelas sem permissão de acesso (Oracle)


Como era um select simples,foi fácil identificar a tabela que "estava com problema". Mas em casos onde possui vários joins, pode ficar dificil identificar qual tabela não possui as permissões necessárias.
Para auxilia-los e verificar quais são as tabelas que o seu usuário não possui permissões use o script abaixo:

WITH PRIVILEGIO AS (
        SELECT * FROM SYS.DBA_TAB_PRIVS P
         WHERE (P.OWNER = 'USUARIO_01')
           AND (P.GRANTEE = 'USUARIO_02')
           AND P.PRIVILEGE = 'SELECT'
  ), OBJETO AS (
        SELECT O.OBJECT_NAME NOME FROM DBA_OBJECTS O
         WHERE (O.OWNER = 'USUARIO_01')
           AND O.OBJECT_TYPE IN ('TABLE', 'VIEW', 'SEQUENCE', 'SYNONYM')
  )
SELECT *
  FROM OBJETO O
  LEFT OUTER JOIN  PRIVILEGIO P ON O.NOME = P.TABLE_NAME
 WHERE P.PRIVILEGE IS NULL;


Os valores "P.OWNER" e "P.GRANTEE" são os nomes do seu usuário, na minha aplicação eu tenho um usuário se banco de dados "usuario_01" e um usuário da aplicação "usuario_02".

O valor "P.PRIVILEGE", são os tipos de privilégios que você pretende verificar se foram liberadas. E o valor de "O.OBJECT_TYPE" é onde você quer verificar se as permissões foram liberadas.

Todos os lugares onde seu usuário não tiver permissão será listado, considerando o seu escopo de busca em OBJECT_TYPE.
Legal, mas e para liberar permissão?

Você usa esse script aqui:

GRANT SELECT ON NOME_DA_TABELA TO NOME_DO_USUARIO;

Bom, é isso qualquer dúvida deixa seu comentário.
Até a próxima!

quinta-feira, 12 de maio de 2016

GO GO! Hangout PDJ - As 5 únicas etapas para desenvolver seu jogo


E ai pessoal, tudo bom?

Hoje, dia 12/05, vai acontecer outro Hangout com Raphael Dias do PDJ explicando sobre as "5 únicas etapas para desenvolver seu jogo", totalmente grátis e online.


GO GO! Hangout PDJ - As 5 únicas etapas para desenvolver seu jogo


Para participar, basta se cadastrar no link (Quero me cadastrar) e ficar de olho no seu email que Raphael vai te mandar o link onde acontecerá o Hangout.

Ah! E diferente dos outros hangouts, esse não será gravado, por isso se programe para não perder a oportunidade, essa é a sua chance.

Abraço e sucesso!

quarta-feira, 11 de maio de 2016

Advpl Web Service - Parte 2



Fala galera!

No post anterior (veja aqui) nós configuramos e habilitamos no Protheus um novo web service. Hoje nós iremos fazer uma pequena aplicação, onde será apresentado alguns dados do cliente em nossa consulta.

Criaremos um novo fonte no Developer Studio e vamos nomeá-lo como WSCLIENTE. Então adicionaremos as seguintes bibliotecas:

#include "protheus.ch"
#include "totvswebsrv.ch"
#include "apwebsrv.ch"

*Sem estas bibliotecas não será possível executar o programa. 

Agora iremos criar nosso web service e seu nome será WSBUSCLI. Nosso web service terá os seguintes propriedades e método:

WSSERVICE WSBUSCLI
 WSDATA Codigo as String
 WSDATA DadosCliente as Cliente
 
 WSMETHOD GetCliente DESCRIPTION "Busca cliente por código"
ENDWSSERVICE"

Começamos nossa declaração de classe web service utilizando o WSSERVICE. Dentro dela declaramos os métodos (WSMETHOD) e as propriedades (WSDATA).

  • WSMETHOD: inicia a declaração de um método em uma classe de web service;
  • WSDATA: declara uma propriedade de uma classe Web Service.

Na nossa classe teremos uma propriedade Codigo do tipo String, uma propriedade DadosCliente do tipo Cliente (veremos isso logo abaixo) e um método GetCliente.
Lembre-se de encerrar a declaração da classe com ENDWSSERVICE.

A nossa propriedade DadosCliente é um tipo Soap que declaramos do tipo Cliente. Veja o código abaixo:

WSSTRUCT Cliente
 WSDATA Nome as String     
 WSDATA Endereco as String
 WSDATA Bairro as String
 WSDATA Municipio as String
 WSDATA Estado as String 
ENDWSSTRUCT

Nessa estrutura (WSSTRUCT) chamada Cliente, possui propriedades que serão enviadas após a requisição do cliente. Definimos o retorno como Nome, Endereco, Bairro, Municipio e Estado. Todos estes do tipo String.

Agora vamos falar do nosso método. O método recebe, no nosso caso, o código do cliente e retorna o DadosCliente. Vejam o código:

WSMETHOD GetCliente WSRECEIVE Codigo WSSEND DadosCliente WSSERVICE WSBUSCLI
 
 dbSelectArea("SA1")
 SA1->(dbSetOrder(1))
 SA1->(dbGoTop())    
 while !SA1->(EOF()) .and. allTrim(SA1->A1_COD) = allTrim(Codigo)
  ::DadosCliente:Nome := allTrim(SA1->A1_NOME)
        ::DadosCliente:Endereco := allTrim(SA1->A1_END)
        ::DadosCliente:Bairro := allTrim(SA1->A1_BAIRRO)        
        ::DadosCliente:Municipio := allTrim(SA1->A1_MUN)
        ::DadosCliente:Estado := allTrim(SA1->A1_EST)
        SA1->(dbSkip())
 endDo                
 
Return .T.

O código é auto-explicativo, onde acessamos a tabela SA1, definimos qual índice será realizada a busca, posicionamos no registro que possui o campo SA1->A1_COD igual ao código recebido e adicionamos as informações obtidas em cada propriedade de DadosCliente. Ao final da execução, o web service enviará estes dados ao requisitante.

Agora vamos testar nosso código, mas como faremos isso? Muito simples, para que possamos testar, precisamos gerar o client do nosso web service. Então acesse a url do seu web service e pesquise pelo nome que você definiu a ele, em nosso caso WSBUSCLI.

Listagem de métodos disponíveis


Clique sobre ele e outra página será aberta com mais informações desse web service, inclusive mostrando qual(is) método(s) temos disponíveis para uso. Ao lado desse página na parte superior esquerda temos um link, onde nós copiaremos (botão direito do mouse).

Link do método que será utilizado

Após copiar o link, vá até o Developer Studio e crie um novo arquivo. Com esse novo arquivo aberto, vá até o menu em Ferramentas > Gerar novo cliente WebServices.

Gerando o client do web service

Será solicitado uma url, então você insere a que foi copiado no passo anterior. Após clicar em Ok, um novo código aparecerá. então escolha uma pasta de sua preferência e salve este código. Não há necessidade de alterar ou modificá-lo.

Assim que compilar o sistema, podemos testar nosso web service.
Acesse o link do web service, pesquise por WSBUSCLI e clique sobre o método que criamos (GETCLIENTE). Abrirá uma nova página onde teremos o formato de requisição e resposta do SOAP.

Tela de visualização de requisição e resposta SOAP

Clique em testar, então outra página será apresentada, nela existirá um campo solicitando o código do cliente. Este código será enviado ao web service que retornará os dados do cliente pesquisado.

Página de teste


Abaixo temos a resposta do nosso web service:

Resposta da requisição ao método

Bom galera, acho que é só isso rsrs
O post ficou um pouco extenso, mas acredito que ajudará muito quem precisará testar alguns web services em seu ambiente de teste ou até para quem precisa utilizar esta facilidade em ambiente de produção.

Acesse nosso GitHub e visualize esse e outros fontes.

Até mais!

:)