summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/pim/today/plugins/addressbook/addressplugin.cpp5
-rw-r--r--core/pim/today/plugins/addressbook/addressplugin.h1
-rw-r--r--core/pim/today/plugins/addressbook/addresspluginconfig.cpp2
-rw-r--r--core/pim/today/plugins/addressbook/addresspluginconfig.h2
-rw-r--r--core/pim/today/plugins/addressbook/addresspluginwidget.cpp11
-rw-r--r--core/pim/today/plugins/addressbook/addresspluginwidget.h1
-rw-r--r--core/pim/today/plugins/addressbook/opie-today-addressbookplugin.control2
7 files changed, 15 insertions, 9 deletions
diff --git a/core/pim/today/plugins/addressbook/addressplugin.cpp b/core/pim/today/plugins/addressbook/addressplugin.cpp
index a70f8d8..5d5d34c 100644
--- a/core/pim/today/plugins/addressbook/addressplugin.cpp
+++ b/core/pim/today/plugins/addressbook/addressplugin.cpp
@@ -1,69 +1,74 @@
/*
* addressplugin.cpp
*
* copyright : (c) 2003 by Stefan Eilers
* email : eilers.stefan@epost.de
*
* This implementation was derived from the todolist plugin implementation
*
*/
/***************************************************************************
* *
* 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 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "addressplugin.h"
#include "addresspluginconfig.h"
AddressBookPlugin::AddressBookPlugin():
m_abWidget( 0l )
{
}
AddressBookPlugin::~AddressBookPlugin() {
}
QString AddressBookPlugin::pluginName() const {
return QObject::tr( "AddressBook plugin" );
}
double AddressBookPlugin::versionNumber() const {
return 0.3;
}
QString AddressBookPlugin::pixmapNameWidget() const {
return "addressbook/AddressBook";
}
QWidget* AddressBookPlugin::widget( QWidget *wid ) {
m_abWidget = new AddressBookPluginWidget( wid, "AddressBook" );
return m_abWidget;
}
QString AddressBookPlugin::pixmapNameConfig() const {
return "addressbook/AddressBook";
}
TodayConfigWidget* AddressBookPlugin::configWidget( QWidget* wid ) {
return new AddressBookPluginConfig( wid , "AddressBook" );
}
QString AddressBookPlugin::appName() const {
return "addressbook";
}
bool AddressBookPlugin::excludeFromRefresh() const {
return false;
}
void AddressBookPlugin::refresh()
{
m_abWidget->refresh( NULL );
}
+
+void AddressBookPlugin::reinitialize()
+{
+ m_abWidget->reinitialize();
+}
diff --git a/core/pim/today/plugins/addressbook/addressplugin.h b/core/pim/today/plugins/addressbook/addressplugin.h
index 04e4faf..0b3b065 100644
--- a/core/pim/today/plugins/addressbook/addressplugin.h
+++ b/core/pim/today/plugins/addressbook/addressplugin.h
@@ -1,50 +1,51 @@
/*
* addressplugin.h
*
* copyright : (c) 2003 by Stefan Eilers
* email : eilers.stefan@epost.de
*
* This implementation was derived from the todolist plugin implementation
*
*/
/***************************************************************************
* *
* 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 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef ADDRESSBOOK_PLUGIN_H
#define ADDRESSBOOK_PLUGIN_H
#include <qstring.h>
#include <qwidget.h>
#include <opie/oclickablelabel.h>
#include <opie/todayplugininterface.h>
#include "addresspluginwidget.h"
class AddressBookPlugin : public TodayPluginObject {
public:
AddressBookPlugin();
~AddressBookPlugin();
QString pluginName() const;
double versionNumber() const;
QString pixmapNameWidget() const;
QWidget* widget(QWidget *);
QString pixmapNameConfig() const;
TodayConfigWidget* configWidget(QWidget *);
QString appName() const;
bool excludeFromRefresh() const;
void refresh();
+ void reinitialize();
private:
AddressBookPluginWidget* m_abWidget;
};
#endif
diff --git a/core/pim/today/plugins/addressbook/addresspluginconfig.cpp b/core/pim/today/plugins/addressbook/addresspluginconfig.cpp
index 9c65e7d..b79c679 100644
--- a/core/pim/today/plugins/addressbook/addresspluginconfig.cpp
+++ b/core/pim/today/plugins/addressbook/addresspluginconfig.cpp
@@ -1,175 +1,173 @@
/*
* addresspluginconfig.cpp
*
* copyright : (c) 2003 by Stefan Eilers
* email : eilers.stefan@epost.de
*
* This implementation was derived from the todolist plugin implementation
*
*/
/***************************************************************************
* *
* 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 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "addresspluginconfig.h"
#include <qpe/config.h>
#include <qlayout.h>
#include <qhbox.h>
#include <qtoolbutton.h>
#include <qlabel.h>
#include <qwhatsthis.h>
#include <qvgroupbox.h>
AddressBookPluginConfig::AddressBookPluginConfig( QWidget *parent, const char* name)
: TodayConfigWidget(parent, name ) {
QVBoxLayout * layout = new QVBoxLayout( this );
layout->setMargin( 20 );
#if 0
// Informational stuff
QHBox *box4 = new QHBox( this );
QLabel* colorLabel = new QLabel( box4, "" );
colorLabel->setText( tr( "To activate settings: Restart application !" ) );
#endif
// Buttongroup to enable/disable shown stuff
QVGroupBox* b_group = new QVGroupBox( this, "name" );
b_group -> setTitle( tr("Enable/Disable Views") );
m_showBirthdayButton = new QRadioButton( b_group );
m_showBirthdayButton -> setText( tr( "Show &Birthdays" ) );
m_showAnniversaryButton = new QRadioButton( b_group );
m_showAnniversaryButton -> setText( tr( "Show &Anniveraries" ) );
QWhatsThis::add( m_showBirthdayButton , tr( "The next birthdays will just be shown, if enabled!" ) );
QWhatsThis::add( m_showAnniversaryButton , tr( "The next anniversaries will just be shown, if enabled !" ) );
// Max lines settings
QHBox *box1 = new QHBox( this );
QLabel* TextLabel6 = new QLabel( box1, "TextLabel6" );
TextLabel6->setText( tr( "Max Lines: " ) );
SpinBox2 = new QSpinBox( box1, "SpinBox2" );
SpinBox2->setMaxValue( 40 );
QWhatsThis::add( SpinBox2 , tr( "Set the maximum number of lines that should be shown for each anniversaries/birthdays" ) );
#if 0
// Clip settings (currently not used)
QHBox *box2 = new QHBox( this );
QLabel* clipLabel = new QLabel( box2, "" );
clipLabel->setText( tr( "Clip line after X chars: " ) );
SpinBoxClip = new QSpinBox( box2, "SpinClip" );
SpinBoxClip->setMaxValue( 200 );
QWhatsThis::add( SpinBoxClip , tr( "After how many chars should be the info about the task be cut off" ) );
#endif
// Look ahead settings
QHBox *box3 = new QHBox( this );
QLabel* daysLabel = new QLabel( box3, "" );
daysLabel->setText( tr( "Days look ahead: " ) );
SpinDaysClip = new QSpinBox( box3, "SpinDays" );
SpinDaysClip->setMaxValue( 200 );
QWhatsThis::add( SpinDaysClip , tr( "How many days we should search forward" ) );
- // Headline color settings
QHBox *box5 = new QHBox( this );
QLabel* colorLabel2 = new QLabel( box5, "" );
colorLabel2->setText( tr( "Set Headline Color: " ) );
headlineColor = new OColorButton( box5, black , "headlineColor" );
QWhatsThis::add( headlineColor , tr( "Colors for the headlines !" ) );
QHBox *box6 = new QHBox( this );
// Entry color settings
QLabel* colorLabel3= new QLabel( box6, "" );
colorLabel3->setText( tr( "Set Entry Color: " ) );
entryColor = new OColorButton( box6, black , "entryColor" );
QWhatsThis::add( entryColor , tr( "This color will be used for shown birthdays/anniversaries !" ) );
// Urgent color settings
QHBox *box7 = new QHBox( this );
QLabel* colorLabel5 = new QLabel( box7, "" );
colorLabel5->setText( tr( "Set Urgent\nColor if below " ) );
SpinUrgentClip = new QSpinBox( box7, "SpinDays" );
SpinUrgentClip->setMaxValue( 200 );
QLabel* colorLabel6 = new QLabel( box7, "" );
colorLabel6->setText( tr( " days: " ) );
urgentColor = new OColorButton( box7, red , "urgentColor" );
QWhatsThis::add( urgentColor , tr( "This urgent color will be used if we are close to the event !" ) );
QWhatsThis::add( SpinUrgentClip , tr( "The urgent color will be used if the birthday/anniversary is closer than given days !" ) );
layout->addWidget( b_group );
- // layout->addWidget( box4 );
layout->addWidget( box1 );
// layout->addWidget( box2 );
layout->addWidget( box3 );
layout->addWidget( box5 );
layout->addWidget( box6 );
layout->addWidget( box7 );
readConfig();
}
void AddressBookPluginConfig::readConfig() {
Config cfg( "todayaddressplugin" );
cfg.setGroup( "config" );
m_max_lines_task = cfg.readNumEntry( "maxlinestask", 5 );
SpinBox2->setValue( m_max_lines_task );
// m_maxCharClip = cfg.readNumEntry( "maxcharclip", 38 );
// SpinBoxClip->setValue( m_maxCharClip );
m_daysLookAhead = cfg.readNumEntry( "dayslookahead", 14 );
SpinDaysClip->setValue( m_daysLookAhead );
m_urgentDays = cfg.readNumEntry( "urgentdays", 7 );
SpinUrgentClip->setValue( m_urgentDays );
m_entryColor = cfg.readEntry( "entrycolor", Qt::black.name() );
entryColor->setColor( QColor( m_entryColor ) );
m_headlineColor = cfg.readEntry( "headlinecolor", Qt::black.name() );
headlineColor->setColor( QColor( m_headlineColor ) );
m_urgentColor = cfg.readEntry( "urgentcolor", Qt::red.name() );
urgentColor->setColor( QColor( m_urgentColor ) );
m_showBirthdayButton->setChecked( cfg.readBoolEntry( "showBirthdays", true ) );
m_showAnniversaryButton->setChecked( cfg.readBoolEntry( "showAnniversaries", true ) );
}
void AddressBookPluginConfig::writeConfig() {
Config cfg( "todayaddressplugin" );
cfg.setGroup( "config" );
m_max_lines_task = SpinBox2->value();
cfg.writeEntry( "maxlinestask", m_max_lines_task );
// m_maxCharClip = SpinBoxClip->value();
// cfg.writeEntry( "maxcharclip", m_maxCharClip );
m_daysLookAhead = SpinDaysClip->value();
cfg.writeEntry( "dayslookahead", m_daysLookAhead );
m_urgentDays = SpinUrgentClip->value();
if ( m_urgentDays > m_daysLookAhead )
m_urgentDays = m_daysLookAhead;
cfg.writeEntry( "urgentdays", m_urgentDays );
m_entryColor = entryColor->color().name();
cfg.writeEntry( "entrycolor", m_entryColor );
m_headlineColor = headlineColor->color().name();
cfg.writeEntry( "headlinecolor", m_headlineColor );
m_urgentColor = urgentColor->color().name();
cfg.writeEntry( "urgentcolor", m_urgentColor );
cfg.writeEntry( "showBirthdays", m_showBirthdayButton->isChecked() );
cfg.writeEntry( "showAnniversaries", m_showAnniversaryButton->isChecked() );
cfg.write();
}
AddressBookPluginConfig::~AddressBookPluginConfig() {
}
diff --git a/core/pim/today/plugins/addressbook/addresspluginconfig.h b/core/pim/today/plugins/addressbook/addresspluginconfig.h
index 5e07aa3..5626e5d 100644
--- a/core/pim/today/plugins/addressbook/addresspluginconfig.h
+++ b/core/pim/today/plugins/addressbook/addresspluginconfig.h
@@ -1,75 +1,75 @@
/*
* addresspluginconfig.h
*
* copyright : (c) 2003 by Stefan Eilers
* email : eilers.stefan@epost.de
*
* This implementation was derived from the todolist plugin implementation
*
*/
/***************************************************************************
* *
* 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 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef ADDRESSBOOK_PLUGIN_CONFIG_H
#define ADDRESSBOOK_PLUGIN_CONFIG_H
#include <qwidget.h>
#include <qspinbox.h>
#include <qradiobutton.h>
#include <opie/todayconfigwidget.h>
#include <opie/ocolorbutton.h>
class AddressBookPluginConfig : public TodayConfigWidget {
-
+ Q_OBJECT
public:
AddressBookPluginConfig( QWidget *parent, const char *name );
~AddressBookPluginConfig();
private:
/**
* if changed then save
*/
bool changed();
void readConfig();
void writeConfig();
QSpinBox* SpinBox2;
QSpinBox* SpinBoxClip;
QSpinBox* SpinDaysClip;
QSpinBox* SpinUrgentClip;
OColorButton* entryColor;
OColorButton* headlineColor;
OColorButton* urgentColor;
QRadioButton* m_showBirthdayButton;
QRadioButton* m_showAnniversaryButton;
// how many lines should be showed in the AddressBook section
int m_max_lines_task;
// clip the lines after X chars
int m_maxCharClip;
// How many days look ahead
int m_daysLookAhead;
// Days until urgent color is used
int m_urgentDays;
// Entry Color
QString m_entryColor;
// Headline Color
QString m_headlineColor;
// Urgent Color
QString m_urgentColor;
};
#endif
diff --git a/core/pim/today/plugins/addressbook/addresspluginwidget.cpp b/core/pim/today/plugins/addressbook/addresspluginwidget.cpp
index 498de28..dad09db 100644
--- a/core/pim/today/plugins/addressbook/addresspluginwidget.cpp
+++ b/core/pim/today/plugins/addressbook/addresspluginwidget.cpp
@@ -1,217 +1,218 @@
/*
* addresspluginwidget.cpp
*
* copyright : (c) 2003 by Stefan Eilers
* email : eilers.stefan@epost.de
*
* This implementation was derived from the todolist plugin implementation
*
*/
/***************************************************************************
* *
* 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 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "addresspluginwidget.h"
#include <qvaluelist.h>
#include <qtl.h>
#include <qstring.h>
#include <qscrollview.h>
#include <qobject.h>
#include <qdatetime.h>
#include <qpe/config.h>
#include <qpe/timestring.h>
#include <qpe/qcopenvelope_qws.h>
#include <opie/ocontact.h>
AddressBookPluginWidget::AddressBookPluginWidget( QWidget *parent, const char* name )
: QWidget( parent, name ) {
addressLabel = 0l;
m_contactdb = 0l;
layoutTodo = 0l;
// Hä ? Nonsense ! (se)
if ( m_contactdb ) {
delete m_contactdb;
}
m_contactdb = new OContactAccess("addressplugin");
connect( m_contactdb, SIGNAL( signalChanged( const OContactAccess * ) ),
this, SLOT( refresh( const OContactAccess * ) ) );
readConfig();
getAddress();
}
AddressBookPluginWidget::~AddressBookPluginWidget() {
delete m_contactdb;
}
void AddressBookPluginWidget::refresh( const OContactAccess* )
{
qWarning(" AddressBookPluginWidget::Database was changed externally ! ");
m_contactdb->reload();
getAddress();
}
+void AddressBookPluginWidget::reinitialize() {
+ readConfig();
+ getAddress();
+}
void AddressBookPluginWidget::readConfig() {
Config cfg( "todayaddressplugin" );
cfg.setGroup( "config" );
m_maxLinesTask = cfg.readNumEntry( "maxlinestask", 5 );
m_maxCharClip = cfg.readNumEntry( "maxcharclip", 38 );
m_daysLookAhead = cfg.readNumEntry( "dayslookahead", 14 );
m_urgentDays = cfg.readNumEntry( "urgentdays", 7 );
m_entryColor = cfg.readEntry("entrycolor", Qt::black.name() );
m_headlineColor = cfg.readEntry( "headlinecolor", Qt::black.name() );
m_urgentColor = cfg.readEntry( "urgentcolor", Qt::red.name() );
m_showBirthdays = cfg.readBoolEntry( "showBirthdays", true );
m_showAnniversaries = cfg.readBoolEntry( "showAnniversaries", true );
}
/**
* Get the addresss
*/
void AddressBookPluginWidget::getAddress() {
if ( ! layoutTodo ){
layoutTodo = new QVBoxLayout( this );
}
if ( ! addressLabel ) {
addressLabel = new OClickableLabel( this );
connect( addressLabel, SIGNAL( clicked() ), this, SLOT( startAddressBook() ) );
layoutTodo->addWidget( addressLabel );
}
QString output;
// Check whether the database provide the search option..
- // The following if-statement was replaced due to a bug in some
- // implementations of libopie. The replacement should work everywhere..(eilers)
- // if ( !m_contactdb->hasQuerySettings( OContactAccess::DateDiff ) ){
- if ( !( m_contactdb->querySettings() & OContactAccess::DateDiff ) ){
+ if ( !m_contactdb->hasQuerySettings( OContactAccess::DateDiff ) ){
// Libopie seems to be old..
output = QObject::tr( "Database does not provide this search query ! Please upgrade libOpie !<br>" );
addressLabel->setText( output );
return;
}
// Define the query for birthdays and start search..
QDate lookAheadDate = QDate::currentDate().addDays( m_daysLookAhead );
int ammount = 0;
if ( m_showBirthdays ){
qWarning("Searching from now (%s) until %s ! ",
QDate::currentDate().toString().latin1(),
lookAheadDate.toString().latin1() );
+
OContact querybirthdays;
querybirthdays.setBirthday( lookAheadDate );
-
m_list = m_contactdb->queryByExample( querybirthdays,
OContactAccess::DateDiff );
if ( m_list.count() > 0 ){
output = "<font color=" + m_headlineColor + ">"
+ QObject::tr( "Next birthdays in <b> %1 </b> days:" )
.arg( m_daysLookAhead )
+ "</font> <br>";
for ( m_it = m_list.begin(); m_it != m_list.end(); ++m_it ) {
if ( ammount++ < m_maxLinesTask ){
// Now we want to calculate how many days
//until birthday. We have to set
// the correct year to calculate the day diff...
QDate destdate = (*m_it).birthday();
destdate.setYMD( QDate::currentDate().year(),
destdate.month(), destdate.day() );
if ( QDate::currentDate().daysTo(destdate) < 0 )
destdate.setYMD( QDate::currentDate().year()+1,
destdate.month(), destdate.day() );
if ( QDate::currentDate().daysTo(destdate) < m_urgentDays )
output += "<font color=" + m_urgentColor + "><b>-"
+ (*m_it).fullName()
+ " ("
+ QString::number(QDate::currentDate()
.daysTo(destdate))
+ " Days) </b></font><br>";
else
output += "<font color=" + m_entryColor + "><b>-"
+ (*m_it).fullName()
+ " ("
+ QString::number(QDate::currentDate()
.daysTo(destdate))
+ " Days) </b></font><br>";
}
}
} else {
output = "<font color=" + m_headlineColor + ">"
+ QObject::tr( "No birthdays in <b> %1 </b> days!" )
.arg( m_daysLookAhead )
+ "</font> <br>";
}
}
if ( m_showAnniversaries ){
// Define the query for anniversaries and start search..
OContact queryanniversaries;
queryanniversaries.setAnniversary( lookAheadDate );
m_list = m_contactdb->queryByExample( queryanniversaries, OContactAccess::DateDiff );
ammount = 0;
if ( m_list.count() > 0 ){
output += "<font color=" + m_headlineColor + ">"
+ QObject::tr( "Next anniversaries in <b> %1 </b> days:" )
.arg( m_daysLookAhead )
+ "</font> <br>";
for ( m_it = m_list.begin(); m_it != m_list.end(); ++m_it ) {
if ( ammount++ < m_maxLinesTask ){
// Now we want to calculate how many days until anniversary.
// We have to set the correct year to calculate the day diff...
QDate destdate = (*m_it).anniversary();
destdate.setYMD( QDate::currentDate().year(), destdate.month(),
destdate.day() );
if ( QDate::currentDate().daysTo(destdate) < 0 )
destdate.setYMD( QDate::currentDate().year()+1,
destdate.month(), destdate.day() );
if ( QDate::currentDate().daysTo(destdate) < m_urgentDays )
output += "<font color=" + m_urgentColor + "><b>-"
+ (*m_it).fullName()
+ " ("
+ QString::number(QDate::currentDate()
.daysTo( destdate ) )
+ " Days) </b></font><br>";
else
output += "<font color=" + m_entryColor + "><b>-"
+ (*m_it).fullName()
+ " ("
+ QString::number(QDate::currentDate()
.daysTo( destdate ) )
+ " Days) </b></font><br>";
}
}
} else {
output += "<font color=" + m_headlineColor + ">"
+ QObject::tr( "No anniversaries in <b> %1 </b> days!" )
.arg( m_daysLookAhead )
+ "</font> <br>";
}
}
addressLabel->setText( output );
}
diff --git a/core/pim/today/plugins/addressbook/addresspluginwidget.h b/core/pim/today/plugins/addressbook/addresspluginwidget.h
index cf2ecce..b0e3811 100644
--- a/core/pim/today/plugins/addressbook/addresspluginwidget.h
+++ b/core/pim/today/plugins/addressbook/addresspluginwidget.h
@@ -1,65 +1,66 @@
/*
* addresspluginwidget.h
*
* copyright : (c) 2003 by Stefan Eilers
* email : eilers.stefan@epost.de
*
* This implementation was derived from the todolist plugin implementation
*
*/
/***************************************************************************
* *
* 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 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef ADDRESSBOOK_PLUGIN_WIDGET_H
#define ADDRESSBOOK_PLUGIN_WIDGET_H
#include <qstring.h>
#include <qwidget.h>
#include <qlayout.h>
#include <opie/ocontactaccess.h>
#include <opie/oclickablelabel.h>
class AddressBookPluginWidget : public QWidget {
Q_OBJECT
public:
AddressBookPluginWidget( QWidget *parent, const char *name );
~AddressBookPluginWidget();
+ void reinitialize();
public slots:
void refresh( const OContactAccess* db );
protected slots:
void startAddressBook();
private:
OClickableLabel* addressLabel;
QVBoxLayout* layoutTodo;
OContactAccess * m_contactdb;
OContactAccess::List m_list;
OContactAccess::List::Iterator m_it;
void readConfig();
void getAddress();
int m_maxLinesTask;
int m_maxCharClip;
int m_daysLookAhead;
int m_urgentDays;
QString m_entryColor;
QString m_headlineColor;
QString m_urgentColor;
bool m_showBirthdays;
bool m_showAnniversaries;
};
#endif
diff --git a/core/pim/today/plugins/addressbook/opie-today-addressbookplugin.control b/core/pim/today/plugins/addressbook/opie-today-addressbookplugin.control
index 9fe23b6..1876eb8 100644
--- a/core/pim/today/plugins/addressbook/opie-today-addressbookplugin.control
+++ b/core/pim/today/plugins/addressbook/opie-today-addressbookplugin.control
@@ -1,9 +1,9 @@
Package: opie-today-addressbookplugin
Files: plugins/today/libtodayaddressbookplugin.so*
Priority: optional
Section: opie/applications
Maintainer: Stefan Eilers <eilers.stefan@epost.de>
Architecture: arm
-Version: $QPE_VERSION-$SUB_VERSION
Depends: libqte2, opie-today
Description: Addressbook plugin for today shows Birthdays and Anniversaries
+Version: $QPE_VERSION$EXTRAVERSION