/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include "basewidget.h"
#include <QRect>
#include <QPainter>
#include <QPainterPath>
#include <QPolygon>
#include <hbgridview.h>
#include <QStandardItemModel>
#include <HbScrollArea>
#include <QPalette>
#include <QImage>
#include <QColor>
#include <HbInstance>
#include <f32file.h>
#include <qglobal.h>
const int KDataDataSize = 2*1024*1024; // 2 MB
const int KThumbDataSize = 10; // 10 B
const int KMaxHeapMem = 16*1024*1024; // 16 MB
basewidget::basewidget(QObject* activityStorage, QObject* activityManager, QTextStream* stream, QGraphicsItem *parent)
: HbWidget(parent), mActivityStorage(activityStorage), mActivityManager(activityManager), mStream(stream),
mPixmap(NULL),mByteArray(NULL),
mSaveVariant(NULL), mSaveMetadata(NULL),
mAlloc(0)
{
mSaveButton = new HbPushButton("Save");
mThumbButton = new HbPushButton("Thumb");
mDataButton = new HbPushButton("Data");
mKBytesEdid = new HbLineEdit("1024");
mKBytesEdid->setObjectName("KBytesEditLine");
mQKBytesValidator = new QIntValidator(this);
mQKBytesValidator->setRange(40, KMaxHeapMem);
mKBytesValidator = new HbValidator(this);
mKBytesValidator->addField(mQKBytesValidator, "3000");
mKBytesEdid->setValidator(mKBytesValidator);
mStatusValueLabel = new HbLabel("None status, none message");
mBytesEditLabel = new HbLabel("Free KBytes[KB]");
mCatchLabel = new HbLabel("Catches");
mGridLayout = new QGraphicsGridLayout();
mGridLayout->addItem(mStatusValueLabel, 0, 0, 1, 6);
mGridLayout->addItem(mCatchLabel, 1, 0, 1, 6);
mGridLayout->addItem(mBytesEditLabel, 2, 0, 1, 2);
mGridLayout->addItem(mKBytesEdid, 2, 2, 1, 4);
mGridLayout->addItem(mSaveButton, 3, 0, 1, 2);
mGridLayout->addItem(mDataButton, 3, 2, 1, 2);
mGridLayout->addItem(mThumbButton, 3, 4, 1, 2);
setLayout(mGridLayout);
connect(mSaveButton, SIGNAL(released()), this, SLOT(save()));
connect(mThumbButton, SIGNAL(released()), this, SLOT(thumb()));
connect(mDataButton, SIGNAL(released()), this, SLOT(data()));
}
basewidget::~basewidget()
{
delete mQKBytesValidator;
delete mKBytesValidator;
}
int basewidget::Bytes() const
{
int kb = Edit2Int(mKBytesEdid);
return kb*1024;
}
int basewidget::Edit2Int(const HbLineEdit* lineedit) const
{
int retvalue = 0;
bool ok = false;
QString edittext = lineedit->text();
retvalue = edittext.toInt(&ok);
if(ok) {
return retvalue;
}
return 0;
}
void basewidget::prepareDataSave()
{
clearSaveData();
int bytes = KDataDataSize;
mByteArray = new QByteArray(bytes, 'a');
HbMainWindow *mainWindow = hbInstance->allMainWindows().first();
mPixmap = new QPixmap(QPixmap::grabWidget(mainWindow, mainWindow->rect()));
mSaveVariant = new QVariant;
*mSaveVariant = *mByteArray;
delete mByteArray;
mByteArray = NULL;
mSaveMetadata = new QVariantHash;
mSaveMetadata->insert(ActivityScreenshotKeyword, *mPixmap);
delete mPixmap;
mPixmap = NULL;
}
void basewidget::prepareThumbSave()
{
clearSaveData();
int bytes = KThumbDataSize;
mByteArray = new QByteArray(bytes, 'a');
QImage img = QImage(1000, 1000, QImage::Format_ARGB32);
img.fill(1);
for( int i=0; i<img.width(); i++) {
for(int j=0; j<img.height(); j++) {
int index = i*j;
img.setPixel(i, j, qRgba((10*index+104*i)%255, (200*index+6*j)%255, (150*index+34*i)%255, (80*index+40*j)%255));
}
}
mPixmap = new QPixmap(QPixmap::fromImage(img));
bool ok = mPixmap->save("c:\\ala.bmp");
mSaveVariant = new QVariant;
*mSaveVariant = *mByteArray;
delete mByteArray;
mByteArray = NULL;
mSaveMetadata = new QVariantHash;
mSaveMetadata->insert(ActivityScreenshotKeyword, *mPixmap);
delete mPixmap;
mPixmap = NULL;
}
void basewidget::clearSaveData()
{
delete mByteArray;
mByteArray = NULL;
delete mPixmap;
mPixmap = NULL;
delete mSaveVariant;
mSaveVariant = NULL;
delete mSaveMetadata;
mSaveMetadata = NULL;
}
bool basewidget::saveActivity(int name)
{
QString display;
display.setNum(name);
mSaveMetadata->insert(ActivityApplicationName, display);
bool retok, ok;
try {
ok = QMetaObject::invokeMethod(mActivityStorage, "saveActivity", Q_RETURN_ARG(bool, retok), Q_ARG(QString, display), Q_ARG(QVariant, *mSaveVariant), Q_ARG(QVariantHash, *mSaveMetadata));
}
catch(...) {
logCatchError("save");
return false;
}
return ok && retok;
}
bool basewidget::removeActivity(const QString& name)
{
bool retok, ok;
try {
ok = QMetaObject::invokeMethod(mActivityStorage, "removeActivity", Q_RETURN_ARG(bool, retok), Q_ARG(QString, name));
}
catch(...) {
logCatchError("remove");
return false;
}
return ok && retok;
}
bool basewidget::activities()
{
bool ok;
try {
ok = QMetaObject::invokeMethod(mActivityStorage, "allActivities", Q_RETURN_ARG(QStringList, mActivities));
}
catch(...) {
logCatchError("activities");
return false;
}
return ok;
}
bool basewidget::privateData(const QString& name)
{
QVariant data;
bool ok;
try {
ok = QMetaObject::invokeMethod(mActivityStorage, "activityData", Q_RETURN_ARG(QVariant, data), Q_ARG(QString, name));
}
catch(...) {
logCatchError("data");
return false;
}
const char* type = data.typeName();
QString dtype(type);
logDataType(dtype);
return ok;
}
bool basewidget::getThumbnail(const QString& name)
{
QVariantHash metadata;
bool ok;
try {
ok = QMetaObject::invokeMethod(mActivityStorage, "activityMetaData", Q_RETURN_ARG(QVariantHash, metadata), Q_ARG(QString, name));
}
catch(...) {
logCatchError("thumbnail");
return false;
}
if(!ok) {
return false;
}
QString pixfile = metadata.value(ActivityScreenshotKeyword).toString();
ok = QMetaObject::invokeMethod(mActivityManager, "getThumbnail", Q_ARG(QSize, QSize(1000, 1000)), Q_ARG(QString, pixfile), Q_ARG(void*, NULL));
return ok;
}
int basewidget::ClientHeapSize()
{
RHeap& heap = User::Heap();
TInt all=0;
heap.AllocSize(all);
return all;
}
void basewidget::logErrorMessage(const QString& mess)
{
QString messlog("*Fail: ");
messlog += mess;
messlog += "*\n";
*mStream<<messlog;
mStream->flush();
mStatusValueLabel->setPlainText("Fail");
}
void basewidget::releaseMem()
{
mActivities.clear();
clearSaveData();
releaseAlloced();
}
void basewidget::save()
{
releaseMem();
bool ok = removeActivity("0");
logAction("save");
prepareDataSave();
alloc();
ok = saveActivity(0);
releaseMem();
logSaveResult(ok);
}
void basewidget::thumb()
{
releaseMem();
disconnect( mActivityManager, SIGNAL(thumbnailReady(QPixmap, void *)), this, SLOT(thumbnailReady(QPixmap, void *)) );
bool ok = removeActivity("0");
logAction("thumb");
prepareThumbSave();
ok = saveActivity(0);
if(!ok) {
logErrorMessage("save");
return;
}
clearSaveData();
ok = activities();
if(!ok || mActivities.count()==0) {
logErrorMessage("activities");
return;
}
QString name = mActivities.at(0);
alloc();
ok = getThumbnail(name);
if(!ok) {
logErrorMessage("getthumb");
return;
}
connect( mActivityManager, SIGNAL(thumbnailReady(QPixmap, void *)), this, SLOT(thumbnailReady(QPixmap, void *)) );
}
void basewidget::data()
{
releaseMem();
bool ok = removeActivity("0");
logAction("data");
prepareDataSave();
ok = saveActivity(0);
if(!ok) {
logErrorMessage("save");
return;
}
ok = activities();
if(!ok || mActivities.count()==0) {
logErrorMessage("activities");
return;
}
QString name = mActivities.at(0);
alloc();
ok = privateData(name);
if(!ok) {
logErrorMessage("data");
return;
}
releaseMem();
}
void basewidget::thumbnailReady(QPixmap pixmap, void* ptr)
{
releaseMem();
disconnect( mActivityManager, SIGNAL(thumbnailReady(QPixmap, void *)), this, SLOT(thumbnailReady(QPixmap, void *)) );
logPixmapSize(pixmap);
}
void basewidget::logCatchError(const QString& mess)
{
QString msg = tr("Catch err: %1").arg(mess);
mCatchLabel->setPlainText(msg);
*mStream<<msg<<"\n";
mStream->flush();
}
void basewidget::logDataType(const QString& type)
{
QString msg = tr("Data type: %1").arg(type);
mStatusValueLabel->setPlainText(msg);
*mStream<<msg<<"\n";
mStream->flush();
}
void basewidget::logPixmapSize(const QPixmap& pix)
{
QSize s = pix.size();
QString msg = tr("Pix size: %1x%2").arg(s.width()).arg(s.height());
mStatusValueLabel->setPlainText(msg);
*mStream<<msg<<"\n";
mStream->flush();
}
void basewidget::logAction(const QString& mess)
{
mStatusValueLabel->clear();
mCatchLabel->clear();
QString msg = tr("Action: %1").arg(mess);
*mStream<<msg<<"\n";
QString bytemsg = tr("Free Bytes: %1").arg(Bytes());
*mStream<<bytemsg<<"\n";
mStream->flush();
}
void basewidget::logSaveResult(bool res)
{
QString msg = tr("Save: %1").arg(res);
mStatusValueLabel->setPlainText(msg);
*mStream<<msg<<"\n";
mStream->flush();
}
bool basewidget::alloc()
{
releaseAlloced();
int tobefreebytes = Bytes();
int all = ClientHeapSize();
int nowfree = KMaxHeapMem - all;
int toalloc = nowfree - tobefreebytes;
bool ok = false;
if( toalloc>=0 ) {
ok = true;
try {
mAlloc = new char[toalloc];
}
catch(...) {
ok = false;
}
}
if(!mAlloc) {
ok = false;
}
if(!ok) {
QString msg = tr("Alloc Failed");
mCatchLabel->setPlainText(msg);
*mStream<<msg<<"\n";
mStream->flush();
}
return ok;
}
void basewidget::releaseAlloced()
{
delete mAlloc;
mAlloc = NULL;
}