
KDE4 Plasma Desktop. DIY plasmoid

In order to implement everything that is described below, the system must contain, in fact, KDE4, as well as the following installed packages: kdesdk, kdebase-devel, kdelibs-devel, cmake. Depending on the distribution, packages may have slightly different names (I give the names for Fedora Core), but the general meaning, I think, is clear.
To begin with, plasmoids are binary and scripted. Without much hesitation, I decided to use the “pluses” that are close to my heart and create, accordingly, a binary widget, which is a .so (shared object) module, that is, a dynamically loaded library. An elementary framework should look something like this: Everything is quite obvious: constructor, destructor, initialization and rendering of the interface. Nothing complicated. Almost empty implementation:
#ifndef __lj_plasmoid_h
#define __lj_plasmoid_h
#include
class QSizeF;
class LjPlasmoid : public Plasma::Applet
{
Q_OBJECT
public:
LjPlasmoid(QObject *parent, const QVariantList &args);
~LjPlasmoid();
void paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect& contentsRect);
void init();
};
#endif
* This source code was highlighted with Source Code Highlighter.
#include "lj_plasmoid.h"
#include
#include
#include
#include
#include
// этот макрос призван рассказать плазме о нашем существовании
// а также связать сам модуль и .desktop файл
K_EXPORT_PLASMA_APPLET(ljplasmoid, LjPlasmoid)
LjPlasmoid::LjPlasmoid(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args)
{
// воспользуемся стандартным фоном
// и зададим размеры окна
setBackgroundHints(DefaultBackground);
resize(400, 300);
}
LjPlasmoid::~LjPlasmoid()
{
}
void LjPlasmoid::init()
{
}
void LjPlasmoid::paintInterface(QPainter *p,
const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
// рисовать нам пока нечего
}
* This source code was highlighted with Source Code Highlighter.
Having saved all this, I began to assemble my plasmoid in order to immediately make sure that my widget draws an empty area in a beautiful frame. For this, in addition to the module itself, a .desktop file of the following content is required: Attention should be paid to the fact that the value of the X-KDE-PluginInfo-Name field must match the first parameter of the K_EXPORT_PLASMA_APPLEТ macro. Next, the module itself must be copied to the folder with the KDE4 libraries (for most cases it is' / usr / lib / kde4 ', or in the case of x86_64 assembly' / usr / lib64 / kde4 '), and the .desktop file should be sent to the address' / usr / share / kde4 / services'. Well, the final touch we need to make the plasma re-read its data so that the newly created widget appears in the list of available ones. This is done by executing the funny command 'kbuildsycoca4'.
[Desktop Entry]
Name=LjPlasmoid
Comment=LiveJournal Plasmoid
Type=Service
ServiceTypes=Plasma/Applet
X-KDE-Library=plasma_applet_ljplasmoid
X-KDE-PluginInfo-Author=Ivan Ivanov
X-KDE-PluginInfo-Email=ivan.ivanov@mail.ru
X-KDE-PluginInfo-Name=ljplasmoid
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=GPL
X-KDE-PluginInfo-EnabledByDefault=true
There are two ways to see the plasmoid in action: add it directly to the desktop, or use the 'plasmoidviewer' utility, which will show the widget in a weekly window. However, neither one nor the other helped me. Instead of my "brainchild," I stubbornly looked at the error message, which claimed that an object named 'ljplasmoid' could not be created.
Attempts to localize the problem were long and painful. All means were used, up to the excellent utility 'strace', with the help of which I tried to determine whether the process 'plasma-desktop' accesses my binary module. It turned out, yes, it was turning, but there was little sense from it - the error stubbornly continued to manifest itself. Last but not least, after a few hours of stomping on the same spot, I began to suspect that the problem might lie in the assembly (I used the IDE CodeBlocks to edit the source code and assembly). Desperate to solve the problem in another way, I decided to try using the cmake-script offered on the KDE site for compilation. Here it is with minimal changes:
project(ljplasmoid)
set(CMAKE_VERBOSE_MAKEFILE ON)
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories( ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES})
set(ljplasmoid_SRCS lj_plasmoid.cpp)
kde4_add_plugin(plasma_applet_ljplasmoid ${ljplasmoid_SRCS})
target_link_libraries(plasma_applet_ljplasmoid ${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS})
To build using the 'cmake' utility, you need to run the command 'cmake -G "Unix Makefiles" && make' in the folder where the CMakeLists.txt file is located (it contains the script itself). For reasons that are not quite clear to me, the change in the compilation method has paid off - the plasmoid has earned! The translucent empty rectangle that appeared on the desktop, in addition to indescribable joy, caused a very strong attack of enthusiasm in me, and I began to continue what was started. The only thing that overshadowed my pleasure with such a development model was the lack of a single IDE and, as a result, the need to constantly switch between the terminal and the editor. But here the way out was found quite quickly. The KDevelop development environment and its built-in 'CMake-based project' project template quickly resolved all my problems.
The next technical case is to add user interface elements (I just need an input field and a “Submit” button). Plasma uses Qt, although in fact you have to connect classes that are bindings over Qt-ones. In total, we have several new include'ov and declarations in the class: Well, of course, the implementation becomes a little more meaningful: In this way, I got a widget that does not know how, but has a simple "face": For working directly with LiveJournal used the API described
...
#include
#include
...
class LjPlasmoid : public Plasma::Applet
{
...
public slots:
void PostPressed();
public:
Plasma::PushButton m_post_button;
Plasma::TextEdit m_text_edit;
};
* This source code was highlighted with Source Code Highlighter.
LjPlasmoid::LjPlasmoid(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args), m_post_button(this), m_text_edit(this)
{
m_post_button.setText("Post");
m_text_edit.setText("[ok: put your text here]");
connect(&m_post_button, SIGNAL(clicked()), SLOT(PostPressed()));
setBackgroundHints(DefaultBackground);
resize(300, 200);
}
void LjPlasmoid::paintInterface(QPainter *p,
const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
p->setRenderHint(QPainter::SmoothPixmapTransform);
p->setRenderHint(QPainter::Antialiasing);
m_post_button.setGeometry(QRect(contentsRect.x() + contentsRect.width() - 75,
contentsRect.y() + contentsRect.height() - 30, 10, 30));
m_text_edit.setGeometry(QRect(contentsRect.x(), contentsRect.y(),
contentsRect.width(), contentsRect.height() - 35));
}
* This source code was highlighted with Source Code Highlighter.

on the official site, as well as a simple set of classes written by me for these purposes, using 'libcurl'. I will not publish the source code of this class, since they go beyond the topic of the topic, but those interested can download them here .
So, the last method remains to be implemented - sending a message to the journal: This is just an example of how to create a plasmoid for your own needs. For this reason, there is no error return, fine tuning of behavior parameters, etc. However, this topic is quite capable of giving a general and most superficial idea of what Plasma is from the inside.
void LjPlasmoid::PostPressed()
{
LjSession session;
LjRequest post(&session, recieve_responce, this);
post.AddData("mode", "postevent");
post.AddData("user", "user_name");
post.AddData("password", "user_password");
post.AddData("ver", "1");
post.AddData("event", m_text_edit.nativeWidget()->toPlainText().toAscii().data());
post.AddData("lineendings", "unix");
post.AddData("subject", "[Posted via LjPlasmoid]");
post.AddData("security", "public");
post.AddData("year", "2009");
post.AddData("mon", "11");
post.AddData("day", "23");
post.AddData("hour", "20");
post.AddData("min", "00");
printf("text2send: %s\n", m_text_edit.nativeWidget()->toPlainText().toAscii().data());
post.Post();
m_text_edit.setText("[ok: put your text here]");
}
* This source code was highlighted with Source Code Highlighter.
As for this widget, the plans are as follows: bring to mind; implement sane setup; Share on KDE-Look. Recently, I’ve been thinking about the idea of moving all protocol-dependent logic to lua scripts, thereby providing extensibility and the ability to work with various blog platforms.
PS And most importantly: many thanks to nsinreal for invite!