Building Plugins:MythNotes02

From MythTV Official Wiki
Jump to: navigation, search

Displays how many times was the plug-in executed since mythfrontend start.

  • "Invisible" initialization and clean-up parts
  • Second window for plug-in configuration


Important.png Note: Read the MythNotes introduction Building_Plugins:MythNotes first.

Important.png Note: This tutorial follows-up the Building_Plugins:MythNotes01 tutorial.

C++ code

Script.png /mythnotes/main.cpp

/*
 * Main of MythTV's demonstration plugin MythNotes
 *
 * Copyright (C) 2010 Lukas Doktor <ldoktor@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 */

#include <iostream>
using namespace std;

#include <QApplication>

#include "notesUI.h"

#include <mythversion.h>
#include <mythpluginapi.h>
#include <mythscreentype.h>
#include <mythuihelper.h>
#include <mythmainwindow.h>
#include <mythcontext.h>


#define LOC_ERR QString("MythNotes:MAIN Error: ")
#define LOC_WARN QString("MythNotes:MAIN Warning: ")
#define LOC QString("MythNotes:MAIN: ")

/* Main program run wrappers */
void runNotes(void);
int  RunNotes(void);

unsigned int *g_executed;

void setupKeys(void)
{
    REG_JUMP("MythNotes", QT_TRANSLATE_NOOP("MythControls",
        "Notes taking demonstration plugin"), "", runNotes);
    REG_KEY("Notes", "EXIT", QT_TRANSLATE_NOOP("MythControls",
    	"Exit the Smart Home"), "Q");
}

/* plugin initialization */
int mythplugin_init(const char *libversion)
{
	VERBOSE(VB_IMPORTANT, LOC + "init");
    if (!gContext->TestPopupVersion("mythnotes", libversion,
                                    MYTH_BINARY_VERSION))
    {
        VERBOSE(VB_IMPORTANT,
                QString("libmythnotes.so/main.o: binary version mismatch"));
        return -1;
    }

    if (!(g_executed = new unsigned int))
    	return -1;
    *g_executed = 0;

    setupKeys();

    return 0;
}

void runNotes(void)
{
    RunNotes();
}

int RunNotes(void)
{
    MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
    NotesUI *notes = new NotesUI(mainStack, g_executed, "Notes");
    
    if (notes->Create())
    {
        mainStack->AddScreen(notes);
        return 0;
    } else {
        delete notes;
        return -1;
    }
}

/* plugin execution */
int mythplugin_run(void)
{
	VERBOSE(VB_IMPORTANT, LOC + "exec");
    return RunNotes();
}

/* plugin config execution */
int mythplugin_config(void)
{
	VERBOSE(VB_IMPORTANT, LOC + "config");
    MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
    NotesUISettings *notes = new NotesUISettings(mainStack, g_executed);

    if (notes->Create())
    {
        mainStack->AddScreen(notes);
        return 0;
    } else {
        delete notes;
        return -1;
    }
}

/* plugin clean-up */
void mythplugin_destroy(void)
{
	VERBOSE(VB_IMPORTANT, LOC + "destroy");
	delete g_executed;
}
  • setupKeys()
    • REG_JUMP - Registers the jumps - can maps a function from this plug-in to a key in MythTV configuration
    • REG_KEY - Creates a named key event which can be mapped in MythTV configuration to different key
  • mythplugin_init()
    • Complete initialization
    • First check the libversion
    • Initialize objects/threads/variables
    • Setup additiona keyboards
  • RunNotes(), runNotes(), mythplugin_run()
    • stays the same (notify that mythplugin_run uses RunNotes and REG_JUMP uses runNotes)
  • mythplugin_config()
    • Additional screen. Looks similar with RunNotes only it creates NotesUISettings object instead of NotesUI.
  • mythplugin_destroy()
    • Clean-up


Script.png /mythnotes/notesUI.h

/*
 * Header file for UI
 *
 * Copyright (C) 2010 Lukas Doktor <ldoktor@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 */

#ifndef NOTESUI_H_
#define NOTESUI_H_

#include <QString>
#include <QKeyEvent>

#include <mythscreentype.h>
#include <mythmainwindow.h>
#include <mythdialogbox.h>
#include <mythuibutton.h>
#include <mythdb.h>
#include <mythverbose.h>

class MythUIButton;
class MythUIText;
class MythUITextEdit;
class QKeyEvent;

class NotesUI : public MythScreenType
{
	Q_OBJECT

  public:
	NotesUI(MythScreenStack *parentStack, unsigned int *executed,
			QString name = "MythNotes");
	bool Create();
	bool keyPressEvent(QKeyEvent *event);

  private:
	unsigned int	*m_executed;
	MythUIText		*m_title;
	MythUIText		*m_notes;
	MythUITextEdit	*m_newnote;
	MythUIButton	*m_addBtn;
	MythUIButton	*m_closeBtn;

  private slots:
	void addCallback();
	void closeCallback();
};

class NotesUISettings : public MythScreenType
{
	Q_OBJECT

  public:
	NotesUISettings(MythScreenStack *parentStack, unsigned int *executed);
	bool Create();

  private:
	unsigned int	*m_executed;
	MythUIButton	*m_clearBtn;
  private slots:
	void clearCallback();
};

#endif /* NOTESUI_H_ */
  • class NotesUI
    • (header) is the same as in the previous tutorial
  • class NotesUISettings
    • New window with plug-in setting


Script.png /mythnotes/notesUI.cpp

/*
 * Source file for UIs
 *
 * Copyright (C) 2010 Lukas Doktor <ldoktor@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 */

#include "notesUI.h"

#define LOC_ERR QString("MythNotes:notesUI Error: ")
#define LOC_WARN QString("MythNotes:notesUI Warning: ")
#define LOC QString("MythNotes:notesUI: ")

NotesUI::NotesUI(MythScreenStack *parent, unsigned int *executed, QString name)
		: MythScreenType(parent, name), m_title(NULL), m_notes(NULL),
		  m_newnote(NULL), m_addBtn(NULL), m_closeBtn(NULL)
{
	m_executed = executed;
}

bool NotesUI::Create()
{
	if (!m_executed) {
		VERBOSE(VB_IMPORTANT, LOC + "uninitialized variable m_executed");
		return false;
	}

	if (!LoadWindowFromXML("notes-ui.xml", "notesui", this))
		return false;

	bool err = false;
	UIUtilE::Assign(this, m_title, "title", &err);
	UIUtilE::Assign(this, m_notes, "notes", &err);
	UIUtilE::Assign(this, m_newnote, "newnote", &err);
	UIUtilE::Assign(this, m_addBtn, "addbtn", &err);
	UIUtilE::Assign(this, m_closeBtn, "closebtn", &err);
	if (err)
		return false;

	connect(m_addBtn, SIGNAL(Clicked()), this, SLOT(addCallback()));
	connect(m_closeBtn, SIGNAL(Clicked()), this, SLOT(closeCallback()));

	*m_executed += 1;
	m_notes->SetText(QString("MythNotes executed: %1").arg(*m_executed));

	BuildFocusList();
	SetFocusWidget(m_newnote);

	return true;
}

bool NotesUI::keyPressEvent(QKeyEvent *event)
{
    if (GetFocusWidget()->keyPressEvent(event))
        return true;

    bool handled = false;
    QStringList actions;
    handled = GetMythMainWindow()->TranslateKeyPress("Notes", event, actions);

    for (int i = 0; i < actions.size() && !handled; i++)
    {
        QString action = actions[i];
        handled = true;

        if (action == "ESCAPE") {
        	closeCallback();
        } else {
            handled = false;
        }
    }

    if (!handled && MythScreenType::keyPressEvent(event))
        handled = true;

    return handled;
}

void NotesUI::addCallback()
{
	m_notes->SetText(m_notes->GetText() + "\n\t" + m_newnote->GetText());
}

void NotesUI::closeCallback()
{
	Close();
}



NotesUISettings::NotesUISettings(MythScreenStack *parent, unsigned int *executed)
				: MythScreenType(parent, "Notes UI Settings"), m_clearBtn(NULL)
{
	m_executed = executed;
}

bool NotesUISettings::Create()
{
	if (!m_executed) {
		VERBOSE(VB_IMPORTANT, LOC + "uninitialized variable m_executed");
		return false;
	}

	if (!LoadWindowFromXML("notes-ui.xml", "notesuisettings", this))
		return false;

	bool err = false;
	UIUtilE::Assign(this, m_clearBtn, "clearbtn", &err);
	if (err)
		return false;

	connect(m_clearBtn, SIGNAL(Clicked()), this, SLOT(clearCallback()));

	BuildFocusList();
	SetFocusWidget(m_clearBtn);

	return true;
}

void NotesUISettings::clearCallback()
{
	*m_executed = 0;
}
  • Defines two window objects which are then used in the "main.cpp"

UI files

Script.png /themes/default/notes-ui.xml

<?xml version="1.0" encoding="utf-8"?>
<mythuitheme>
    <window name="notesui">
        <textarea name="title">
            <area>10,10,780,60</area>
            <font>baselarge</font>
            <align>allcenter</align>
            <multiline>yes</multiline>
            <value>MythNotes</value>
        </textarea>

        <textarea name="notes">
            <area>10,80,395,510</area>
            <font>basemedium</font>
            <align>left,top</align>
            <multiline>yes</multiline>
        </textarea>

        <textedit name="newnote" from="basetextedit">
            <area>405,80,395,30</area>
        </textedit>

        <button name="addbtn" from="basewidebutton">
            <position>405,130</position>
            <value>Add note</value>
        </button>

        <button name="closebtn" from="basewidebutton">
            <position>405,180</position>
            <value>Close</value>
        </button>
    </window>
    
    <window name="notesuisettings">
    	<textarea name="title">
            <area>10,10,780,60</area>
            <font>baselarge</font>
            <align>allcenter</align>
            <multiline>yes</multiline>
            <value>Notes Settings</value>
        </textarea>
        
        <button name="clearbtn" from="basewidebutton">
            <position>30,80</position>
            <value>Clear No. Executions</value>
        </button>
    </window>
</mythuitheme>
  • In XML file we need to define two windows. Based on the "name" they are than loaded from C++ file and the UI widgets are assigned and used in the code.


Remaining files

No changes here

Compile & Run

See the first part Building_Plugins:MythNotes00.

Recapitulation

  • copy the plug-in from the first part (Building_Plugins:MythNotes01)
  • Modify the C++ code (Complete initialization, add new window and define clean-up)
  • Modify the XML UI layout (Add second screen)

Next tutorial

Important.png Note: You have successfully finished the Complete plug-in tutorial. Let's move on to the next level - "Storing the information" (Building_Plugins:MythNotes03)