File: plugin_kxmlhelloworld.cpp

package info (click to toggle)
libkf5kipi 4%3A17.08.3-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 740 kB
  • sloc: cpp: 4,772; makefile: 3
file content (334 lines) | stat: -rw-r--r-- 12,827 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/* ============================================================
 *
 * This file is a part of kipi-plugins project
 * http://www.digikam.org
 *
 * Date        : 2012-02-16
 * Description : an Hello World plugin using KDE XML-GUI technology.
 *
 * Copyright (C) 2012-2017 by Gilles Caulier <caulier dot gilles at gmail dot com>
 * Copyright (C) 2012      by Victor Dodon   <dodonvictor at gmail dot com>
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU 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.
 *
 * ============================================================ */

/** Take a care about includes order, to prevent compilation problem.
 *  1/ class header file.
 *  2/ C ansi if really necessary.
 *  3/ C++ (always prefered than C ansi.
 *  4/ Extra libraries such as openCV for ex.
 *  4/ Qt.
 *  5/ KDE.
 *  6/ Local files.
 *  7/ At end of file .moc file of class.
 *
 *  Also, use C++ classes include header styles with Qt5,
 *  but do not use it with KF5 headers (use C ANSI style instead).
 */

// include here header file. See also loc file to plug at end of implementation.

#include "plugin_kxmlhelloworld.h"

// Qt includes

#include <QPointer>
#include <QDomDocument>
#include <QAction>
#include <QDebug>
#include <QKeySequence>
#include <QUrl>
#include <QDialog>
#include <QDialogButtonBox>
#include <QVBoxLayout>
#include <QPushButton>
#include <QMessageBox>

// KDE includes

#include <kpluginfactory.h>

/// This is all libkipi headers included in this tool.

#include "imagecollection.h"
#include "imagecollectionselector.h"
#include "interface.h"

// Special header used to include kipi-plugins debug space when plugin is includes in Kipi-plugins project.
//#include "kipiplugins_debug.h"

/** Put here all Kipi-plugins common includes used to create a new tool.
 *  Look into kipi-plugins/common/libkipiplugins/ API documentation for details.
 */

/// You must wrap all your plugin code to a dedicated namespace
namespace KIPIKXMLHelloWorldPlugin
{

/** Under Kipi-plugins, you can use KPToolDialog class from kipi-plugins to display plugin dialogs. It offers some facilities to
    set data and rules about plugins, especially to wrap properlly tool with KDE bugilla. We use KPAboutData container
    for that.
*/

/** Using private container everywhere is clear to speed up compilation and reduce source code depencies through header files.
 *  See this url for details : http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B#Using_a_d-Pointer
 */
class Plugin_KXMLHelloWorld::Private
{
public:

    Private()
    {
        /// It's always clean to init pointers to zero. If crash appear,
        /// debugger will show a null pointer instead a non initialized one.
        actionImages = 0;
        actionTools  = 0;
        actionExport = 0;
        actionImport = 0;
    }

    /** These plugin actions will pluged into menu KIPI host application.
     */
    QAction* actionImages;
    QAction* actionTools;
    QAction* actionExport;
    QAction* actionImport;
};

/** Macro from KDE KParts to create the factory for this plugin.
 *  The first argument is the name of the plugin library
 *  and the second is the generic factory templated from
 *  the class for your plugin.
 */
K_PLUGIN_FACTORY(KXMLHelloWorldFactory, registerPlugin<Plugin_KXMLHelloWorld>();)

/** The plugin constructor. Note that plugin name passed as string in 3rd arguement of KIPI::Plugin parent class
 *  is the same than Name value from .desktop file.
 */
Plugin_KXMLHelloWorld::Plugin_KXMLHelloWorld(QObject* const parent, const QVariantList&)
    : Plugin(parent, "KXMLHelloWorld"),
      /// Private container is allocated here.
      d(new Private)
{
    // plugin do not use libkipi debug space. There is a debug space dedicate to kipi-plugins. See kipiplugins_debug.h header.
    //qCDebug(KIPIPLUGINS_LOG) << "Plugin_KXMLHelloWorld plugin loaded";

    /** This is needed to setup the plugin gui and to merge with the kipi host
     *  application gui.
     *  The name of the UI file must be: nameofpluginui.rc, where "nameofplugin"
     *  is the name given to the plugin factory, usualy: kipiplugin_<name> .
     *  UI file of the plugin must be installed in kipi data dir.
     */
    setUiBaseName("kipiplugin_kxmlhelloworldui.rc");

    /** We need to call setupXML so the XML file and the GUI of the plugin to
      * be merged with those of the KIPI host app
      */
    setupXML();
}

Plugin_KXMLHelloWorld::~Plugin_KXMLHelloWorld()
{
    /// Don't forget to clear d private container allocation in destructor to prevent memory leak.
    delete d;
}

void Plugin_KXMLHelloWorld::setup(QWidget* const widget)
{
    /** Each plugin must overload Plugin::setup method.
     *  We pass the widget which host plugin in KIPI host application
     */
    Plugin::setup(widget);

    /** This is the interface instance to plugin host application. Note that you can get it everywhere in your plugin using
     *  instance of KIPI::PluginLoader singleton which provide a method for that.
     *  Since libkipi 2.0.0, KIPI host interface is also available from KIPI::Plugin::interface().
     */
    if (!interface())
        return;

    /** We will enable plugin actions only if the KIPI interface is not null
      */
    setupActions();
}

void Plugin_KXMLHelloWorld::setupActions()
{
    /** We define plugin action which will be plug in KIPI host application.
     *  Note that if you set keyboard shortcut to an action you must take a care
     *  about already existing one from other tool to prevent conflict.
     *  Don't forget to define an unique string name to your action, to be able to disable it
     *  in KIPI host application if necessary. You must check of course name already used in
     *  others tool before to prevent redondancy.
     */

    /** We need to call setDefaultCategory in case the plugin loader cannot
      * recognize the category of an action
      */
    setDefaultCategory(ExportPlugin);

    /** An action dedicated to be plugged in digiKam Image menu.
     */
    d->actionImages = new QAction(this);
    d->actionImages->setText(QLatin1String("KXML Hello World Image..."));
    d->actionImages->setIcon(QIcon::fromTheme(QString::fromLatin1("script-error")));
    d->actionImages->setShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::CTRL + Qt::Key_F1));

    /** Connect plugin action signal to dedicated slot.
     */
    connect(d->actionImages, SIGNAL(triggered(bool)),
            this, SLOT(slotActivateActionImages()));

    /** We need to register actions in plugin instance
     */
    addAction(QString::fromLatin1("kxmlhelloworld-actionImage"), d->actionImages, ImagesPlugin);

    /** This will get items selection from KIPI host application.
     */
    ImageCollection selection = interface()->currentSelection();
    d->actionImages->setEnabled(selection.isValid() && !selection.images().isEmpty());

    /** Another action dedicated to be plugged in digiKam Tool menu.
     */
    d->actionTools = new QAction(this);
    d->actionTools->setText(QLatin1String("KXML Hello World Tools..."));
    d->actionTools->setIcon(QIcon::fromTheme(QString::fromLatin1("script-error")));
    d->actionTools->setShortcut(QKeySequence(Qt::ALT+Qt::SHIFT+Qt::CTRL+Qt::Key_F2));

    connect(d->actionTools, SIGNAL(triggered(bool)),
            this, SLOT(slotActivateActionTools()));

    addAction(QString::fromLatin1("kxmlhelloworld-actionTools"), d->actionTools, ToolsPlugin);

    /** We will get current selected album in the digikam tree view
     */
    ImageCollection currAlbum = interface()->currentAlbum();
    bool enable               = currAlbum.isValid() && !currAlbum.images().isEmpty();
    d->actionTools->setEnabled(enable);

    /** Another action dedicated to be plugged in digiKam Export menu.
     */
    d->actionExport = new QAction(this);
    d->actionExport->setText(QLatin1String("KXML Hello World Export..."));
    d->actionExport->setIcon(QIcon::fromTheme(QString::fromLatin1("script-error")));
    d->actionExport->setShortcut(QKeySequence(Qt::ALT+Qt::SHIFT+Qt::CTRL+Qt::Key_F3));

    connect(d->actionExport, SIGNAL(triggered(bool)),
            this, SLOT(slotActivateActionExport()));

    addAction(QString::fromLatin1("kxmlhelloworld-actionExport"), d->actionExport, ExportPlugin);

    /** Another action dedicated to be plugged in digiKam Import menu.
     */
    d->actionImport = new QAction(this);
    d->actionImport->setText(QLatin1String("KXML Hello World Import..."));
    d->actionImport->setIcon(QIcon::fromTheme(QString::fromLatin1("script-error")));
    d->actionImport->setShortcut(QKeySequence(Qt::ALT+Qt::SHIFT+Qt::CTRL+Qt::Key_F4));

    connect(d->actionImport, SIGNAL(triggered(bool)),
            this, SLOT(slotActivateActionImport()));

    addAction(QString::fromLatin1("kxmlhelloworld-actionImport"), d->actionImport, ImportPlugin);

    /** If selection change in KIPI host application, this signal will be fired, and plugin action enabled accordingly.
     */
    connect(interface(), SIGNAL(selectionChanged(bool)),
            d->actionImages, SLOT(setEnabled(bool)));

    connect(interface(), SIGNAL(currentAlbumChanged(bool)),
            d->actionTools, SLOT(setEnabled(bool)));
}

void Plugin_KXMLHelloWorld::slotActivateActionImages()
{
    /** When actionImages is actived, we display list of items selected in a message box.
     *  This example show a simple dialog with current items selected in KIPI host application.
     *  You can branch here your dedicated dialog to process items as you want.
     */
    ImageCollection images = interface()->currentSelection();

    if (images.isValid() && !images.images().isEmpty())
    {
        QStringList names;

        foreach (const QUrl& url, images.images())
            names << url.fileName();

        QMessageBox::information(0, QLatin1String("This is the list of selected items"), names.join(QString::fromLatin1("\n")));
    }
}

void Plugin_KXMLHelloWorld::slotActivateActionTools()
{
    /** When actionTools is actived, we display a dedicated widget to select albums from kipi host application
     *  for post processing purpose. When selection is done, we display it in a message box.
     */
    QPointer<QDialog> dlg                   = new QDialog(0);
    ImageCollectionSelector* const selector = interface()->imageCollectionSelector(dlg);
    QDialogButtonBox* const buttons         = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, dlg);
    QVBoxLayout* const vbox                 = new QVBoxLayout(dlg);
    vbox->addWidget(selector);
    vbox->addWidget(buttons);
    dlg->setLayout(vbox);

    connect(buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked,
            dlg.data(), &QDialog::accept);

    connect(buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked,
            dlg.data(), &QDialog::reject);

    dlg->exec();

    QList<ImageCollection> list = selector->selectedImageCollections();

    if (!list.isEmpty())
    {
        QStringList names;

        foreach (const ImageCollection& col, list)
            names << col.name();

        QMessageBox::information(0, QLatin1String("This is the list of selected albums"), names.join(QString::fromLatin1("\n")));
    }

    delete dlg;
}

void Plugin_KXMLHelloWorld::slotActivateActionExport()
{
    /** When actionExport is actived, we can display a dedicated widget from libkipiplugins which will show
     *  and permit to manage current items selection from kipi host application for batch post-processing purpose.
     */

    QMessageBox::information(0, QLatin1String("Information"), QLatin1String("Plugin_KXMLHelloWorld::slotActivateActionExport() activated"));
}

void Plugin_KXMLHelloWorld::slotActivateActionImport()
{

    ImageCollection images = interface()->currentSelection();

    if (images.isValid() && !images.images().isEmpty())
    {
        /** When actionImport is actived, we can display a dedicated widget from libkipiplugins which will preview
         *  the first selected item of current selection from kipi host application.
         */
    }

    QMessageBox::information(0, QLatin1String("Information"), QLatin1String("Plugin_KXMLHelloWorld::slotActivateActionImport() activated"));
}

}  // namespace KIPIHelloWorldPlugin

// Moc file must be included at end because it's a plugin (it's a specific and special case where we need to do it).

#include "plugin_kxmlhelloworld.moc"