Development/Tutorials/Plasma4/DataEngines (pt BR)

Jump to: navigation, search


Development/Tutorials/Plasma/DataEngines


Escrevendo uma Data Engine
Tutorial Series   Plasma Tutorial
Previous   C++, Qt, KDE4 development environment
What's Next  
Further Reading   DataEngine API, CMake Tutorials, Writing a Plasmoid (Tutorial)

Abstract

Data Engines fornecem uma interface padronizada para a visualização em diferentes data sources.

Este tutorial irá guiá-lo através da criação de um data engine simples. O exemplo que usaremos é uma versão simplificada do time data engine que vem com a instalação básica do plasma no kdebase-workspace.

O time data engine fornece a data atual e a hora para qualquer fuso horário que o sistema conheça. Ele é usado por todos os relógio plasmoids. O benefício óbvio é que não há necessidade para reimplementar a lógica para selecionar o fuso horário em casa relógio em plasmoid.

O Plasma Engine Explorer

Uma ferramenta muito útil para quem quer escrever um data engine é o Plasma Engine Explorer. Você pode usá-lo para ver como o data engine deveria funcionar em tempo de execução.

plasmaengineexplorer
</code>
 
Perto do topo da janela há um combobox para selecionar um data engine.
Escolha o "time" engine. Agora você pode solicitar uma fonte. Experimente
pedir a fonte "Local", com um intervalo de atualização de 500ms (duas vezes por
segundo). Um único item, Local, devem ficar visíveis na lista de fontes. Clique no + do lado esquerdo para expandi-lo, e você deve ver a data, a hora, o fuso horário do continente e o fuso horário da cidade listada, junto com o tipo
de cada um.
 
[[Image:Plasma-engine-explorer-time.png]]
 
Selecione outros fusos horários, como "Europe / Paris" e
"Ásia / Tóquio".
 
Depois de criar o seu data engine, lembre-se de testar usando o Plasma Engine Explorer!
 
 
==O Código==
 
===O Arquivo Desktop===
 
 
Cada data engine en precisa de um arquivo de descrição para dizer ao plasma como
carregá-lo e o que é chamado.
 
 
'''plasma-engine-testtime.desktop'''
<syntaxhighlight lang="ini">
[Desktop Entry]
Name=Test Time Engine
Comment=A duplicate of the Time Engine
Type=Service
 
X-KDE-ServiceTypes=Plasma/DataEngine
X-KDE-Library=plasma_engine_testtime
X-Plasma-EngineName=testtime
X-KDE-PluginInfo-Author=Aaron Seigo
X-KDE-PluginInfo-Email=aseigo@kde.org
X-KDE-PluginInfo-Name=testtime
X-KDE-PluginInfo-Version=0.1
X-KDE-PluginInfo-Website=http://plasma.kde.org/
X-KDE-PluginInfo-Category=Examples
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=LGPL
X-KDE-PluginInfo-EnabledByDefault=true
</code>
 
As partes mais importantes são:
* os campos Name, Comment e Type, são exigidos para todos os arquivos 
.desktop.
* o campo X-KDE-ServiceTypes, que diz ao plasma que este é um data engine.
* o campo X-KDE-Library, que diz ao plasma como carregar o data engine - neste caso carregar plasma_engine_testtime.so do plugin folder.
* o campo X-Plasma-EngineName, que diz ao plasma o qual é o nome do plugin exportado (setado pelo K_EXPORT_PLASMA_DATAENGINE).
* o X-KDE-PluginInfo-Name é importante para DataEngines desde o 4.2, sem isso, o plasma não vai encontrar a sua DataEngine.
 
===O arquivo Header===
 
'''testtimeengine.h'''
<syntaxhighlight lang="cpp-qt">
// the following header is required by the LGPL because
// we are using the actual time engine code
/*
 *   Copyright 2007 Aaron Seigo <aseigo@kde.org>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library General Public License as
 *   published by the Free Software Foundation; either version 2 or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
//um padrão de include para impedir problemas se o
// cabeçalho for incluído várias vezes
#ifndef TESTTIMEENGINE_H
#define TESTTIMEENGINE_H
 
// Precisamos do cabeçalho DataEngine, já que TestTimeEngine herda dele
#include <Plasma/DataEngine>
 
/**
 * Fornece a data e hora atual para um determinado
 * Fuso horário.
 *
 * "Local" é uma fonte especial que é um alias para o atual
 * Fuso horário.
 */
class TestTimeEngine : public Plasma::DataEngine
{
    // required since Plasma::DataEngine inherits QObject
    Q_OBJECT
 
    public:
        // cada engine precisa de um construtor com esses parâmetros
        TestTimeEngine(QObject* parent, const QVariantList& args);
 
    protected:
        // esta função virtual é chamada quando quando um novo source é requisitado
        bool sourceRequestEvent(const QString& name);
 
        // esta função virtual é chamada quando uma atualização automática
        // é disparada por um source existente (ex: quando um intervalo de //atualização é iniciado quando faz requisição a um source)
        bool updateSourceEvent(const QString& source);
};
 
#endif // TESTTIMEENGINE_H
</code>
 
Um arquivo header pode parecer um pouco inútil para um plugin
deste tamanho, mas é um bom ter esse hábito.
 
Note que eu não coloco uma K_EXPORT_PLASMA_DATAENGINE no header.
Quando houver apenas um arquivo .cpp no projeto, não há problema, mas plugins
maiores diversos arquivos podem incluir esse header e só pode haver um
K_EXPORT_PLASMA_DATAENGINE no projeto. Se K_EXPORT_PLASMA_DATAENGINE é compilado várias vezes, você obterá um erro de linker quando compilar.
Observe também que o nome deveria '''não''' deveria terminar em "engine" (por exemplo, "testtimeengine"), porque o Plasma não consegue encontrar o DataEngine correto.
 
===Main Code===
 
'''testtimeengine.cpp'''
<syntaxhighlight lang="cpp-qt">
// the following header is required by the LGPL because
// we are using the actual time engine code
/*
 *   Copyright 2007 Aaron Seigo <aseigo@kde.org>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library General Public License as
 *   published by the Free Software Foundation; either version 2 or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
#include "testtimeengine.h"
 
#include <QDate>
#include <QTime>
 
#include <KSystemTimeZones>
#include <KDateTime>
 
#include <Plasma/DataContainer>
 
TestTimeEngine::TestTimeEngine(QObject* parent, const QVariantList& args)
    : Plasma::DataEngine(parent, args)
{
    // Ignoramos alguns argumentos - data engines não tem muito uso para eles
    Q_UNUSED(args)
 
    // Isso impede que applets usem um alto intervalo de atualização //desnecessariamente de um desnecessariamente e usando muita CPU.
    // No caso de um relógio que só tem precisão em segundos,
    // Um terço de um segundo deve ser mais do que suficiente.
    setMinimumPollingInterval(333);
}
 
bool TestTimeEngine::sourceRequestEvent(const QString &name)
{
    // Nós não temos nenhum código especial para executar a
    // Primeira vez que uum source seja solicitado, por isso, basta chamar
    // updateSourceEvent().
    return updateSourceEvent(name);
}
 
bool TestTimeEngine::updateSourceEvent(const QString &name)
{
    QString timezone;
 
    if (name == I18N_NOOP("Local")) {
        // Local é um caso especial - é só pegar a hora e data atual 
        setData(name, I18N_NOOP("Time"), QTime::currentTime());
        setData(name, I18N_NOOP("Date"), QDate::currentDate());
    } else {
        // Primeiro verifica se o fuso horario é válido
        KTimeZone newTz = KSystemTimeZones::zone(name);
        if (!newTz.isValid()) {
            return false;
        }
 
        // Pegando a data e hora
        KDateTime dt = KDateTime::currentDateTime(newTz);
        setData(name, I18N_NOOP("Time"), dt.time());
        setData(name, I18N_NOOP("Date"), dt.date());
    }
    return true;
}
 
// Isso faz a mágica que permite o Plasma carregar
// este plugin. O primeiro argumento deve corresponder 
// ao X-Plasma-EngineName in the .desktop file.
K_EXPORT_PLASMA_DATAENGINE(testtime, TestTimeEngine)
 
// Isto é necessário uma vez que é um TestTimeEngine QObject
#include "testtimeengine.moc"
</code>
 
 
====Responding to Requests for Sources====
 
O <tt>sourceRequestEvent()</tt> método é chamado pela primeira vez quando um source é carregado. Você pode usar isso para fazer qualquer processamento especial que deve ser feito pela primeira vez uma fonte é criada, mas não quando ele é atualizado posteriormente.
 
Se um source é criado com um intervalo de pesquisa, <tt>updateSourceEvent()</tt> será chamado a cada intervalo de tempo em que expira. Por exemplo, se um applet solicita o source "foo", com um intervalo de pesquisa de 500ms, <tt>sourceRequestEvent("foo")</tt> serão chamados, inicialmente, em seguida, meio segundo mais tarde, e a cada meio segundo depois que <tt>updateSourceEvent("foo") </ tt> for chamado.
 
Note, no entanto, que os applets não têm que definir um intervalo de pesquisa e
podem simplesmente esperar por uma engine para passar os dados para ele.
 
====Controlando a frequência de atualização====
 
Há alguns métodos para controlar as atualizações. Usamos <tt>setMinimumPollingInterval(333)</tt> para evitar <tt>updateSourceEvent()</tt>
a ser chamado mais de três vezes por segundo por qualquer source.
Você também pode aplicar um intervalo de atualização específica para todos os
sources fornecidos por esta engine com <tt>setPollingInterval()</tt>, que leva
um tempo em milissegundos como seu único argumento.
 
====Respondendo a eventos externos====
 
Pesquisa não faz sentido para todos as engines. Alguns mecanismos, como uma engine do dispositivo, responder a eventos externos. Você pode usar <tt>setData()</tt> a qualquer momento para criar ou atualizar um source. 
<tt>removeData()</ tt> e <tt>removeSource()</tt> também são métodos úteis. Para os applets que quiser ser informado quando o source muda, sem usar pesquisa,
use <tt>dataUpdated</tt>. Use-o chamando <tt>connectSource</tt>.
 
 
====Listando potenciais sources====
 
Applets podem solicitar uma lista das fontes disponíveis para uma engine. Por padrão, esta é apenas uma lista de todos os sources que foram criados (com <tt> setData()</ tt> ou <tt>addSource()</ tt>) até agora (e não retirados, é claro). No entanto, você pode querer procurar sources, mas na verdade não criá-los. Por
exemplo, podemos procurar para cada fuso horário que o sistema conhece, mas não
realmente criar e preencher os sources, já que dificilmente será usado realmente.
 
Isso pode ser feito reimplementando <tt>virtual QStringList sources() const</tt> e devolvendo uma lista dos nomes de todas as fontes disponíveis.
 
====Inicialização====
 
Se você quiser executar qualquer inicialização além de propriedades
simples, como popular sources, você não pode fazê-lo no construtor, já
que a data engine não foi devidamente inicializado neste momento. Em vez
disso, reimplemente método <tt>virtual void init()</tt>.
 
Por exemplo, o tasks data engine utiliza método <tt>init()</tt>
para obter uma lista de todas as tarefas em execução e cria sources para cada uma delas.
 
 
====Mais controle sobre os dados====
 
O <tt>DataContainer</tt> da classe pode ser usado para dar mais controle
sobre a atualização de dados se você precisar dele. Os métodos de <tt>DataEngine</tt> são <tt>DataContainer* containerForSource(const QString& source)</tt>, <tt>void addSource(DataContainer* source)</tt> e <tt>SourceDict containerDict() const</tt>.
 
===Building===
 
O arquivo CMakeLists.txt diz ao CMake como construir o seu plugin. O arquivo seguinte vai trabalhar para este projeto:
 
<syntaxhighlight lang="bash">
# Um nome para o projeto
project(plasma-testtime)
 
# Encontre as Libraries requisitadas
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
 
add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories(
   ${CMAKE_SOURCE_DIR}
   ${CMAKE_BINARY_DIR}
   ${KDE4_INCLUDES}
   )
 
# Adicionamos nossos fontes aqui
set(testtime_engine_SRCS testtimeengine.cpp)
 
# Agora certifique-se de todos os arquivos estão no lugar certo
kde4_add_plugin(plasma_engine_testtime ${testtime_engine_SRCS})
target_link_libraries(plasma_engine_testtime
                      ${KDE4_KDECORE_LIBS}
                      ${KDE4_PLASMA_LIBS})
 
install(TARGETS plasma_engine_testtime
        DESTINATION ${PLUGIN_INSTALL_DIR})
 
install(FILES plasma-engine-testtime.desktop
        DESTINATION ${SERVICES_INSTALL_DIR})
</code>
 
 
==Testando==
 
Execute:
<syntaxhighlight lang="bash">
cmake -DCMAKE_BUILD_TYPE=debugfull -DCMAKE_INSTALL_PREFIX=$KDEDIR
make
make install
</code>
 
Substitua <tt>$KDEDIR</tt> com o diretório de instalação do KDE se <tt>$KDEDIR </tt> não está definido.
 
Alternativamente, você pode executar o seguinte:
<syntaxhighlight lang="bash">
cmake -DCMAKE_BUILD_TYPE=debugfull
make
cp ./lib/plasma_engine_testtime.so $KDEDIR/lib/kde4
cp ./plasma-engine-testtime.desktop $KDEDIR/share/kde4/services/
</code>
 
Agora execute <tt>kbuildsycoca4</tt>  para contar para as aplicações do KDE (incluindo o plasma e o plasma engine explorer) sobre o novo arquivo .desktop.
 
Agora você pode testá-lo, como fizemos com o time engine. Execute:
<syntaxhighlight lang="bash">
plasmaengineexplorer --engine testtime
</code>
 
Note que se você alterar uma data engine (ou applet), a mudança não irá
registrar em todos os aplicativos em execução. Após a modificação e reinstalação
de uma data engine, para fazer plasma registrar a mudança que você deve
executar:
 
<syntaxhighlight lang="bash">
kbuildsycoca4
kquitapp plasma-desktop (or plasma-netbook, etc)
plasma-desktop
</code>

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal