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