piprofilerui/ui/hb/src/pimainview.cpp
branchRCL_3
changeset 13 822c625f7adc
child 19 b3cee849fa46
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofilerui/ui/hb/src/pimainview.cpp	Wed Jun 09 09:42:37 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 <hbdocumentloader.h>
+#include <hbmainwindow.h>
+#include <hbapplication.h>
+#include <hbaction.h>
+#include <qgraphicslayout.h>
+#include <qvariant.h>
+#include <qobject.h>
+#include <qlist.h>
+#include <hbmessagebox.h>
+#include <hblabel.h>
+#include <hbwidget.h>
+#include <qstringlist.h>
+#include <qsignalmapper.h>
+#include <hblistwidget.h>
+#include <hblistwidgetitem.h>
+#include <hbmenu.h>
+#include <hbtoolbar.h>
+#include <hbdialog.h>
+#include <hbprogressdialog.h>
+#include <hbtextitem.h>
+#include <hbindicator.h>
+#include <qdebug.h>
+
+#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<HbAction *> (object);
+
+    // About
+    object = loader.findObject(ACTIONABOUT);
+    Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE);
+    this->mActionAbout = qobject_cast<HbAction *> (object);
+
+    // Settings
+    object = loader.findObject(ACTIONSETTINGS);
+    Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE);
+    this->mActionSettings = qobject_cast<HbAction *> (object);
+
+    // Start profiling
+    object = loader.findObject(ACTIONSTARTPROFILING);
+    Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE);
+    this->mActionStartProfiling = qobject_cast<HbAction *> (object);
+
+    // Start timed profiling
+    object = loader.findObject(ACTIONSTARTTIMEDPROFILING);
+    Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE);
+    this->mActionStartTimedProfiling = qobject_cast<HbAction *> (object);
+
+    QGraphicsWidget *widget = loader.findWidget(LISTWIDGETPLUGINS);
+    Q_ASSERT_X((widget != 0), "Launcher", "Invalid launcher.xml file");
+    this->mListPlugins = qobject_cast<HbListWidget *> (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<PluginAttributes> *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);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------