[kde-doc-english] [calligra] kexi/main: GUI: prototype of welcome status bar
Jaroslaw Staniek
staniek at kde.org
Sat Feb 18 23:02:42 UTC 2012
Git commit 59036e061ab35277fe7c0254234ec8f1374a3517 by Jaroslaw Staniek.
Committed on 23/01/2012 at 23:43.
Pushed by staniek into branch 'master'.
GUI: prototype of welcome status bar
feedback format++: added JSON-compatible character escaping; added uid
M +1 -0 kexi/main/CMakeLists.txt
M +47 -4 kexi/main/KexiUserFeedbackAgent.cpp
M +11 -2 kexi/main/startup/KexiWelcomeAssistant.cpp
M +2 -0 kexi/main/startup/KexiWelcomeAssistant.h
A +200 -0 kexi/main/startup/KexiWelcomeStatusBar.cpp [License: LGPL (v2+)]
A +48 -0 kexi/main/startup/KexiWelcomeStatusBar.h [License: LGPL (v2+)]
http://commits.kde.org/calligra/59036e061ab35277fe7c0254234ec8f1374a3517
diff --git a/kexi/main/CMakeLists.txt b/kexi/main/CMakeLists.txt
index 40e883b..1c1f3d6 100644
--- a/kexi/main/CMakeLists.txt
+++ b/kexi/main/CMakeLists.txt
@@ -26,6 +26,7 @@ KexiUserFeedbackAgent.cpp
startup/KexiNewProjectAssistant.cpp
startup/KexiOpenProjectAssistant.cpp
startup/KexiWelcomeAssistant.cpp
+startup/KexiWelcomeStatusBar.cpp
startup/KexiImportExportAssistant.cpp
startup/KexiStartupFileHandler.cpp
startup/KexiStartupDialog.cpp
diff --git a/kexi/main/KexiUserFeedbackAgent.cpp b/kexi/main/KexiUserFeedbackAgent.cpp
index 083f748..2ecee1d 100644
--- a/kexi/main/KexiUserFeedbackAgent.cpp
+++ b/kexi/main/KexiUserFeedbackAgent.cpp
@@ -25,13 +25,21 @@
#include <KIO/Job>
#include <KLocale>
#include <KDebug>
+#include <KConfigGroup>
#include <QPair>
#include <QApplication>
#include <QDesktopWidget>
#include <QProcess>
+#include <QUuid>
-static const char userFeedbackUrl[] = "http://www.kexi-project.org/feedback/send";
+//! Version of feedback data format.
+//! Changelog:
+//! *1.0: initial version
+//! *1.1: added JSON-compatible character escaping; added uid
+static const char KexiUserFeedbackAgent_VERSION[] = "1.1";
+
+static const char KexiUserFeedbackAgent_URL[] = "http://www.kexi-project.org/feedback/send";
typedef QPair<QByteArray, QVariant> DataPair;
@@ -44,13 +52,27 @@ public:
}
bool enabled;
QList<DataPair> data;
+ //! Unique user ID handy if used does not want to disclose username
+ //! but agrees to be identified as unique user of the application.
+ QUuid uid;
};
KexiUserFeedbackAgent::KexiUserFeedbackAgent(QObject* parent)
: QObject(parent), d(new Private)
{
+ KConfigGroup configGroup(KGlobal::config()->group("User Feedback"));
+
+ // load or create uid
+ QString uidString = configGroup.readEntry("uid", QString());
+ d->uid = QUuid(uidString);
+ if (d->uid.isNull()) {
+ d->uid = QUuid::createUuid();
+ configGroup.writeEntry("uid", d->uid.toString());
+ }
+
#define ADD(a, b) d->data.append(qMakePair(QByteArray(a), QVariant(b)))
- ADD("ver", "1.0");
+ ADD("ver", KexiUserFeedbackAgent_VERSION);
+ ADD("uid", d->uid.toString());
ADD("app_ver", Kexi::versionString());
ADD("app_ver_major", Kexi::versionMajor());
ADD("app_ver_minor", Kexi::versionMinor());
@@ -116,6 +138,26 @@ void KexiUserFeedbackAgent::setEnabled(bool enabled)
d->enabled = enabled;
}
+//! Escapes string for json format (see http://json.org/string.gif).
+inline QString escapeJson(const QString& s)
+{
+ QString res;
+ for (int i=0; i<s.length(); i++) {
+ switch (s[i].toLatin1()) {
+ case '\\': res += QLatin1String("\\\\"); break;
+ case '/': res += QLatin1String("\\/"); break;
+ case '"': res += QLatin1String("\\\""); break;
+ case '\b': res += QLatin1String("\\b"); break;
+ case '\f': res += QLatin1String("\\f"); break;
+ case '\n': res += QLatin1String("\\n"); break;
+ case '\r': res += QLatin1String("\\r"); break;
+ case '\t': res += QLatin1String("\\t"); break;
+ default: res += s[i];
+ }
+ }
+ return res;
+}
+
void KexiUserFeedbackAgent::sendData()
{
QByteArray postData;
@@ -124,11 +166,12 @@ void KexiUserFeedbackAgent::sendData()
postData += ',';
}
postData += (QByteArray("\"") + item.first + "\":\""
- + item.second.toString().toUtf8() + '"');
+ + escapeJson(item.second.toString()).toUtf8() + '"');
}
+ kDebug() << postData;
KIO::Job* sendJob = KIO::storedHttpPost(
- postData, KUrl(userFeedbackUrl), KIO::HideProgressInfo);
+ postData, KUrl(KexiUserFeedbackAgent_URL), KIO::HideProgressInfo);
connect(sendJob, SIGNAL(finished(KJob*)), this, SLOT(sendJobFinished(KJob*)));
sendJob->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded");
}
diff --git a/kexi/main/startup/KexiWelcomeAssistant.cpp b/kexi/main/startup/KexiWelcomeAssistant.cpp
index 6f2a60f..9f0c9ed 100644
--- a/kexi/main/startup/KexiWelcomeAssistant.cpp
+++ b/kexi/main/startup/KexiWelcomeAssistant.cpp
@@ -1,5 +1,5 @@
/* This file is part of the KDE project
- Copyright (C) 2011 Jarosław Staniek <staniek at kde.org>
+ Copyright (C) 2011-2012 Jarosław Staniek <staniek at kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -20,6 +20,7 @@
#include "KexiWelcomeAssistant.h"
#include "KexiRecentProjectsModel.h"
+#include "KexiWelcomeStatusBar.h"
#include <core/kexi.h>
#include <core/KexiRecentProjects.h>
@@ -66,7 +67,11 @@ KexiMainWelcomePage::KexiMainWelcomePage(
{
connect(this, SIGNAL(openProject(KexiProjectData,QString,bool*)),
assistant, SIGNAL(openProject(KexiProjectData,QString,bool*)));
+ QWidget* contents = new QWidget;
+ QHBoxLayout* contentsLyr = new QHBoxLayout(contents);
+
m_recentProjects = new KexiCategorizedView;
+ contentsLyr->addWidget(m_recentProjects, 1);
//m_recentProjects->setItemDelegate(new KFileItemDelegate(this));
setFocusWidget(m_recentProjects);
m_recentProjects->setFrameShape(QFrame::NoFrame);
@@ -77,7 +82,11 @@ KexiMainWelcomePage::KexiMainWelcomePage(
m_recentProjects->setSpacing(margin);
m_recentProjects->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
connect(m_recentProjects, SIGNAL(clicked(QModelIndex)), this, SLOT(slotItemClicked(QModelIndex)));
- setContents(m_recentProjects);
+
+ m_statusBar = new KexiWelcomeStatusBar;
+ contentsLyr->addWidget(m_statusBar);
+
+ setContents(contents);
QTimer::singleShot(100, this, SLOT(loadProjects()));
}
diff --git a/kexi/main/startup/KexiWelcomeAssistant.h b/kexi/main/startup/KexiWelcomeAssistant.h
index 98319cc..a8d892d 100644
--- a/kexi/main/startup/KexiWelcomeAssistant.h
+++ b/kexi/main/startup/KexiWelcomeAssistant.h
@@ -34,6 +34,7 @@ class KexiProjectSelectorWidget;
class KCategorizedView;
class KexiWelcomeAssistant;
class KexiRecentProjectsProxyModel;
+class KexiWelcomeStatusBar;
class KexiMainWelcomePage : public KexiAssistantPage
{
@@ -55,6 +56,7 @@ private:
KexiCategorizedView* m_recentProjects;
KexiRecentProjectsProxyModel* m_recentProjectsProxyModel;
KexiWelcomeAssistant* m_assistant;
+ KexiWelcomeStatusBar* m_statusBar;
};
class KexiProjectData;
diff --git a/kexi/main/startup/KexiWelcomeStatusBar.cpp b/kexi/main/startup/KexiWelcomeStatusBar.cpp
new file mode 100644
index 0000000..384de2f
--- /dev/null
+++ b/kexi/main/startup/KexiWelcomeStatusBar.cpp
@@ -0,0 +1,200 @@
+/* This file is part of the KDE project
+ Copyright (C) 2011-2012 Jarosław Staniek <staniek at kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "KexiWelcomeStatusBar.h"
+#include <kexiutils/utils.h>
+
+#include <KTextBrowser>
+#include <KGlobalSettings>
+#include <KIconLoader>
+#include <KColorUtils>
+#include <KColorScheme>
+#include <KStandardDirs>
+#include <KDebug>
+
+#include <QLayout>
+#include <QProgressBar>
+#include <QtCore/qmath.h>
+
+#define HEADER_SIZE 1.0
+
+class KexiStatusTextDocument : public QTextDocument
+{
+public:
+ KexiStatusTextDocument(KexiWelcomeStatusBar* parent) : QTextDocument(parent),
+ m_parent(parent)
+ {
+ // http://www.qtcentre.org/wiki/index.php?title=QTextBrowser_with_images_and_CSS
+ qreal fontSize = qFloor(
+ (KGlobalSettings::smallestReadableFont().pointSizeF()
+ + m_parent->font().pointSizeF())
+ / 2.0);
+ KColorScheme colorScheme(m_parent->palette().currentColorGroup());
+ QString css =
+ QString("* { font-size:%1pt; color:%2; } ")
+ .arg(fontSize).arg(m_parent->palette().color(QPalette::Text).name())
+ + QString(".gray, .gray * { color:%1; } ")
+ .arg(KColorUtils::mix(m_parent->palette().color(QPalette::Text),
+ m_parent->palette().color(QPalette::Base), 0.5).name())
+ + "img.icon { vertical-align:bottom; } "
+ //+ "body { background-color:yellow; } "
+ + "p { text-indent:0px; } "
+ + QString("*.head { text-indent:0px; font-size:%1pt; font-weight:bold; } ").arg(
+ m_parent->font().pointSizeF() * HEADER_SIZE)
+ + QString("a, a * { color:%1; } ")
+ .arg(colorScheme.foreground(KColorScheme::LinkText).color().name());
+ addResource(QTextDocument::StyleSheetResource, QUrl( "format.css" ), css);
+ }
+protected:
+ virtual QVariant loadResource(int type, const QUrl &name)
+ {
+ if (type == QTextDocument::ImageResource) {
+ if (name.scheme() == QLatin1String("kicon")) {
+ return KIconLoader::global()->loadIcon(name.host(), KIconLoader::NoGroup, 16);
+ }
+ else if (name.scheme() == "feedbackdata") {
+ if (name.host() == "progress") {
+ return m_parent->userProgressPixmap();
+ }
+ }
+ else if (name.toString() == "ext") {
+ return m_parent->externalLinkPixmap();
+ }
+ }
+ return QTextDocument::loadResource(type, name);
+ }
+private:
+ KexiWelcomeStatusBar *m_parent;
+};
+
+//---
+
+class KexiWelcomeStatusBar::Private
+{
+public:
+ Private(KexiWelcomeStatusBar* _q)
+ : q(_q)
+ {
+ }
+
+ KTextBrowser *statusBrowser;
+ QProgressBar userProgressBar;
+ QVBoxLayout *lyr;
+ QPixmap externalLinkPixmap;
+private:
+ KexiWelcomeStatusBar *q;
+};
+
+KexiWelcomeStatusBar::KexiWelcomeStatusBar(QWidget* parent)
+ : QWidget(parent), d(new Private(this))
+{
+ d->lyr = new QVBoxLayout(this);
+ d->userProgressBar.setTextVisible(false);
+ setUserProgress(5);
+
+ init();
+}
+
+KexiWelcomeStatusBar::~KexiWelcomeStatusBar()
+{
+ delete d;
+}
+
+void KexiWelcomeStatusBar::init()
+{
+ QString title("You in Kexi Project"); // Your Status in Kexi Project
+ QString html = QString(
+ "<p><span class=\"head\">%1</span> <a class='gray' href='feedback://help_your_status'>(?)</a></p>"
+ "<p><img src='feedbackdata://progress'> <b>%2%</b> involved</p>"
+ "<p><b>Contribute</b> <a class='gray' href='feedback://help_why_contribute'>(Why?)</a></p>"
+ "<p><img src=\"kicon://list-add\"> <a href='feedback://show_share_usage_info'>Share Usage Info</a> <span class='gray'>(+5%)</span></p>"
+ ).arg(title).arg(d->userProgressBar.value());
+
+ d->statusBrowser = new KTextBrowser;
+ d->statusBrowser->setFrameShape(QFrame::NoFrame);
+ d->statusBrowser->setTextInteractionFlags(Qt::LinksAccessibleByMouse|Qt::LinksAccessibleByKeyboard);
+ d->lyr->addWidget(d->statusBrowser);
+
+ KexiStatusTextDocument *doc = new KexiStatusTextDocument(this);
+
+ QFont f(d->statusBrowser->font());
+ f.setBold(true);
+ f.setPointSizeF(f.pointSizeF() * HEADER_SIZE);
+ d->statusBrowser->setFixedWidth(QFontMetrics(f).width(title + "(?)_____"));
+ d->userProgressBar.setFixedSize(
+ d->statusBrowser->minimumWidth() - QFontMetrics(f).width("888% involved"),
+ fontMetrics().height());
+ //statusDoc->addResource(QTextDocument::ImageResource, QUrl( "bg.png" ), QPixmap(":bg"));
+
+ title = "What's New?";
+ // <img src='ext'>
+ html += QString(
+ "<br>"
+ "<p><b class=\"head\">%1</b></p>"
+ "<p><a href=\"newsdata://0\"> Fruits of CSS2: Office Forms</a></p>"
+ "<p align=\"right\"><a href=\"newsdata://show_all\">See all <b>News</b> »</a></p>"
+ ).arg(title);
+
+ title = "Recent Releases";
+ html += QString(
+ "<br>"
+ "<p><b class=\"head\">%1</b></p>"
+ "<p><table>"
+ "<tr><td><p>Stable release: </p></td><td><a href=\"http://www.koffice.org/news/announcements/koffice-2-3-3-update/\">2.3.3</a></td></tr>"
+ "<tr><td><p>Preview release: </p></td><td><a href=\"http://www.calligra.org/news/announcements/calligra-2-4-beta-6/\">2.4 Beta 6</a></td></tr>"
+ "</table></p>"
+ "<p align=\"right\"><a href=\"newsdata://show_all\">See more <b>Releases</b> »</a></p>"
+ ).arg(title);
+
+ QString htmlHead(QLatin1String(
+ "<html><head>"
+ "<link rel='stylesheet' type='text/css' href='format.css'>"
+ "</head><body>"));
+ doc->setHtml(htmlHead + html + "</body></html>");
+ d->statusBrowser->setDocument(doc);
+ kDebug() << d->statusBrowser->toHtml();
+}
+
+void KexiWelcomeStatusBar::setUserProgress(int progress)
+{
+ d->userProgressBar.setValue(progress);
+}
+
+QPixmap KexiWelcomeStatusBar::userProgressPixmap()
+{
+ QPixmap px(d->userProgressBar.size());
+ px.fill(Qt::transparent);
+ QPainter p(&px);
+ p.setOpacity(0.5);
+ d->userProgressBar.render(&p);
+ return px;
+}
+
+QPixmap KexiWelcomeStatusBar::externalLinkPixmap()
+{
+ if (d->externalLinkPixmap.isNull()) {
+ d->externalLinkPixmap = QPixmap(
+ KStandardDirs::locate("data", "kexi/pics/external-link.png"));
+ KColorScheme colorScheme(palette().currentColorGroup());
+ QColor c(colorScheme.foreground(KColorScheme::LinkText).color());
+ c.setAlpha(100);
+ KexiUtils::replaceColors(&d->externalLinkPixmap, c);
+ }
+ return d->externalLinkPixmap;
+}
diff --git a/kexi/main/startup/KexiWelcomeStatusBar.h b/kexi/main/startup/KexiWelcomeStatusBar.h
new file mode 100644
index 0000000..f2fb1ab
--- /dev/null
+++ b/kexi/main/startup/KexiWelcomeStatusBar.h
@@ -0,0 +1,48 @@
+/* This file is part of the KDE project
+ Copyright (C) 2012 Jarosław Staniek <staniek at kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KEXIWELCOMESTATUSBAR_H
+#define KEXIWELCOMESTATUSBAR_H
+
+#include <QWidget>
+
+//! Status sidebar for the welcome page
+class KexiWelcomeStatusBar : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit KexiWelcomeStatusBar(QWidget* parent = 0);
+ ~KexiWelcomeStatusBar();
+
+ QPixmap userProgressPixmap();
+ QPixmap externalLinkPixmap();
+
+signals:
+
+private slots:
+
+private:
+ void setUserProgress(int progress);
+ void init();
+
+ class Private;
+ Private * const d;
+};
+
+#endif
More information about the kde-doc-english
mailing list