piprofilerui/ui/hb/src/pimainview.cpp
branchRCL_3
changeset 12 aefcba28a3e0
child 21 b3cee849fa46
equal deleted inserted replaced
11:454d022d514b 12:aefcba28a3e0
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <hbdocumentloader.h>
       
    20 #include <hbmainwindow.h>
       
    21 #include <hbapplication.h>
       
    22 #include <hbaction.h>
       
    23 #include <qgraphicslayout.h>
       
    24 #include <qvariant.h>
       
    25 #include <qobject.h>
       
    26 #include <qlist.h>
       
    27 #include <hbmessagebox.h>
       
    28 #include <hblabel.h>
       
    29 #include <hbwidget.h>
       
    30 #include <qstringlist.h>
       
    31 #include <qsignalmapper.h>
       
    32 #include <hblistwidget.h>
       
    33 #include <hblistwidgetitem.h>
       
    34 #include <hbmenu.h>
       
    35 #include <hbtoolbar.h>
       
    36 #include <hbdialog.h>
       
    37 #include <hbprogressdialog.h>
       
    38 #include <hbtextitem.h>
       
    39 #include <hbindicator.h>
       
    40 #include <qdebug.h>
       
    41 
       
    42 #include "pimainview.h"
       
    43 #include "piprofilerengine.h"
       
    44 #include "notifications.h"
       
    45 #include "pimainwindow.h"
       
    46 
       
    47 const char *INVALIDCONFIGURATIONFILE = "Invalid configuration file";
       
    48 const char *APPLICATIONNAME = "PI Profiler";
       
    49 
       
    50 // actions that are found from xml
       
    51 const char *ACTIONEXIT = "actionExit";
       
    52 const char *ACTIONSTARTPROFILING = "actionStartProfiling";
       
    53 const char *ACTIONSTARTTIMEDPROFILING = "actionStartTimedProfiling";
       
    54 const char *ACTIONSETTINGS = "actionSettings";
       
    55 const char *ACTIONABOUT = "actionAbout";
       
    56 
       
    57 // UI components that are found from xml
       
    58 
       
    59 const char *LISTWIDGETPLUGINS = "listPlugins";
       
    60 const char *TEXTMANDATORYPLUGINS = "Mandatory plug-ins:";
       
    61 const char *TEXTOPTIONALPLUGINS = "Optional plug-ins:";
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 
       
    65 PIMainView::PIMainView() :
       
    66     application(0), mMainWindow(0), mEngine(0), mPluginList(0), mContextMenu(0), mActionExit(0),
       
    67         mActionExitAndLeaveProfilingOn(0), mActionAbout(0), mActionStartTimedProfiling(0),
       
    68         mActionSettings(0), mActionStopProfiling(0), mListPlugins(0), mProfilingNote(0)
       
    69 {
       
    70 
       
    71 }
       
    72 
       
    73 // ---------------------------------------------------------------------------
       
    74 
       
    75 PIMainView::~PIMainView()
       
    76 {
       
    77 }
       
    78 
       
    79 // ---------------------------------------------------------------------------
       
    80 
       
    81 void PIMainView::init(PIMainWindow *mainWindow, HbApplication* app, HbDocumentLoader &loader,
       
    82     PIProfilerEngine *engine)
       
    83 {
       
    84 
       
    85     application = app;
       
    86     mMainWindow = mainWindow;
       
    87 
       
    88     // Load items from xml file
       
    89     loadItemsFromResources(loader);
       
    90 
       
    91     // Set list widget items
       
    92     mListPlugins->setLongPressEnabled(true);
       
    93     mListPlugins->setClampingStyle(HbScrollArea::BounceBackClamping);
       
    94     mListPlugins->setFrictionEnabled(true);
       
    95 
       
    96     // Create stop profiling action
       
    97     mActionStopProfiling = new HbAction("Stop Profiling", this);
       
    98 
       
    99     // Create exit and leave profiling on action
       
   100     mActionExitAndLeaveProfilingOn = new HbAction("Close UI\n(Continue profiling)", this);
       
   101 
       
   102     mEngine = engine;
       
   103 
       
   104     // Connect signals and slots
       
   105     this->connectSignalsAndSlots(app);
       
   106 
       
   107     // Create icons
       
   108     mIconDisabled = HbIcon(":/gfx/disabled.svg");
       
   109     mIconEnabled = HbIcon(":/gfx/enabled.svg");
       
   110 
       
   111     // update timed profiling text according to settings
       
   112     updateTimedProfilingText();
       
   113 }
       
   114 
       
   115 // ---------------------------------------------------------------------------
       
   116 
       
   117 
       
   118 void PIMainView::connectSignalsAndSlots(HbApplication* app)
       
   119 {
       
   120 
       
   121     // Menu items:
       
   122     connect(mActionExit, SIGNAL(triggered()), app, SLOT( quit() ));
       
   123     connect(mActionSettings, SIGNAL(triggered()), this, SLOT( openSettingsView() ));
       
   124     connect(mActionAbout, SIGNAL(triggered()), this, SLOT( showAboutPopup() ));
       
   125     connect(mActionStartProfiling, SIGNAL(triggered()), this, SLOT( startProfiling() ));
       
   126     connect(mActionStartTimedProfiling, SIGNAL(triggered()), this, SLOT( startTimedProfiling() ));
       
   127 
       
   128     // List widget actions
       
   129     connect(mListPlugins, SIGNAL(activated(HbListWidgetItem*)), this,
       
   130         SLOT(enableOrDisablePlugin(HbListWidgetItem*)));
       
   131     connect(mListPlugins, SIGNAL(longPressed(HbListWidgetItem*, QPointF)), this,
       
   132         SLOT(showContexMenu(HbListWidgetItem*, QPointF)));
       
   133 
       
   134     connect(
       
   135         mEngine,
       
   136         SIGNAL(profilingStatusChanged(ProfilerEngineStatus, const QString&, ProfilingMode, ProfilingOutput)),
       
   137         this,
       
   138         SLOT(profilingStatusChanged(ProfilerEngineStatus, const QString&, ProfilingMode, ProfilingOutput)));
       
   139 
       
   140     connect(mMainWindow, SIGNAL(returnedFromSettings()), this, SLOT( updateTimedProfilingText() ));
       
   141     connect(mActionExitAndLeaveProfilingOn, SIGNAL(triggered()), this,
       
   142         SLOT( exitAndLeaveProfilingOn() ));
       
   143     connect(mActionStopProfiling, SIGNAL(triggered()), this, SLOT( stopProfiling() ));
       
   144 
       
   145 }
       
   146 
       
   147 // ---------------------------------------------------------------------------
       
   148 
       
   149 
       
   150 void PIMainView::loadItemsFromResources(HbDocumentLoader &loader)
       
   151 {
       
   152 
       
   153     // ACTIONS:
       
   154 
       
   155     // Exit
       
   156     QObject *object = loader.findObject(ACTIONEXIT);
       
   157     Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE);
       
   158     this->mActionExit = qobject_cast<HbAction *> (object);
       
   159 
       
   160     // About
       
   161     object = loader.findObject(ACTIONABOUT);
       
   162     Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE);
       
   163     this->mActionAbout = qobject_cast<HbAction *> (object);
       
   164 
       
   165     // Settings
       
   166     object = loader.findObject(ACTIONSETTINGS);
       
   167     Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE);
       
   168     this->mActionSettings = qobject_cast<HbAction *> (object);
       
   169 
       
   170     // Start profiling
       
   171     object = loader.findObject(ACTIONSTARTPROFILING);
       
   172     Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE);
       
   173     this->mActionStartProfiling = qobject_cast<HbAction *> (object);
       
   174 
       
   175     // Start timed profiling
       
   176     object = loader.findObject(ACTIONSTARTTIMEDPROFILING);
       
   177     Q_ASSERT_X((object != 0), APPLICATIONNAME, INVALIDCONFIGURATIONFILE);
       
   178     this->mActionStartTimedProfiling = qobject_cast<HbAction *> (object);
       
   179 
       
   180     QGraphicsWidget *widget = loader.findWidget(LISTWIDGETPLUGINS);
       
   181     Q_ASSERT_X((widget != 0), "Launcher", "Invalid launcher.xml file");
       
   182     this->mListPlugins = qobject_cast<HbListWidget *> (widget);
       
   183 }
       
   184 
       
   185 // ---------------------------------------------------------------------------
       
   186 
       
   187 void PIMainView::showAboutPopup()
       
   188 {
       
   189 
       
   190     Notifications::showMessageBox("Version 2.2.0.2 - 4th May 2010. \n"
       
   191             "Copyright © 2010 Nokia Corporation "
       
   192             "and/or its subsidiary(-ies). "
       
   193             "All rights reserved.");
       
   194 
       
   195 }
       
   196 // ---------------------------------------------------------------------------
       
   197 
       
   198 void PIMainView::setPluginList(QList<PluginAttributes> *pluginList)
       
   199 {
       
   200 
       
   201     this->mPluginList = pluginList;
       
   202     this->updatePlugInLists();
       
   203 
       
   204 }
       
   205 
       
   206 // ---------------------------------------------------------------------------
       
   207 
       
   208 void PIMainView::openSettingsView()
       
   209 {
       
   210     mMainWindow->activateSettingsView();
       
   211 }
       
   212 
       
   213 // ---------------------------------------------------------------------------
       
   214 
       
   215 void PIMainView::updatePlugInLists()
       
   216 {
       
   217 
       
   218     mListPlugins->clear();
       
   219 
       
   220     // Create Compulsory and Optional labels into list widget:
       
   221     HbListWidgetItem *compulsory = new HbListWidgetItem();
       
   222     compulsory->setText(TEXTMANDATORYPLUGINS);
       
   223     mListPlugins->addItem(compulsory);
       
   224 
       
   225     HbListWidgetItem *optional = new HbListWidgetItem();
       
   226     optional->setText(TEXTOPTIONALPLUGINS);
       
   227     mListPlugins->addItem(optional);
       
   228 
       
   229     HbIcon *icon;
       
   230 
       
   231     // Go thru pluginlist and add list item for each plug-in into list widget 
       
   232     for (int index = 0; index < mPluginList->size(); index++) {
       
   233         QString plugInName = mPluginList->at(index).mName;
       
   234 
       
   235         // get icon for item 
       
   236         if (mPluginList->at(index).mEnabled) {
       
   237             icon = &mIconEnabled;
       
   238         }
       
   239         else {
       
   240             icon = &mIconDisabled;
       
   241         }
       
   242 
       
   243         // Create list widget item
       
   244         // TODO ensure that this does not leak memory
       
   245         HbListWidgetItem *newItem = new HbListWidgetItem();
       
   246         newItem->setIcon(*icon);
       
   247         newItem->setText(plugInName);
       
   248         newItem->setData(mPluginList->at(index).mUid);
       
   249 
       
   250         // check if plug-in is compulsory or optional
       
   251         if (mPluginList->at(index).mIsHidden) {
       
   252             mListPlugins->insertItem(mListPlugins->row(optional), newItem);
       
   253         }
       
   254         else {
       
   255             mListPlugins->addItem(newItem);
       
   256 
       
   257         }
       
   258     }
       
   259 
       
   260 }
       
   261 // ---------------------------------------------------------------------------
       
   262 
       
   263 void PIMainView::enableOrDisablePlugin(HbListWidgetItem *widget)
       
   264 {
       
   265 
       
   266     // if widget is not found, set currently highlighted item as widget
       
   267     // (in that case this method is called from context menu)
       
   268     if (widget == 0) {
       
   269         widget = mListPlugins->currentItem();
       
   270     }
       
   271 
       
   272     // if this method is called from list widget's activated signal, do nothing
       
   273     // if context menu is open.
       
   274     else {
       
   275         if (mContextMenu != 0) {
       
   276             return;
       
   277         }
       
   278     }
       
   279     bool ok = false;
       
   280     int widgetUid = widget->data().toInt(&ok);
       
   281     if (!ok) {
       
   282         qWarning("PIProfiler: Unable to find plug-in uid");
       
   283         return;
       
   284     }
       
   285 
       
   286     // go thru plug-in array and find checked plug-in
       
   287     for (int index = 0; index < mPluginList->size(); index++) {
       
   288 
       
   289         if (mPluginList->at(index).mUid == widgetUid) {
       
   290             PluginAttributes pluginAttributes = mPluginList->at(index);
       
   291 
       
   292             // if plug-in is hidden it cannot be disabled
       
   293             if (pluginAttributes.mIsHidden) {
       
   294                 return;
       
   295             }
       
   296 
       
   297             // change enable status and set icon correct
       
   298             if (pluginAttributes.mEnabled) {
       
   299                 pluginAttributes.mEnabled = false;
       
   300                 widget->setIcon(mIconDisabled);
       
   301             }
       
   302             else {
       
   303                 pluginAttributes.mEnabled = true;
       
   304                 widget->setIcon(mIconEnabled);
       
   305             }
       
   306 
       
   307             // save plug-in settings
       
   308             if (mEngine->savePluginSettings(pluginAttributes)) {
       
   309                 mPluginList->replace(index, pluginAttributes);
       
   310             }
       
   311             else {
       
   312                 // if saving operation failed, revert icon back
       
   313                 if (pluginAttributes.mEnabled) {
       
   314                     widget->setIcon(mIconEnabled);
       
   315                 }
       
   316                 else {
       
   317                     pluginAttributes.mEnabled = true;
       
   318                     widget->setIcon(mIconDisabled);
       
   319                 }
       
   320                 Notifications::showErrorNote(
       
   321                     "Error occured while saving settings to Profiler engine.");
       
   322             }
       
   323             break;
       
   324         }
       
   325 
       
   326     }
       
   327 
       
   328 }
       
   329 
       
   330 // ---------------------------------------------------------------------------
       
   331 
       
   332 void PIMainView::showContexMenu(HbListWidgetItem *widget, const QPointF &point)
       
   333 {
       
   334 
       
   335     bool ok = false;
       
   336     int uid = widget->data().toInt(&ok);
       
   337 
       
   338     if (!ok) {
       
   339         return;
       
   340     }
       
   341 
       
   342     for (int index = 0; index < mPluginList->size(); index++) {
       
   343 
       
   344         if (mPluginList->at(index).mUid == uid) {
       
   345 
       
   346             // Create Context menu:
       
   347             mContextMenu = new HbMenu();
       
   348             mContextMenu->setPreferredPos(point, HbPopup::TopLeftCorner);
       
   349             mContextMenu->setDismissPolicy(HbPopup::TapOutside);
       
   350             mContextMenu->setAttribute(Qt::WA_DeleteOnClose);
       
   351 
       
   352             // Enable/disable plug-in
       
   353             if (!mPluginList->at(index).mIsHidden) {
       
   354                 HbAction *enableAction;
       
   355                 if (mPluginList->at(index).mEnabled) {
       
   356                     enableAction = mContextMenu->addAction(QString("Disable"));
       
   357                 }
       
   358                 else {
       
   359                     enableAction = mContextMenu->addAction(QString("Enable"));
       
   360                 }
       
   361                 connect(enableAction, SIGNAL(triggered()), this, SLOT( enableOrDisablePlugin() ));
       
   362             }
       
   363 
       
   364             //FIXME take these into use once expanding and collapsing data form groups works. 
       
   365             // Plug-in specific settings 
       
   366             /*if (mPluginList->at(index).mItemCount != 0 || mPluginList->at(index).mSampleRate != -1) {
       
   367              HbAction *pluginSettingsAction = mContextMenu->addAction(QString(
       
   368              "Plug-in settings"));
       
   369              connect(pluginSettingsAction, SIGNAL(triggered()), this,
       
   370              SLOT(openPluginSpecificSettings()));
       
   371              }*/
       
   372 
       
   373             // Plug in info
       
   374             HbAction *infoAction = mContextMenu->addAction(QString("Plug-in info"));
       
   375             connect(infoAction, SIGNAL(triggered()), this, SLOT( openSampleInfo() ));
       
   376 
       
   377             connect(mContextMenu, SIGNAL(aboutToClose()), this, SLOT( contextMenuClosed() ));
       
   378             mContextMenu->open(this, SLOT(contextMenuClosed()));
       
   379             break;
       
   380         }
       
   381     }
       
   382 
       
   383 }
       
   384 
       
   385 // ---------------------------------------------------------------------------
       
   386 
       
   387 void PIMainView::openSampleInfo()
       
   388 {
       
   389 
       
   390     // Show plug-in specific info
       
   391     bool ok = false;
       
   392     int uid = mListPlugins->currentItem()->data().toInt(&ok);
       
   393     if (!ok) {
       
   394         return;
       
   395     }
       
   396     Notifications::showInformationNote(this->getPluginAttributes(uid).mDescription);
       
   397 }
       
   398 // ---------------------------------------------------------------------------
       
   399 
       
   400 PluginAttributes PIMainView::getPluginAttributes(int uid)
       
   401 {
       
   402     // Get plug-in attributes from the plug-in list based on uid number
       
   403     for (int index = 0; index < mPluginList->size(); index++) {
       
   404         if (mPluginList->at(index).mUid == uid) {
       
   405             return mPluginList->at(index);
       
   406         }
       
   407     }
       
   408     return PluginAttributes();
       
   409 }
       
   410 
       
   411 // ---------------------------------------------------------------------------
       
   412 
       
   413 void PIMainView::contextMenuClosed()
       
   414 {
       
   415     mContextMenu = 0;
       
   416 }
       
   417 
       
   418 // ---------------------------------------------------------------------------
       
   419 
       
   420 void PIMainView::startProfiling()
       
   421 {
       
   422 
       
   423     showProfilingNote();
       
   424     if (!mEngine->startProfiling()) {
       
   425         Notifications::showErrorNote("Unable to start profiling");
       
   426         mProfilingNote->close();
       
   427         mProfilingNote = 0;
       
   428     }
       
   429 }
       
   430 
       
   431 // ---------------------------------------------------------------------------
       
   432 void PIMainView::startTimedProfiling()
       
   433 {
       
   434     showProfilingNote();
       
   435     if (!mEngine->startTimedProfiling()) {
       
   436         Notifications::showErrorNote("Unable to start profiling");
       
   437         mProfilingNote->close();
       
   438         mProfilingNote = 0;
       
   439     }
       
   440 }
       
   441 
       
   442 // ---------------------------------------------------------------------------
       
   443 
       
   444 
       
   445 void PIMainView::stopProfiling()
       
   446 {
       
   447     mProfilingNote = 0;
       
   448     mEngine->stopProfiling();
       
   449 }
       
   450 
       
   451 // ---------------------------------------------------------------------------
       
   452 
       
   453 void PIMainView::profilingStatusChanged(ProfilerEngineStatus status, const QString &text,
       
   454     ProfilingMode profilingMode, ProfilingOutput outputMode)
       
   455 {
       
   456 
       
   457     if (status == PI_FINISHED_SUCCEFULLY) {
       
   458         // Profiling finished successfully
       
   459 
       
   460         // close profiling note
       
   461         if (mProfilingNote != 0) {
       
   462             mProfilingNote->close();
       
   463             mProfilingNote = 0;
       
   464         }
       
   465 
       
   466         // Show info text
       
   467         Notifications::showInformationNote(text);
       
   468         return;
       
   469     }
       
   470 
       
   471     if (mProfilingNote == 0) {
       
   472         // if profiling note is not yet shown, create it
       
   473         showProfilingNote();
       
   474     }
       
   475 
       
   476     if (status == PI_ERROR) {
       
   477         // if errors occured, close profiling note and show error message
       
   478         if (mProfilingNote != 0) {
       
   479             mProfilingNote->close();
       
   480             mProfilingNote = 0;
       
   481         }
       
   482         Notifications::showErrorNote(text);
       
   483     }
       
   484 
       
   485     else if (status == PI_PROFILING) {
       
   486         // if profiling is on-going, update info text according to output:
       
   487 
       
   488         HbLabel *titleLabel = new HbLabel("Profiling...", mProfilingNote);
       
   489         titleLabel->setAlignment(Qt::AlignCenter);
       
   490 
       
   491         HbTextItem *textItem = new HbTextItem(text, mProfilingNote);
       
   492         textItem->setAlignment(Qt::AlignCenter);
       
   493 
       
   494         mProfilingNote->setHeadingWidget(titleLabel);
       
   495         mProfilingNote->setContentWidget(textItem);
       
   496     }
       
   497 
       
   498 }
       
   499 
       
   500 // ---------------------------------------------------------------------------
       
   501 
       
   502 void PIMainView::showProfilingNote()
       
   503 {
       
   504     // Create new dialog 
       
   505     mProfilingNote = new HbDialog();
       
   506     mProfilingNote->setAttribute(Qt::WA_DeleteOnClose);
       
   507 
       
   508     // Make it modal.
       
   509     mProfilingNote->setModal(true);
       
   510 
       
   511     // set dismiss policy
       
   512     mProfilingNote->setDismissPolicy(HbPopup::NoDismiss);
       
   513     mProfilingNote->setTimeout(0); //
       
   514     mProfilingNote->setBackgroundFaded(true);
       
   515 
       
   516     // create label and text item for popup
       
   517     HbTextItem *titleLabel = new HbTextItem("Profiling...", mProfilingNote);
       
   518     HbTextItem *label = new HbTextItem("Starting to profile", mProfilingNote);
       
   519 
       
   520     label->setAlignment(Qt::AlignCenter);
       
   521     titleLabel->setAlignment(Qt::AlignCenter);
       
   522     mProfilingNote->setHeadingWidget(titleLabel);
       
   523     mProfilingNote->setContentWidget(label);
       
   524 
       
   525     // set actions
       
   526     mProfilingNote->setPrimaryAction(mActionStopProfiling);
       
   527     mProfilingNote->setSecondaryAction(mActionExitAndLeaveProfilingOn);
       
   528 
       
   529     mProfilingNote->open();
       
   530 }
       
   531 
       
   532 // ---------------------------------------------------------------------------
       
   533 
       
   534 void PIMainView::updateTimedProfilingText()
       
   535 {
       
   536     QString text = "Start timed profiling(";
       
   537     QString number;
       
   538     number.setNum(mEngine->getTimeLimit(), 10);
       
   539     text.append(number);
       
   540     text.append("s)");
       
   541     mActionStartTimedProfiling->setText(text);
       
   542 
       
   543 }
       
   544 
       
   545 // ---------------------------------------------------------------------------
       
   546 
       
   547 void PIMainView::exitAndLeaveProfilingOn()
       
   548 {
       
   549     mEngine->leaveProfilingOnAfterClosing();
       
   550     application->quit();
       
   551 }
       
   552 // ---------------------------------------------------------------------------
       
   553 
       
   554 void PIMainView::openPluginSpecificSettings()
       
   555 {
       
   556     HbListWidgetItem *listItem = mListPlugins->currentItem();
       
   557     bool ok = false;
       
   558     int uid = listItem->data().toInt(&ok);
       
   559     if (ok) {
       
   560         mMainWindow->activateSettingsView(uid);
       
   561     }
       
   562 }
       
   563 
       
   564 // ---------------------------------------------------------------------------
       
   565 // ---------------------------------------------------------------------------