Building Plugins:MythNotes03
From MythTV Official Wiki
Stores full-text notes in one big textarea.
- Internal storage gContext
- Basic SQL storage
Note: Read the MythNotes introduction Building_Plugins:MythNotes first.
Note: This tutorial follows-up the Building_Plugins:MythNotes02 tutorial.
C++ code
In this example are displayed two kinds of storing informations commonly used in MythTV.
- mythcontext - QString storage with QString key. Allows per frontend or general storage.
- mythdb - MySQL driver.
/* * 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); 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; } gCoreContext->ActivateSettingsCache(false); QString hostname = gCoreContext->GetHostName(); if (gCoreContext->GetSettingOnHost("NotesExecuted", hostname).isEmpty()) { gCoreContext->SaveSettingOnHost("NotesExecuted", "False", hostname); } if (gCoreContext->GetSetting("NotesExecutedCount").isEmpty()) { gCoreContext->SaveSetting("NotesExecutedCount", "0"); } gCoreContext->ActivateSettingsCache(true); setupKeys(); return 0; } void runNotes(void) { RunNotes(); } int RunNotes(void) { MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); NotesUI *notes = new NotesUI(mainStack, "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); 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"); }
- include gContext and SQL
- mythplugin_init()
- Check default gContext setting (per host and general)
/* * 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> #include <mythcontext.h> class MythUIButton; class MythUIText; class MythUITextEdit; class QKeyEvent; class NotesUI : public MythScreenType { Q_OBJECT public: NotesUI(MythScreenStack *parentStack, QString name = "MythNotes"); bool Create(); bool keyPressEvent(QKeyEvent *event); private: MythUIText *m_title; MythUIText *m_notes; MythUITextEdit *m_table; MythUIButton *m_selectBtn; MythUIButton *m_closeBtn; private slots: void selectCallback(); void closeCallback(); }; class NotesUISettings : public MythScreenType { Q_OBJECT public: NotesUISettings(MythScreenStack *parentStack); bool Create(); private: MythUIButton *m_clearBtn; private slots: void clearCallback(); }; #endif /* NOTESUI_H_ */
- minor changes in includes, variables and private slots
/* * 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, QString name) : MythScreenType(parent, name), m_title(NULL), m_notes(NULL), m_table(NULL), m_selectBtn(NULL), m_closeBtn(NULL) { } bool NotesUI::Create() { 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_table, "table", &err); UIUtilE::Assign(this, m_selectBtn, "selectbtn", &err); UIUtilE::Assign(this, m_closeBtn, "closebtn", &err); if (err) return false; connect(m_selectBtn, SIGNAL(Clicked()), this, SLOT(selectCallback())); connect(m_closeBtn, SIGNAL(Clicked()), this, SLOT(closeCallback())); /* NOT LOCKED, DEMONSTRATION ONLY */ gCoreContext->ActivateSettingsCache(false); QString hostname = gCoreContext->GetHostName(); if (gCoreContext->GetSettingOnHost("NotesExecuted", hostname) != "True") { gCoreContext->SaveSettingOnHost("NotesExecuted", "True", hostname); m_title->SetText("MythNotes HOST "); } else { m_title->SetText("MythNotes "); } int executed = (gCoreContext->GetSetting("NotesExecutedCount")).toInt() + 1; gCoreContext->SaveSetting("NotesExecutedCount", executed); gCoreContext->ActivateSettingsCache(true); m_title->SetText(m_title->GetText() + QString(" %1").arg(executed)); BuildFocusList(); SetFocusWidget(m_table); 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::selectCallback() { MSqlQuery db(MSqlQuery::InitCon()); QString query = QString("SELECT * " "FROM %1").arg(m_table->GetText()); if (!db.exec(query)) { MythDB::DBError("Notes select tables", db); m_notes->SetText("Error occured"); return; } m_notes->SetText(""); while (db.next()) { m_notes->SetText(m_notes->GetText() + "\n" + db.value(0).toString()); } } void NotesUI::closeCallback() { Close(); } NotesUISettings::NotesUISettings(MythScreenStack *parent) : MythScreenType(parent, "Notes UI Settings"), m_clearBtn(NULL) { } bool NotesUISettings::Create() { 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() { gCoreContext->ActivateSettingsCache(false); gCoreContext->SaveSetting("NotesExecutedCount", "0"); gCoreContext->ActivateSettingsCache(true); }
- NotesUI::Create()
- Assigns UIs
- connects signals->slots
- modifies UI texts accordingly to setting
- builds focus'
- NotesUI::selectCallback()
- creates DB connection
- executes the querry (SQL syntax)
- while (db.next()) - goes through results; stores the current line in db.value()
UI files
<?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="table" from="basetextedit"> <area>405,80,395,30</area> </textedit> <button name="selectbtn" from="basewidebutton"> <position>405,130</position> <value>Display table</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 Global No. Executions</value> </button> </window> </mythuitheme>
- Only minor changes you already know
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:MythNotes02)
- Modify the C++ code (includes, init, gContext, SQL, ...)
- Modify the XML UI layout (minor changes)
Next tutorial
Note: You have successfully finished the Storing the information tutorial. Let's move on to the next level - "Advanced UI" (Building_Plugins:MythNotes04)