diff -r 454d022d514b -r aefcba28a3e0 piprofilerui/ui/hb/src/pimainview.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piprofilerui/ui/hb/src/pimainview.cpp Tue May 25 12:43:15 2010 +0300 @@ -0,0 +1,565 @@ +/* +* Copyright (c) 2010 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pimainview.h" +#include "piprofilerengine.h" +#include "notifications.h" +#include "pimainwindow.h" + +const char *INVALIDCONFIGURATIONFILE = "Invalid configuration file"; +const char *APPLICATIONNAME = "PI Profiler"; + +// actions that are found from xml +const char *ACTIONEXIT = "actionExit"; +const char *ACTIONSTARTPROFILING = "actionStartProfiling"; +const char *ACTIONSTARTTIMEDPROFILING = "actionStartTimedProfiling"; +const char *ACTIONSETTINGS = "actionSettings"; +const char *ACTIONABOUT = "actionAbout"; + +// UI components that are found from xml + +const char *LISTWIDGETPLUGINS = "listPlugins"; +const char *TEXTMANDATORYPLUGINS = "Mandatory plug-ins:"; +const char *TEXTOPTIONALPLUGINS = "Optional plug-ins:"; + +// --------------------------------------------------------------------------- + +PIMainView::PIMainView() : + application(0), mMainWindow(0), mEngine(0), mPluginList(0), mContextMenu(0), mActionExit(0), + mActionExitAndLeaveProfilingOn(0), mActionAbout(0), mActionStartTimedProfiling(0), + mActionSettings(0), mActionStopProfiling(0), mListPlugins(0), mProfilingNote(0) +{ + +} + +// --------------------------------------------------------------------------- + +PIMainView::~PIMainView() +{ +} + +// --------------------------------------------------------------------------- + +void PIMainView::init(PIMainWindow *mainWindow, HbApplication* app, HbDocumentLoader &loader, + PIProfilerEngine *engine) +{ + + application = app; + mMainWindow = mainWindow; + + // Load items from xml file + loadItemsFromResources(loader); + + // Set list widget items + mListPlugins->setLongPressEnabled(true); + mListPlugins->setClampingStyle(HbScrollArea::BounceBackClamping); + mListPlugins->setFrictionEnabled(true); + + // Create stop profiling action + mActionStopProfiling = new HbAction("Stop Profiling", this); + + // Create exit and leave profiling on action + mActionExitAndLeaveProfilingOn = new HbAction("Close UI\n(Continue profiling)", this); + + mEngine = engine; + + // Connect signals and slots + this->connectSignalsAndSlots(app); + + // Create icons + mIconDisabled = HbIcon(":/gfx/disabled.svg"); + mIconEnabled = HbIcon(":/gfx/enabled.svg"); + + // update timed profiling text according to settings + updateTimedProfilingText(); +} + +// --------------------------------------------------------------------------- + + +void PIMainView::connectSignalsAndSlots(HbApplication* app) +{ + + // Menu items: + connect(mActionExit, SIGNAL(triggered()), app, SLOT( quit() )); + connect(mActionSettings, SIGNAL(triggered()), this, SLOT( openSettingsView() )); + connect(mActionAbout, SIGNAL(triggered()), this, SLOT( showAboutPopup() )); + connect(mActionStartProfiling, SIGNAL(triggered()), this, SLOT( startProfiling() )); + connect(mActionStartTimedProfiling, SIGNAL(triggered()), this, SLOT( startTimedProfiling() )); + + // List widget actions + connect(mListPlugins, SIGNAL(activated(HbListWidgetItem*)), this, + SLOT(enableOrDisablePlugin(HbListWidgetItem*))); + connect(mListPlugins, SIGNAL(longPressed(HbListWidgetItem*, QPointF)), this, + SLOT(showContexMenu(HbListWidgetItem*, QPointF))); + + connect( + mEngine, + SIGNAL(profilingStatusChanged(ProfilerEngineStatus, const QString&, ProfilingMode, ProfilingOutput)), + this, + SLOT(profilingStatusChanged(ProfilerEngineStatus, const QString&, ProfilingMode, ProfilingOutput))); + + connect(mMainWindow, SIGNAL(returnedFromSettings()), this, SLOT( updateTimedProfilingText() )); + connect(mActionExitAndLeaveProfilingOn, SIGNAL(triggered()), this, + SLOT( exitAndLeaveProfilingOn() )); + connect(mActionStopProfiling, SIGNAL(triggered()), this, SLOT( stopProfiling() )); + +} + +// --------------------------------------------------------------------------- + + +void PIMainView::loadItemsFromResources(HbDocumentLoader &loader) +{ + + // ACTIONS: + + // Exit + QObject *object = loader.findObject(ACTIONEXIT); + Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE); + this->mActionExit = qobject_cast (object); + + // About + object = loader.findObject(ACTIONABOUT); + Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE); + this->mActionAbout = qobject_cast (object); + + // Settings + object = loader.findObject(ACTIONSETTINGS); + Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE); + this->mActionSettings = qobject_cast (object); + + // Start profiling + object = loader.findObject(ACTIONSTARTPROFILING); + Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE); + this->mActionStartProfiling = qobject_cast (object); + + // Start timed profiling + object = loader.findObject(ACTIONSTARTTIMEDPROFILING); + Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE); + this->mActionStartTimedProfiling = qobject_cast (object); + + QGraphicsWidget *widget = loader.findWidget(LISTWIDGETPLUGINS); + Q_ASSERT_X((widget != 0), "Launcher", "Invalid launcher.xml file"); + this->mListPlugins = qobject_cast (widget); +} + +// --------------------------------------------------------------------------- + +void PIMainView::showAboutPopup() +{ + + Notifications::showMessageBox("Version 2.2.0.2 - 4th May 2010. \n" + "Copyright © 2010 Nokia Corporation " + "and/or its subsidiary(-ies). " + "All rights reserved."); + +} +// --------------------------------------------------------------------------- + +void PIMainView::setPluginList(QList *pluginList) +{ + + this->mPluginList = pluginList; + this->updatePlugInLists(); + +} + +// --------------------------------------------------------------------------- + +void PIMainView::openSettingsView() +{ + mMainWindow->activateSettingsView(); +} + +// --------------------------------------------------------------------------- + +void PIMainView::updatePlugInLists() +{ + + mListPlugins->clear(); + + // Create Compulsory and Optional labels into list widget: + HbListWidgetItem *compulsory = new HbListWidgetItem(); + compulsory->setText(TEXTMANDATORYPLUGINS); + mListPlugins->addItem(compulsory); + + HbListWidgetItem *optional = new HbListWidgetItem(); + optional->setText(TEXTOPTIONALPLUGINS); + mListPlugins->addItem(optional); + + HbIcon *icon; + + // Go thru pluginlist and add list item for each plug-in into list widget + for (int index = 0; index < mPluginList->size(); index++) { + QString plugInName = mPluginList->at(index).mName; + + // get icon for item + if (mPluginList->at(index).mEnabled) { + icon = &mIconEnabled; + } + else { + icon = &mIconDisabled; + } + + // Create list widget item + // TODO ensure that this does not leak memory + HbListWidgetItem *newItem = new HbListWidgetItem(); + newItem->setIcon(*icon); + newItem->setText(plugInName); + newItem->setData(mPluginList->at(index).mUid); + + // check if plug-in is compulsory or optional + if (mPluginList->at(index).mIsHidden) { + mListPlugins->insertItem(mListPlugins->row(optional), newItem); + } + else { + mListPlugins->addItem(newItem); + + } + } + +} +// --------------------------------------------------------------------------- + +void PIMainView::enableOrDisablePlugin(HbListWidgetItem *widget) +{ + + // if widget is not found, set currently highlighted item as widget + // (in that case this method is called from context menu) + if (widget == 0) { + widget = mListPlugins->currentItem(); + } + + // if this method is called from list widget's activated signal, do nothing + // if context menu is open. + else { + if (mContextMenu != 0) { + return; + } + } + bool ok = false; + int widgetUid = widget->data().toInt(&ok); + if (!ok) { + qWarning("PIProfiler: Unable to find plug-in uid"); + return; + } + + // go thru plug-in array and find checked plug-in + for (int index = 0; index < mPluginList->size(); index++) { + + if (mPluginList->at(index).mUid == widgetUid) { + PluginAttributes pluginAttributes = mPluginList->at(index); + + // if plug-in is hidden it cannot be disabled + if (pluginAttributes.mIsHidden) { + return; + } + + // change enable status and set icon correct + if (pluginAttributes.mEnabled) { + pluginAttributes.mEnabled = false; + widget->setIcon(mIconDisabled); + } + else { + pluginAttributes.mEnabled = true; + widget->setIcon(mIconEnabled); + } + + // save plug-in settings + if (mEngine->savePluginSettings(pluginAttributes)) { + mPluginList->replace(index, pluginAttributes); + } + else { + // if saving operation failed, revert icon back + if (pluginAttributes.mEnabled) { + widget->setIcon(mIconEnabled); + } + else { + pluginAttributes.mEnabled = true; + widget->setIcon(mIconDisabled); + } + Notifications::showErrorNote( + "Error occured while saving settings to Profiler engine."); + } + break; + } + + } + +} + +// --------------------------------------------------------------------------- + +void PIMainView::showContexMenu(HbListWidgetItem *widget, const QPointF &point) +{ + + bool ok = false; + int uid = widget->data().toInt(&ok); + + if (!ok) { + return; + } + + for (int index = 0; index < mPluginList->size(); index++) { + + if (mPluginList->at(index).mUid == uid) { + + // Create Context menu: + mContextMenu = new HbMenu(); + mContextMenu->setPreferredPos(point, HbPopup::TopLeftCorner); + mContextMenu->setDismissPolicy(HbPopup::TapOutside); + mContextMenu->setAttribute(Qt::WA_DeleteOnClose); + + // Enable/disable plug-in + if (!mPluginList->at(index).mIsHidden) { + HbAction *enableAction; + if (mPluginList->at(index).mEnabled) { + enableAction = mContextMenu->addAction(QString("Disable")); + } + else { + enableAction = mContextMenu->addAction(QString("Enable")); + } + connect(enableAction, SIGNAL(triggered()), this, SLOT( enableOrDisablePlugin() )); + } + + //FIXME take these into use once expanding and collapsing data form groups works. + // Plug-in specific settings + /*if (mPluginList->at(index).mItemCount != 0 || mPluginList->at(index).mSampleRate != -1) { + HbAction *pluginSettingsAction = mContextMenu->addAction(QString( + "Plug-in settings")); + connect(pluginSettingsAction, SIGNAL(triggered()), this, + SLOT(openPluginSpecificSettings())); + }*/ + + // Plug in info + HbAction *infoAction = mContextMenu->addAction(QString("Plug-in info")); + connect(infoAction, SIGNAL(triggered()), this, SLOT( openSampleInfo() )); + + connect(mContextMenu, SIGNAL(aboutToClose()), this, SLOT( contextMenuClosed() )); + mContextMenu->open(this, SLOT(contextMenuClosed())); + break; + } + } + +} + +// --------------------------------------------------------------------------- + +void PIMainView::openSampleInfo() +{ + + // Show plug-in specific info + bool ok = false; + int uid = mListPlugins->currentItem()->data().toInt(&ok); + if (!ok) { + return; + } + Notifications::showInformationNote(this->getPluginAttributes(uid).mDescription); +} +// --------------------------------------------------------------------------- + +PluginAttributes PIMainView::getPluginAttributes(int uid) +{ + // Get plug-in attributes from the plug-in list based on uid number + for (int index = 0; index < mPluginList->size(); index++) { + if (mPluginList->at(index).mUid == uid) { + return mPluginList->at(index); + } + } + return PluginAttributes(); +} + +// --------------------------------------------------------------------------- + +void PIMainView::contextMenuClosed() +{ + mContextMenu = 0; +} + +// --------------------------------------------------------------------------- + +void PIMainView::startProfiling() +{ + + showProfilingNote(); + if (!mEngine->startProfiling()) { + Notifications::showErrorNote("Unable to start profiling"); + mProfilingNote->close(); + mProfilingNote = 0; + } +} + +// --------------------------------------------------------------------------- +void PIMainView::startTimedProfiling() +{ + showProfilingNote(); + if (!mEngine->startTimedProfiling()) { + Notifications::showErrorNote("Unable to start profiling"); + mProfilingNote->close(); + mProfilingNote = 0; + } +} + +// --------------------------------------------------------------------------- + + +void PIMainView::stopProfiling() +{ + mProfilingNote = 0; + mEngine->stopProfiling(); +} + +// --------------------------------------------------------------------------- + +void PIMainView::profilingStatusChanged(ProfilerEngineStatus status, const QString &text, + ProfilingMode profilingMode, ProfilingOutput outputMode) +{ + + if (status == PI_FINISHED_SUCCEFULLY) { + // Profiling finished successfully + + // close profiling note + if (mProfilingNote != 0) { + mProfilingNote->close(); + mProfilingNote = 0; + } + + // Show info text + Notifications::showInformationNote(text); + return; + } + + if (mProfilingNote == 0) { + // if profiling note is not yet shown, create it + showProfilingNote(); + } + + if (status == PI_ERROR) { + // if errors occured, close profiling note and show error message + if (mProfilingNote != 0) { + mProfilingNote->close(); + mProfilingNote = 0; + } + Notifications::showErrorNote(text); + } + + else if (status == PI_PROFILING) { + // if profiling is on-going, update info text according to output: + + HbLabel *titleLabel = new HbLabel("Profiling...", mProfilingNote); + titleLabel->setAlignment(Qt::AlignCenter); + + HbTextItem *textItem = new HbTextItem(text, mProfilingNote); + textItem->setAlignment(Qt::AlignCenter); + + mProfilingNote->setHeadingWidget(titleLabel); + mProfilingNote->setContentWidget(textItem); + } + +} + +// --------------------------------------------------------------------------- + +void PIMainView::showProfilingNote() +{ + // Create new dialog + mProfilingNote = new HbDialog(); + mProfilingNote->setAttribute(Qt::WA_DeleteOnClose); + + // Make it modal. + mProfilingNote->setModal(true); + + // set dismiss policy + mProfilingNote->setDismissPolicy(HbPopup::NoDismiss); + mProfilingNote->setTimeout(0); // + mProfilingNote->setBackgroundFaded(true); + + // create label and text item for popup + HbTextItem *titleLabel = new HbTextItem("Profiling...", mProfilingNote); + HbTextItem *label = new HbTextItem("Starting to profile", mProfilingNote); + + label->setAlignment(Qt::AlignCenter); + titleLabel->setAlignment(Qt::AlignCenter); + mProfilingNote->setHeadingWidget(titleLabel); + mProfilingNote->setContentWidget(label); + + // set actions + mProfilingNote->setPrimaryAction(mActionStopProfiling); + mProfilingNote->setSecondaryAction(mActionExitAndLeaveProfilingOn); + + mProfilingNote->open(); +} + +// --------------------------------------------------------------------------- + +void PIMainView::updateTimedProfilingText() +{ + QString text = "Start timed profiling("; + QString number; + number.setNum(mEngine->getTimeLimit(), 10); + text.append(number); + text.append("s)"); + mActionStartTimedProfiling->setText(text); + +} + +// --------------------------------------------------------------------------- + +void PIMainView::exitAndLeaveProfilingOn() +{ + mEngine->leaveProfilingOnAfterClosing(); + application->quit(); +} +// --------------------------------------------------------------------------- + +void PIMainView::openPluginSpecificSettings() +{ + HbListWidgetItem *listItem = mListPlugins->currentItem(); + bool ok = false; + int uid = listItem->data().toInt(&ok); + if (ok) { + mMainWindow->activateSettingsView(uid); + } +} + +// --------------------------------------------------------------------------- +// ---------------------------------------------------------------------------