<commit_before>//=============================================================================================================
/**
 * @file     main.cpp
 * @author   Ruben Dörfel <doerfelruben@aol.com>
 * @since    0.1.5
 * @date     July, 2020
 *
 * @section  LICENSE
 *
 * Copyright (C) 2020, Ruben Dörfel. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *       following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 *       the following disclaimer in the documentation and/or other materials provided with the distribution.
 *     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
 *       to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @brief     Examplethat shows the coregistration workflow.
 *
 */

//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <iostream>

#include <disp3D/viewers/abstractview.h>
#include <disp3D/engine/model/items/digitizer/digitizersettreeitem.h>
#include <disp3D/engine/model/data3Dtreemodel.h>
#include <disp3D/engine/model/items/bem/bemsurfacetreeitem.h>
#include <disp3D/engine/model/items/bem/bemtreeitem.h>

#include "fiff/fiff_dig_point_set.h"
#include "fiff/fiff_dig_point.h"
#include "fiff/fiff_coord_trans.h"

#include "mne/mne_bem_surface.h"
#include "mne/mne_project_to_surface.h"

#include <utils/generics/applicationlogger.h>
#include "rtprocessing/icp.h"

//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QApplication>
#include <QMainWindow>
#include <QCommandLineParser>
#include <QDebug>
#include <QFile>

//=============================================================================================================
// Eigen
//=============================================================================================================

#include <Eigen/Core>

//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace Eigen;
using namespace UTILSLIB;
using namespace RTPROCESSINGLIB;
using namespace FIFFLIB;
using namespace DISP3DLIB;
using namespace MNELIB;

//=============================================================================================================
// MAIN
//=============================================================================================================

//=============================================================================================================
/**
 * The function main marks the entry point of the program.
 * By default, main has the storage class extern.
 *
 * @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
 * @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
 * @return the value that was set to exit() (which is 0 if exit() is called via quit()).
 */
int main(int argc, char *argv[])
{
    #ifdef STATICBUILD
    Q_INIT_RESOURCE(disp3d);
    #endif

    qInstallMessageHandler(ApplicationLogger::customLogWriter);
    QApplication a(argc, argv);

    // Command Line Parser
    QCommandLineParser parser;
    parser.setApplicationDescription("Example Coregistration");
    parser.addHelpOption();

    QCommandLineOption digOption("dig", "The destination point set", "file", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis-ave.fif");
    QCommandLineOption bemOption("bem", "The bem file", "file", QCoreApplication::applicationDirPath() + "/MNE-sample-data/subjects/sample/bem/sample-head.fif");
    QCommandLineOption transOption("trans", "The MRI-Head transformation file", "file", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis_raw-trans.fif");
    QCommandLineOption scaleOption("scale", "Weather to scale during the registration or not", "bool", "false");
    QCommandLineOption tolOption("tol", "The convergence limit for the icp algorithm.", "float", "0.001");
    QCommandLineOption distOption("dist", "The maximum distance between digitizer and head shape in mm.", "float", "0.02");

    parser.addOption(digOption);
    parser.addOption(bemOption);
    parser.addOption(scaleOption);
    parser.addOption(transOption);
    parser.addOption(tolOption);
    parser.addOption(distOption);

    parser.process(a);

    // get cli parameters
    QFile t_fileDig(parser.value(digOption));
    QFile t_fileBem(parser.value(bemOption));
    QFile t_fileTrans(parser.value(transOption));

    bool bScale = false;
    if(parser.value(scaleOption) == "false" || parser.value(scaleOption) == "0") {
        bScale = false;
    } else if(parser.value(scaleOption) == "true" || parser.value(scaleOption) == "1") {
        bScale = true;
    }

    float fTol = parser.value(tolOption).toFloat();
    float fMaxDist = parser.value(distOption).toFloat();

    // read Trans
    FiffCoordTrans transHeadMriRef(t_fileTrans);

    // read Bem
    MNEBem bemHead(t_fileBem);
    MNEBemSurface::SPtr bemSurface = MNEBemSurface::SPtr::create(bemHead[0]);
    MNEProjectToSurface::SPtr mneSurfacePoints = MNEProjectToSurface::SPtr::create(*bemSurface);

    // read digitizer data
    QList<int> lPickFiducials({FIFFV_POINT_CARDINAL});
    QList<int> lPickHSP({FIFFV_POINT_CARDINAL,FIFFV_POINT_HPI,FIFFV_POINT_EXTRA,FIFFV_POINT_EEG});
    FiffDigPointSet digSetSrc = FiffDigPointSet(t_fileDig).pickTypes(lPickFiducials);   // Fiducials Head-Space
    FiffDigPointSet digSetDst = FiffDigPointSet(t_fileDig).pickTypes(lPickFiducials);
    digSetDst.applyTransform(transHeadMriRef, false);                                   // Fiducials MRI-Space
    FiffDigPointSet digSetHsp = FiffDigPointSet(t_fileDig).pickTypes(lPickHSP);         // Head shape points Head-Space

    // Initial Fiducial Alignment
    // Declare variables
    Matrix3f matSrc(digSetSrc.size(),3);
    Matrix3f matDst(digSetDst.size(),3);
    Matrix4f matTrans;
    Vector3f vecWeights(digSetSrc.size()); // LPA, Nasion, RPA
    float fScale;

    // get coordinates
    for(int i = 0; i< digSetSrc.size(); ++i) {
        matSrc(i,0) = digSetSrc[i].r[0]; matSrc(i,1) = digSetSrc[i].r[1]; matSrc(i,2) = digSetSrc[i].r[2];
        matDst(i,0) = digSetDst[i].r[0]; matDst(i,1) = digSetDst[i].r[1]; matDst(i,2) = digSetDst[i].r[2];

        // set standart weights
        if(digSetSrc[i].ident == FIFFV_POINT_NASION) {
            vecWeights(i) = 10.0;
        } else {
            vecWeights(i) = 1.0;
        }
    }

    // align fiducials
    if(!fitMatched(matSrc,matDst,matTrans,fScale,bScale,vecWeights)) {
        qWarning() << "Point cloud registration not succesfull.";
    }

    fiff_int_t iFrom = digSetSrc[0].coord_frame;
    fiff_int_t iTo = bemSurface.data()->coord_frame;
    FiffCoordTrans transHeadMri = FiffCoordTrans::make(iFrom, iTo, matTrans);

    // Prepare Icp:
    VectorXf vecWeightsICP(digSetHsp.size()); // Weigths vector
    int iMaxIter = 20;
    MatrixXf matHsp(digSetHsp.size(),3);

    for(int i = 0; i < digSetHsp.size(); ++i) {
        matHsp(i,0) = digSetHsp[i].r[0]; matHsp(i,1) = digSetHsp[i].r[1]; matHsp(i,2) = digSetHsp[i].r[2];
        // set standart weights
        if((digSetHsp[i].kind == FIFFV_POINT_CARDINAL) && (digSetHsp[i].ident == FIFFV_POINT_NASION)) {
            vecWeightsICP(i) = 10.0;
        } else {
            vecWeightsICP(i) = 1.0;
        }
    }

    MatrixXf matHspClean;
    VectorXi vecTake;

    // discard outliers
    if(!discardOutliers(mneSurfacePoints, matHsp, transHeadMri, vecTake, matHspClean, fMaxDist)) {
        qWarning() << "Discard outliers was not succesfull.";
    }
    VectorXf vecWeightsICPClean(vecTake.size());

    for(int i = 0; i < vecTake.size(); ++i) {
        vecWeightsICPClean(i) = vecWeightsICP(vecTake(i));
    }

    // icp
    if(!icp(mneSurfacePoints, matHspClean, transHeadMri, iMaxIter, fTol, vecWeightsICPClean)) {
        qWarning() << "ICP was not succesfull.";
    }
    qInfo() << "transHeadMri:";
    transHeadMri.print();
    qInfo() << "transHeadMriRef:";
    transHeadMriRef.print();

    AbstractView::SPtr p3DAbstractView = AbstractView::SPtr(new AbstractView());
    Data3DTreeModel::SPtr p3DDataModel = p3DAbstractView->getTreeModel();
    DigitizerSetTreeItem* pDigSrcSetTreeItem = p3DDataModel->addDigitizerData("Sample", "Fiducials Transformed", digSetSrc);
    DigitizerSetTreeItem* pDigHspSetTreeItem = p3DDataModel->addDigitizerData("Sample", "Digitizer", digSetHsp);
    pDigSrcSetTreeItem->setTransform(transHeadMri,true);

    BemTreeItem* pBemItem = p3DDataModel->addBemData("Sample", "Head", bemHead);
    QList<QStandardItem*> itemList = pBemItem->findChildren(Data3DTreeModelItemTypes::BemSurfaceItem);
    for(int j = 0; j < itemList.size(); ++j) {
        if(BemSurfaceTreeItem* pBemItem = dynamic_cast<BemSurfaceTreeItem*>(itemList.at(j))) {
            pBemItem->setTransform(transHeadMri,true);
        }
    }

    p3DAbstractView->show();

    return a.exec();
}
<commit_msg>Enh: Add iteration setting via cli<commit_after>//=============================================================================================================
/**
 * @file     main.cpp
 * @author   Ruben Dörfel <doerfelruben@aol.com>
 * @since    0.1.5
 * @date     July, 2020
 *
 * @section  LICENSE
 *
 * Copyright (C) 2020, Ruben Dörfel. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *       following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 *       the following disclaimer in the documentation and/or other materials provided with the distribution.
 *     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
 *       to endorse or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @brief     Examplethat shows the coregistration workflow.
 *
 */

//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <iostream>

#include <disp3D/viewers/abstractview.h>
#include <disp3D/engine/model/items/digitizer/digitizersettreeitem.h>
#include <disp3D/engine/model/data3Dtreemodel.h>
#include <disp3D/engine/model/items/bem/bemsurfacetreeitem.h>
#include <disp3D/engine/model/items/bem/bemtreeitem.h>

#include "fiff/fiff_dig_point_set.h"
#include "fiff/fiff_dig_point.h"
#include "fiff/fiff_coord_trans.h"

#include "mne/mne_bem_surface.h"
#include "mne/mne_project_to_surface.h"

#include <utils/generics/applicationlogger.h>
#include "rtprocessing/icp.h"

//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QApplication>
#include <QMainWindow>
#include <QCommandLineParser>
#include <QDebug>
#include <QFile>

//=============================================================================================================
// Eigen
//=============================================================================================================

#include <Eigen/Core>

//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace Eigen;
using namespace UTILSLIB;
using namespace RTPROCESSINGLIB;
using namespace FIFFLIB;
using namespace DISP3DLIB;
using namespace MNELIB;

//=============================================================================================================
// MAIN
//=============================================================================================================

//=============================================================================================================
/**
 * The function main marks the entry point of the program.
 * By default, main has the storage class extern.
 *
 * @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
 * @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
 * @return the value that was set to exit() (which is 0 if exit() is called via quit()).
 */
int main(int argc, char *argv[])
{
    #ifdef STATICBUILD
    Q_INIT_RESOURCE(disp3d);
    #endif

    qInstallMessageHandler(ApplicationLogger::customLogWriter);
    QApplication a(argc, argv);

    // Command Line Parser
    QCommandLineParser parser;
    parser.setApplicationDescription("Example Coregistration");
    parser.addHelpOption();

    QCommandLineOption digOption("dig", "The destination point set", "file", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis-ave.fif");
    QCommandLineOption bemOption("bem", "The bem file", "file", QCoreApplication::applicationDirPath() + "/MNE-sample-data/subjects/sample/bem/sample-head.fif");
    QCommandLineOption transOption("trans", "The MRI-Head transformation file", "file", QCoreApplication::applicationDirPath() + "/MNE-sample-data/MEG/sample/sample_audvis_raw-trans.fif");
    QCommandLineOption scaleOption("scale", "Weather to scale during the registration or not", "bool", "false");
    QCommandLineOption tolOption("tol", "The convergence limit for the icp algorithm.", "float", "0.001");
    QCommandLineOption distOption("dist", "The maximum distance between digitizer and head shape in mm.", "float", "0.02");
    QCommandLineOption iterOption("iter", "The maximum number of icp iterations.", "int", "20");

    parser.addOption(digOption);
    parser.addOption(bemOption);
    parser.addOption(scaleOption);
    parser.addOption(transOption);
    parser.addOption(tolOption);
    parser.addOption(distOption);
    parser.addOption(iterOption);

    parser.process(a);

    // get cli parameters
    QFile t_fileDig(parser.value(digOption));
    QFile t_fileBem(parser.value(bemOption));
    QFile t_fileTrans(parser.value(transOption));

    bool bScale = false;
    if(parser.value(scaleOption) == "false" || parser.value(scaleOption) == "0") {
        bScale = false;
    } else if(parser.value(scaleOption) == "true" || parser.value(scaleOption) == "1") {
        bScale = true;
    }

    float fTol = parser.value(tolOption).toFloat();
    float fMaxDist = parser.value(distOption).toFloat();
    int iMaxIter = parser.value(iterOption).toInt();

    // read Trans
    FiffCoordTrans transHeadMriRef(t_fileTrans);

    // read Bem
    MNEBem bemHead(t_fileBem);
    MNEBemSurface::SPtr bemSurface = MNEBemSurface::SPtr::create(bemHead[0]);
    MNEProjectToSurface::SPtr mneSurfacePoints = MNEProjectToSurface::SPtr::create(*bemSurface);

    // read digitizer data
    QList<int> lPickFiducials({FIFFV_POINT_CARDINAL});
    QList<int> lPickHSP({FIFFV_POINT_CARDINAL,FIFFV_POINT_HPI,FIFFV_POINT_EXTRA,FIFFV_POINT_EEG});
    FiffDigPointSet digSetSrc = FiffDigPointSet(t_fileDig).pickTypes(lPickFiducials);   // Fiducials Head-Space
    FiffDigPointSet digSetDst = FiffDigPointSet(t_fileDig).pickTypes(lPickFiducials);
    digSetDst.applyTransform(transHeadMriRef, false);                                   // Fiducials MRI-Space
    FiffDigPointSet digSetHsp = FiffDigPointSet(t_fileDig).pickTypes(lPickHSP);         // Head shape points Head-Space

    // Initial Fiducial Alignment
    // Declare variables
    Matrix3f matSrc(digSetSrc.size(),3);
    Matrix3f matDst(digSetDst.size(),3);
    Matrix4f matTrans;
    Vector3f vecWeights(digSetSrc.size()); // LPA, Nasion, RPA
    float fScale;

    // get coordinates
    for(int i = 0; i< digSetSrc.size(); ++i) {
        matSrc(i,0) = digSetSrc[i].r[0]; matSrc(i,1) = digSetSrc[i].r[1]; matSrc(i,2) = digSetSrc[i].r[2];
        matDst(i,0) = digSetDst[i].r[0]; matDst(i,1) = digSetDst[i].r[1]; matDst(i,2) = digSetDst[i].r[2];

        // set standart weights
        if(digSetSrc[i].ident == FIFFV_POINT_NASION) {
            vecWeights(i) = 10.0;
        } else {
            vecWeights(i) = 1.0;
        }
    }

    // align fiducials
    if(!fitMatched(matSrc,matDst,matTrans,fScale,bScale,vecWeights)) {
        qWarning() << "Point cloud registration not succesfull.";
    }

    fiff_int_t iFrom = digSetSrc[0].coord_frame;
    fiff_int_t iTo = bemSurface.data()->coord_frame;
    FiffCoordTrans transHeadMri = FiffCoordTrans::make(iFrom, iTo, matTrans);

    // Prepare Icp:
    VectorXf vecWeightsICP(digSetHsp.size()); // Weigths vector
    MatrixXf matHsp(digSetHsp.size(),3);

    for(int i = 0; i < digSetHsp.size(); ++i) {
        matHsp(i,0) = digSetHsp[i].r[0]; matHsp(i,1) = digSetHsp[i].r[1]; matHsp(i,2) = digSetHsp[i].r[2];
        // set standart weights
        if((digSetHsp[i].kind == FIFFV_POINT_CARDINAL) && (digSetHsp[i].ident == FIFFV_POINT_NASION)) {
            vecWeightsICP(i) = 10.0;
        } else {
            vecWeightsICP(i) = 1.0;
        }
    }

    MatrixXf matHspClean;
    VectorXi vecTake;

    // discard outliers
    if(!discardOutliers(mneSurfacePoints, matHsp, transHeadMri, vecTake, matHspClean, fMaxDist)) {
        qWarning() << "Discard outliers was not succesfull.";
    }
    VectorXf vecWeightsICPClean(vecTake.size());

    for(int i = 0; i < vecTake.size(); ++i) {
        vecWeightsICPClean(i) = vecWeightsICP(vecTake(i));
    }

    // icp
    if(!icp(mneSurfacePoints, matHspClean, transHeadMri, iMaxIter, fTol, vecWeightsICPClean)) {
        qWarning() << "ICP was not succesfull.";
    }
    qInfo() << "transHeadMri:";
    transHeadMri.print();
    qInfo() << "transHeadMriRef:";
    transHeadMriRef.print();

    AbstractView::SPtr p3DAbstractView = AbstractView::SPtr(new AbstractView());
    Data3DTreeModel::SPtr p3DDataModel = p3DAbstractView->getTreeModel();
    DigitizerSetTreeItem* pDigSrcSetTreeItem = p3DDataModel->addDigitizerData("Sample", "Fiducials Transformed", digSetSrc);
    DigitizerSetTreeItem* pDigHspSetTreeItem = p3DDataModel->addDigitizerData("Sample", "Digitizer", digSetHsp);
    pDigSrcSetTreeItem->setTransform(transHeadMri,true);

    BemTreeItem* pBemItem = p3DDataModel->addBemData("Sample", "Head", bemHead);
    QList<QStandardItem*> itemList = pBemItem->findChildren(Data3DTreeModelItemTypes::BemSurfaceItem);
    for(int j = 0; j < itemList.size(); ++j) {
        if(BemSurfaceTreeItem* pBemItem = dynamic_cast<BemSurfaceTreeItem*>(itemList.at(j))) {
            pBemItem->setTransform(transHeadMri,true);
        }
    }

    p3DAbstractView->show();

    return a.exec();
}
<|endoftext|>


<commit_before>//  Powiter
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
*Created by Alexandre GAUTHIER-FOICHAT on 6/1/2012.
*contact: immarespond at gmail dot com
*
*/

#include "Gui/ComboBox.h"

#include <algorithm>
#include <QLayout>
#include <QLabel>
#include <QMenu>
#include <QStyle>

#include "Global/GlobalDefines.h"

using namespace std;
ComboBox::ComboBox(QWidget* parent):QFrame(parent),_currentIndex(0),_maximumTextSize(0),pressed(false){

    _mainLayout = new QHBoxLayout(this);
    _mainLayout->setSpacing(0);
    _mainLayout->setContentsMargins(0, 0, 0, 0);
    setLayout(_mainLayout);
    setFrameShape(QFrame::Box);

    _currentText = new QLabel(this);
    setCurrentIndex(-1);
    _currentText->setMinimumWidth(10);
    _mainLayout->addWidget(_currentText);

    _dropDownIcon = new QLabel(this);
    QImage imgC(IMAGES_PATH"combobox.png");
    QPixmap pixC=QPixmap::fromImage(imgC);
    pixC = pixC.scaled(10,10);
    _dropDownIcon->setPixmap(pixC);
    _mainLayout->addWidget(_dropDownIcon);

    _menu = new QMenu(this);
}

void ComboBox::paintEvent(QPaintEvent *e)
{
//    QStyleOption opt;
//    opt.init(this);
//    QPainter p(this);
//    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
    QFrame::paintEvent(e);
}

void ComboBox::mousePressEvent(QMouseEvent* e){
    QImage imgC(IMAGES_PATH"pressed_combobox.png");
    QPixmap pixC=QPixmap::fromImage(imgC);
    pixC = pixC.scaled(10,10);
    _dropDownIcon->setPixmap(pixC);
    setPressed(true);
    style()->unpolish(this);
    style()->polish(this);
    createMenu();
    QFrame::mousePressEvent(e);
}

void ComboBox::mouseReleaseEvent(QMouseEvent* e){
    QImage imgC(IMAGES_PATH"combobox.png");
    QPixmap pixC=QPixmap::fromImage(imgC);
    pixC = pixC.scaled(10,10);
    _dropDownIcon->setPixmap(pixC);
    setPressed(false);
    style()->unpolish(this);
    style()->polish(this);
    QFrame::mouseReleaseEvent(e);
}

void ComboBox::createMenu(){
    _menu->clear();
    for (U32 i = 0 ; i < _actions.size(); ++i) {
        for (U32 j = 0; j < _separators.size(); ++j) {
            if (_separators[j] == (int)i) {
                _menu->addSeparator();
                break;
            }
        }
        _menu->addAction(_actions[i]);
    }
    QAction* triggered = _menu->exec(this->mapToGlobal(QPoint(0,height())));
    for (U32 i = 0; i < _actions.size(); ++i) {
        if (triggered == _actions[i]) {
            setCurrentIndex(i);
            break;
        }
    }

    QImage imgC(IMAGES_PATH"combobox.png");
    QPixmap pixC=QPixmap::fromImage(imgC);
    pixC = pixC.scaled(10,10);
    _dropDownIcon->setPixmap(pixC);
    setPressed(false);
    style()->unpolish(this);
    style()->polish(this);

}

void ComboBox::insertItem(int index,const QString& item,QIcon icon,QKeySequence key){
    QAction* action =  new QAction(this);
    action->setText(item);
    if (!icon.isNull()) {
        action->setIcon(icon);
    }
    if (!key.isEmpty()) {
        action->setShortcut(key);
    }
    if (item.size() > _maximumTextSize) {
        _maximumTextSize = item.size();
    }
    _actions.insert(_actions.begin()+index, action);
    /*if this is the first action we add, make it current*/
    if(_actions.size() == 1){
        setCurrentText(itemText(0));
    }

}

void ComboBox::addItem(const QString& item,QIcon icon ,QKeySequence key){
    QAction* action =  new QAction(this);
    action->setText(item);
    if (!icon.isNull()) {
        action->setIcon(icon);
    }
    if (!key.isEmpty()) {
        action->setShortcut(key);
    }

    if (item.size() > _maximumTextSize) {
        _maximumTextSize = item.size();
    }

    _actions.push_back(action);

    /*if this is the first action we add, make it current*/
    if(_actions.size() == 1){
        setCurrentText(itemText(0));
    }
}

void ComboBox::setCurrentText(const QString& text){
    QString str(text);
    str.prepend("  ");
    str.append("  ");
    _currentText->setText(str);
    for (U32 i = 0; i < _actions.size(); ++i) {
        if(_actions[i]->text() == text){
            _currentIndex = i;
            break;
        }
    }
}
QString ComboBox::text() const{
    return _currentText->text();
}

int ComboBox::activeIndex() const{
    return _currentIndex;
}

void ComboBox::setCurrentIndex(int index){
    QString str;
    QString rawStr;
    if(index >= 0){
        str = _actions[index]->text();
        rawStr = str;
        /*before displaying,prepend and append the text by some spacing.
         This is a dirty way to do this but QLayout::addSpacing() doesn't preserve
         the same style for the label.*/
        int dsize = _maximumTextSize - str.size();
        dsize/=2;
        str.prepend("  ");
        for (int i = 0; i < dsize ; ++i) {str.prepend(" ");}
        str.append("  ");
        for (int i = 0; i < dsize ; ++i) {str.append(" ");}
    }else{
        str = "    ";
    }
    _currentIndex = index;
    _currentText->setText(str);
    emit currentIndexChanged(index);
    emit currentIndexChanged(rawStr);
}
void ComboBox::addSeparator(){
    _separators.push_back(_actions.size()-1);
}
void ComboBox::insertSeparator(int index){
    _separators.push_back(index);
}

QString ComboBox::itemText(int index) const{
    if(index < (int)_actions.size())
        return _actions[index]->text();
    else
        return "";
}

void ComboBox::removeItem(const QString& item){
    for (U32 i = 0; i < _actions.size(); ++i) {
        if (_actions[i]->text() == item) {
            _actions.erase(_actions.begin()+i);
            if (_currentText->text() == item) {
                setCurrentIndex(i-1);
            }
            /*adjust separators that were placed after this item*/
            for (U32 j = 0; j < _separators.size(); ++j) {
                if (_separators[j] >= (int)i) {
                    --_separators[j];
                }
            }
        }
    }
    /*we also need to re-calculate the maximum text size*/
    _maximumTextSize = 0;
    for (U32 i = 0; i < _actions.size(); ++i) {
        if (_actions[i]->text().size() > _maximumTextSize) {
            _maximumTextSize = _actions[i]->text().size();
        }
    }
}

void ComboBox::setItemText(int index,const QString& item){
    _actions[index]->setText(item);
    /*we also need to re-calculate the maximum text size*/
    _maximumTextSize = 0;
    for (U32 i = 0; i < _actions.size(); ++i) {
        if (_actions[i]->text().size() > _maximumTextSize) {
            _maximumTextSize = _actions[i]->text().size();
        }
    }
}

void ComboBox::setItemShortcut(int index,const QKeySequence& sequence){
    _actions[index]->setShortcut(sequence);
}

void ComboBox::setItemIcon(int index,const QIcon& icon){
    _actions[index]->setIcon(icon);
}
void ComboBox::disableItem(int index){
    _actions[index]->setEnabled(false);
}

void ComboBox::enableItem(int index){
    _actions[index]->setEnabled(true);
}

<commit_msg>add assert()s<commit_after>//  Powiter
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
*Created by Alexandre GAUTHIER-FOICHAT on 6/1/2012.
*contact: immarespond at gmail dot com
*
*/

#include "Gui/ComboBox.h"

#include <cassert>
#include <algorithm>
#include <QLayout>
#include <QLabel>
#include <QMenu>
#include <QStyle>

#include "Global/GlobalDefines.h"

using namespace std;
ComboBox::ComboBox(QWidget* parent):QFrame(parent),_currentIndex(0),_maximumTextSize(0),pressed(false){

    _mainLayout = new QHBoxLayout(this);
    _mainLayout->setSpacing(0);
    _mainLayout->setContentsMargins(0, 0, 0, 0);
    setLayout(_mainLayout);
    setFrameShape(QFrame::Box);

    _currentText = new QLabel(this);
    setCurrentIndex(-1);
    _currentText->setMinimumWidth(10);
    _mainLayout->addWidget(_currentText);

    _dropDownIcon = new QLabel(this);
    QImage imgC(IMAGES_PATH"combobox.png");
    QPixmap pixC=QPixmap::fromImage(imgC);
    pixC = pixC.scaled(10,10);
    _dropDownIcon->setPixmap(pixC);
    _mainLayout->addWidget(_dropDownIcon);

    _menu = new QMenu(this);
}

void ComboBox::paintEvent(QPaintEvent *e)
{
//    QStyleOption opt;
//    opt.init(this);
//    QPainter p(this);
//    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
    QFrame::paintEvent(e);
}

void ComboBox::mousePressEvent(QMouseEvent* e){
    QImage imgC(IMAGES_PATH"pressed_combobox.png");
    QPixmap pixC=QPixmap::fromImage(imgC);
    pixC = pixC.scaled(10,10);
    _dropDownIcon->setPixmap(pixC);
    setPressed(true);
    style()->unpolish(this);
    style()->polish(this);
    createMenu();
    QFrame::mousePressEvent(e);
}

void ComboBox::mouseReleaseEvent(QMouseEvent* e){
    QImage imgC(IMAGES_PATH"combobox.png");
    QPixmap pixC=QPixmap::fromImage(imgC);
    pixC = pixC.scaled(10,10);
    _dropDownIcon->setPixmap(pixC);
    setPressed(false);
    style()->unpolish(this);
    style()->polish(this);
    QFrame::mouseReleaseEvent(e);
}

void ComboBox::createMenu(){
    _menu->clear();
    for (U32 i = 0 ; i < _actions.size(); ++i) {
        for (U32 j = 0; j < _separators.size(); ++j) {
            if (_separators[j] == (int)i) {
                _menu->addSeparator();
                break;
            }
        }
        _menu->addAction(_actions[i]);
    }
    QAction* triggered = _menu->exec(this->mapToGlobal(QPoint(0,height())));
    for (U32 i = 0; i < _actions.size(); ++i) {
        if (triggered == _actions[i]) {
            setCurrentIndex(i);
            break;
        }
    }

    QImage imgC(IMAGES_PATH"combobox.png");
    QPixmap pixC=QPixmap::fromImage(imgC);
    pixC = pixC.scaled(10,10);
    _dropDownIcon->setPixmap(pixC);
    setPressed(false);
    style()->unpolish(this);
    style()->polish(this);

}

void ComboBox::insertItem(int index,const QString& item,QIcon icon,QKeySequence key){
    assert(index >= 0);
    QAction* action =  new QAction(this);
    action->setText(item);
    if (!icon.isNull()) {
        action->setIcon(icon);
    }
    if (!key.isEmpty()) {
        action->setShortcut(key);
    }
    if (item.size() > _maximumTextSize) {
        _maximumTextSize = item.size();
    }
    _actions.insert(_actions.begin()+index, action);
    /*if this is the first action we add, make it current*/
    if(_actions.size() == 1){
        setCurrentText(itemText(0));
    }

}

void ComboBox::addItem(const QString& item,QIcon icon ,QKeySequence key){
    QAction* action =  new QAction(this);
    action->setText(item);
    if (!icon.isNull()) {
        action->setIcon(icon);
    }
    if (!key.isEmpty()) {
        action->setShortcut(key);
    }

    if (item.size() > _maximumTextSize) {
        _maximumTextSize = item.size();
    }

    _actions.push_back(action);

    /*if this is the first action we add, make it current*/
    if(_actions.size() == 1){
        setCurrentText(itemText(0));
    }
}

void ComboBox::setCurrentText(const QString& text){
    QString str(text);
    str.prepend("  ");
    str.append("  ");
    assert(_currentText);
    _currentText->setText(str);
    for (U32 i = 0; i < _actions.size(); ++i) {
        if(_actions[i]->text() == text){
            _currentIndex = i;
            break;
        }
    }
}
QString ComboBox::text() const{
    return _currentText->text();
}

int ComboBox::activeIndex() const{
    return _currentIndex;
}

void ComboBox::setCurrentIndex(int index){
    QString str;
    QString rawStr;
    if(index >= 0){
        str = _actions[index]->text();
        rawStr = str;
        /*before displaying,prepend and append the text by some spacing.
         This is a dirty way to do this but QLayout::addSpacing() doesn't preserve
         the same style for the label.*/
        int dsize = _maximumTextSize - str.size();
        dsize/=2;
        str.prepend("  ");
        for (int i = 0; i < dsize ; ++i) {str.prepend(" ");}
        str.append("  ");
        for (int i = 0; i < dsize ; ++i) {str.append(" ");}
    }else{
        str = "    ";
    }
    _currentIndex = index;
    _currentText->setText(str);
    emit currentIndexChanged(index);
    emit currentIndexChanged(rawStr);
}
void ComboBox::addSeparator(){
    _separators.push_back(_actions.size()-1);
}
void ComboBox::insertSeparator(int index){
    assert(index >= 0);
    _separators.push_back(index);
}

QString ComboBox::itemText(int index) const{
    if(0 <= index && index < (int)_actions.size()) {
        assert(_actions[index]);
        return _actions[index]->text();
    } else {
        return "";
    }
}

void ComboBox::removeItem(const QString& item){
    for (U32 i = 0; i < _actions.size(); ++i) {
        assert(_actions[i]);
        if (_actions[i]->text() == item) {
            _actions.erase(_actions.begin()+i);
            assert(_currentText);
            if (_currentText->text() == item) {
                setCurrentIndex(i-1);
            }
            /*adjust separators that were placed after this item*/
            for (U32 j = 0; j < _separators.size(); ++j) {
                if (_separators[j] >= (int)i) {
                    --_separators[j];
                }
            }
        }
    }
    /*we also need to re-calculate the maximum text size*/
    _maximumTextSize = 0;
    for (U32 i = 0; i < _actions.size(); ++i) {
        assert(_actions[i]);
        if (_actions[i]->text().size() > _maximumTextSize) {
            _maximumTextSize = _actions[i]->text().size();
        }
    }
}

void ComboBox::setItemText(int index,const QString& item){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setText(item);
    /*we also need to re-calculate the maximum text size*/
    _maximumTextSize = 0;
    for (U32 i = 0; i < _actions.size(); ++i) {
        assert(_actions[i]);
        if (_actions[i]->text().size() > _maximumTextSize) {
            _maximumTextSize = _actions[i]->text().size();
        }
    }
}

void ComboBox::setItemShortcut(int index,const QKeySequence& sequence){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setShortcut(sequence);
}

void ComboBox::setItemIcon(int index,const QIcon& icon){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setIcon(icon);
}
void ComboBox::disableItem(int index){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setEnabled(false);
}

void ComboBox::enableItem(int index){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setEnabled(true);
}

<|endoftext|>


<commit_before>// Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
// Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.

#include <gearbox/core/Json.h>
#include <gearbox/core/JsonGenerator.h>

#include <limits>
#include <string>

#include <boost/lexical_cast.hpp>

using std::string;

namespace Gearbox {

    const std::string double_format = "%." + boost::lexical_cast<string>(std::numeric_limits<double>().digits10) + "g";

string Json::Generator::generate(const Json & json, bool beautify) {

    yajl_gen g = yajl_gen_alloc(NULL);
    if( beautify ) {
        yajl_gen_config(g, yajl_gen_beautify, 1);
        yajl_gen_config(g, yajl_gen_indent_string, "  ");
    }

    Json::Generator::generate(g, &json);

    const unsigned char * buf;
    size_t len;
    yajl_gen_get_buf(g, &buf, &len);
    string tmp(reinterpret_cast<const char *>(buf), len);
    yajl_gen_free(g);
    return tmp;
}

void Json::Generator::generate(yajl_gen g, const Json * j) {
    switch(j->impl_->type) {
    case Json::UNDEF:
        yajl_gen_null(g);
        break;
    case Json::BOOL:
        yajl_gen_bool(g, j->as<bool>());
        break;
    case Json::INT:
        yajl_gen_integer(g, j->as<int64_t>());
        break;
    case Json::DOUBLE: {

        // this used to work, but it seems yajl_gen_double now has precision issues
        // yajl_gen_double(g, j->as<double>());
        char i[32];
        int chars = sprintf(i, double_format.c_str(), j->as<double>());
        yajl_gen_number(g, i, chars);
    }
        break;
    case Json::STRING:
        yajl_gen_string(
            g,
            reinterpret_cast<const unsigned char *>(j->as<string>().c_str()),
            j->as<string>().size()
        );
        break;
    case Json::OBJECT:
        Json::Generator::generateObject(g,j);
        break;
    case Json::ARRAY:
        Json::Generator::generateArray(g,j);
        break;
    }
}

void Json::Generator::generateObject(yajl_gen g, const Json * j) {
    yajl_gen_map_open(g);

    Json::Object & o = j->as<Json::Object>();
    Json::Object::iterator i = o.begin();
    Json::Object::iterator e = o.end();
    for( ; i != e; ++i ) {
        yajl_gen_string(g, reinterpret_cast<const unsigned char *>(i->first.c_str()), i->first.size());
        Json::Generator::generate(g, i->second.get());
    }

    yajl_gen_map_close(g);
}

void Json::Generator::generateArray(yajl_gen g, const Json * j) {
    yajl_gen_array_open(g);
    Json::Array & a = j->as<Json::Array>();
    for( unsigned int i=0; i< a.size(); ++i ) {
        Json::Generator::generate(g, a[i].get());
    }
    yajl_gen_array_close(g);
}

} // namespace
<commit_msg>include stdio.h in JsonGenerator<commit_after>// Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
// Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.

#include <gearbox/core/Json.h>
#include <gearbox/core/JsonGenerator.h>

#include <limits>
#include <string>
#include <stdio.h>

#include <boost/lexical_cast.hpp>

using std::string;

namespace Gearbox {

    const std::string double_format = "%." + boost::lexical_cast<string>(std::numeric_limits<double>().digits10) + "g";

string Json::Generator::generate(const Json & json, bool beautify) {

    yajl_gen g = yajl_gen_alloc(NULL);
    if( beautify ) {
        yajl_gen_config(g, yajl_gen_beautify, 1);
        yajl_gen_config(g, yajl_gen_indent_string, "  ");
    }

    Json::Generator::generate(g, &json);

    const unsigned char * buf;
    size_t len;
    yajl_gen_get_buf(g, &buf, &len);
    string tmp(reinterpret_cast<const char *>(buf), len);
    yajl_gen_free(g);
    return tmp;
}

void Json::Generator::generate(yajl_gen g, const Json * j) {
    switch(j->impl_->type) {
    case Json::UNDEF:
        yajl_gen_null(g);
        break;
    case Json::BOOL:
        yajl_gen_bool(g, j->as<bool>());
        break;
    case Json::INT:
        yajl_gen_integer(g, j->as<int64_t>());
        break;
    case Json::DOUBLE: {

        // this used to work, but it seems yajl_gen_double now has precision issues
        // yajl_gen_double(g, j->as<double>());
        char i[32];
        int chars = sprintf(i, double_format.c_str(), j->as<double>());
        yajl_gen_number(g, i, chars);
    }
        break;
    case Json::STRING:
        yajl_gen_string(
            g,
            reinterpret_cast<const unsigned char *>(j->as<string>().c_str()),
            j->as<string>().size()
        );
        break;
    case Json::OBJECT:
        Json::Generator::generateObject(g,j);
        break;
    case Json::ARRAY:
        Json::Generator::generateArray(g,j);
        break;
    }
}

void Json::Generator::generateObject(yajl_gen g, const Json * j) {
    yajl_gen_map_open(g);

    Json::Object & o = j->as<Json::Object>();
    Json::Object::iterator i = o.begin();
    Json::Object::iterator e = o.end();
    for( ; i != e; ++i ) {
        yajl_gen_string(g, reinterpret_cast<const unsigned char *>(i->first.c_str()), i->first.size());
        Json::Generator::generate(g, i->second.get());
    }

    yajl_gen_map_close(g);
}

void Json::Generator::generateArray(yajl_gen g, const Json * j) {
    yajl_gen_array_open(g);
    Json::Array & a = j->as<Json::Array>();
    for( unsigned int i=0; i< a.size(); ++i ) {
        Json::Generator::generate(g, a[i].get());
    }
    yajl_gen_array_close(g);
}

} // namespace
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2017 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <grpc/impl/codegen/port_platform.h>

#include "src/core/lib/channel/channel_trace.h"
#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/channel/channelz_registry.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/mutex_lock.h"

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>

#include <cstring>

namespace grpc_core {
namespace channelz {
namespace {

// singleton instance of the registry.
ChannelzRegistry* g_channelz_registry = nullptr;

}  // anonymous namespace

void ChannelzRegistry::Init() { g_channelz_registry = New<ChannelzRegistry>(); }

void ChannelzRegistry::Shutdown() { Delete(g_channelz_registry); }

ChannelzRegistry* ChannelzRegistry::Default() {
  GPR_DEBUG_ASSERT(g_channelz_registry != nullptr);
  return g_channelz_registry;
}

ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); }

ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); }

intptr_t ChannelzRegistry::InternalRegister(BaseNode* node) {
  MutexLock lock(&mu_);
  entities_.push_back(node);
  return ++uuid_generator_;
}

void ChannelzRegistry::MaybePerformCompaction() {
  constexpr double kEmptinessTheshold = 1 / 3;
  double emptiness_ratio =
      double(num_empty_slots_) / double(entities_.capacity());
  if (emptiness_ratio > kEmptinessTheshold) {
    int front = 0;
    for (size_t i = 0; i < entities_.size(); ++i) {
      if (entities_[i] != nullptr) {
        entities_[front++] = entities_[i];
      }
    }
    for (int i = 0; i < num_empty_slots_; ++i) {
      entities_.pop_back();
    }
    num_empty_slots_ = 0;
  }
}

int ChannelzRegistry::FindByUuid(intptr_t target_uuid) {
  int left = 0;
  int right = entities_.size() - 1;
  while (left <= right) {
    int true_middle = left + (right - left) / 2;
    int first_non_null = true_middle;
    while (first_non_null < right && entities_[first_non_null] == nullptr) {
      first_non_null++;
    }
    if (entities_[first_non_null] == nullptr) {
      right = true_middle - 1;
      continue;
    }
    intptr_t uuid = entities_[first_non_null]->uuid();
    if (uuid == target_uuid) {
      return first_non_null;
    }
    if (uuid < target_uuid) {
      left = first_non_null + 1;
    } else {
      right = true_middle - 1;
    }
  }
  return -1;
}

void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
  GPR_ASSERT(uuid >= 1);
  MutexLock lock(&mu_);
  GPR_ASSERT(uuid <= uuid_generator_);
  int idx = FindByUuid(uuid);
  GPR_ASSERT(idx >= 0);
  entities_[idx] = nullptr;
  num_empty_slots_++;
  MaybePerformCompaction();
}

BaseNode* ChannelzRegistry::InternalGet(intptr_t uuid) {
  MutexLock lock(&mu_);
  if (uuid < 1 || uuid > uuid_generator_) {
    return nullptr;
  }
  int idx = FindByUuid(uuid);
  return idx < 0 ? nullptr : entities_[idx];
}

char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* json_iterator = nullptr;
  InlinedVector<BaseNode*, 10> top_level_channels;
  // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is
  // reserved). However, we want to support requests coming in with
  // start_channel_id=0, which signifies "give me everything." Hence this
  // funky looking line below.
  size_t start_idx = start_channel_id == 0 ? 0 : start_channel_id - 1;
  for (size_t i = start_idx; i < entities_.size(); ++i) {
    if (entities_[i] != nullptr &&
        entities_[i]->type() ==
            grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel) {
      top_level_channels.push_back(entities_[i]);
    }
  }
  if (!top_level_channels.empty()) {
    // create list of channels
    grpc_json* array_parent = grpc_json_create_child(
        nullptr, json, "channel", nullptr, GRPC_JSON_ARRAY, false);
    for (size_t i = 0; i < top_level_channels.size(); ++i) {
      grpc_json* channel_json = top_level_channels[i]->RenderJson();
      json_iterator =
          grpc_json_link_child(array_parent, channel_json, json_iterator);
    }
  }
  // For now we do not have any pagination rules. In the future we could
  // pick a constant for max_channels_sent for a GetTopChannels request.
  // Tracking: https://github.com/grpc/grpc/issues/16019.
  json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
                                         GRPC_JSON_TRUE, false);
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}

char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) {
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* json_iterator = nullptr;
  InlinedVector<BaseNode*, 10> servers;
  // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is
  // reserved). However, we want to support requests coming in with
  // start_server_id=0, which signifies "give me everything."
  size_t start_idx = start_server_id == 0 ? 0 : start_server_id - 1;
  for (size_t i = start_idx; i < entities_.size(); ++i) {
    if (entities_[i] != nullptr &&
        entities_[i]->type() ==
            grpc_core::channelz::BaseNode::EntityType::kServer) {
      servers.push_back(entities_[i]);
    }
  }
  if (!servers.empty()) {
    // create list of servers
    grpc_json* array_parent = grpc_json_create_child(
        nullptr, json, "server", nullptr, GRPC_JSON_ARRAY, false);
    for (size_t i = 0; i < servers.size(); ++i) {
      grpc_json* server_json = servers[i]->RenderJson();
      json_iterator =
          grpc_json_link_child(array_parent, server_json, json_iterator);
    }
  }
  // For now we do not have any pagination rules. In the future we could
  // pick a constant for max_channels_sent for a GetServers request.
  // Tracking: https://github.com/grpc/grpc/issues/16019.
  json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
                                         GRPC_JSON_TRUE, false);
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}

}  // namespace channelz
}  // namespace grpc_core

char* grpc_channelz_get_top_channels(intptr_t start_channel_id) {
  return grpc_core::channelz::ChannelzRegistry::GetTopChannels(
      start_channel_id);
}

char* grpc_channelz_get_servers(intptr_t start_server_id) {
  return grpc_core::channelz::ChannelzRegistry::GetServers(start_server_id);
}

char* grpc_channelz_get_channel(intptr_t channel_id) {
  grpc_core::channelz::BaseNode* channel_node =
      grpc_core::channelz::ChannelzRegistry::Get(channel_id);
  if (channel_node == nullptr ||
      (channel_node->type() !=
           grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel &&
       channel_node->type() !=
           grpc_core::channelz::BaseNode::EntityType::kInternalChannel)) {
    return nullptr;
  }
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* channel_json = channel_node->RenderJson();
  channel_json->key = "channel";
  grpc_json_link_child(json, channel_json, nullptr);
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}

char* grpc_channelz_get_subchannel(intptr_t subchannel_id) {
  grpc_core::channelz::BaseNode* subchannel_node =
      grpc_core::channelz::ChannelzRegistry::Get(subchannel_id);
  if (subchannel_node == nullptr ||
      subchannel_node->type() !=
          grpc_core::channelz::BaseNode::EntityType::kSubchannel) {
    return nullptr;
  }
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* subchannel_json = subchannel_node->RenderJson();
  subchannel_json->key = "subchannel";
  grpc_json_link_child(json, subchannel_json, nullptr);
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}

char* grpc_channelz_get_socket(intptr_t socket_id) {
  grpc_core::channelz::BaseNode* socket_node =
      grpc_core::channelz::ChannelzRegistry::Get(socket_id);
  if (socket_node == nullptr ||
      socket_node->type() !=
          grpc_core::channelz::BaseNode::EntityType::kSocket) {
    return nullptr;
  }
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* socket_json = socket_node->RenderJson();
  socket_json->key = "socket";
  grpc_json_link_child(json, socket_json, nullptr);
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}
<commit_msg>Fix objc build<commit_after>/*
 *
 * Copyright 2017 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <grpc/impl/codegen/port_platform.h>

#include "src/core/lib/channel/channel_trace.h"
#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/channel/channelz_registry.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/gprpp/mutex_lock.h"

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>

#include <cstring>

namespace grpc_core {
namespace channelz {
namespace {

// singleton instance of the registry.
ChannelzRegistry* g_channelz_registry = nullptr;

}  // anonymous namespace

void ChannelzRegistry::Init() { g_channelz_registry = New<ChannelzRegistry>(); }

void ChannelzRegistry::Shutdown() { Delete(g_channelz_registry); }

ChannelzRegistry* ChannelzRegistry::Default() {
  GPR_DEBUG_ASSERT(g_channelz_registry != nullptr);
  return g_channelz_registry;
}

ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); }

ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); }

intptr_t ChannelzRegistry::InternalRegister(BaseNode* node) {
  MutexLock lock(&mu_);
  entities_.push_back(node);
  return ++uuid_generator_;
}

void ChannelzRegistry::MaybePerformCompaction() {
  constexpr double kEmptinessTheshold = 1 / 3;
  double emptiness_ratio =
      double(num_empty_slots_) / double(entities_.capacity());
  if (emptiness_ratio > kEmptinessTheshold) {
    int front = 0;
    for (size_t i = 0; i < entities_.size(); ++i) {
      if (entities_[i] != nullptr) {
        entities_[front++] = entities_[i];
      }
    }
    for (int i = 0; i < num_empty_slots_; ++i) {
      entities_.pop_back();
    }
    num_empty_slots_ = 0;
  }
}

int ChannelzRegistry::FindByUuid(intptr_t target_uuid) {
  size_t left = 0;
  size_t right = entities_.size() - 1;
  while (left <= right) {
    size_t true_middle = left + (right - left) / 2;
    size_t first_non_null = true_middle;
    while (first_non_null < right && entities_[first_non_null] == nullptr) {
      first_non_null++;
    }
    if (entities_[first_non_null] == nullptr) {
      right = true_middle - 1;
      continue;
    }
    intptr_t uuid = entities_[first_non_null]->uuid();
    if (uuid == target_uuid) {
      return first_non_null;
    }
    if (uuid < target_uuid) {
      left = first_non_null + 1;
    } else {
      right = true_middle - 1;
    }
  }
  return -1;
}

void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
  GPR_ASSERT(uuid >= 1);
  MutexLock lock(&mu_);
  GPR_ASSERT(uuid <= uuid_generator_);
  int idx = FindByUuid(uuid);
  GPR_ASSERT(idx >= 0);
  entities_[idx] = nullptr;
  num_empty_slots_++;
  MaybePerformCompaction();
}

BaseNode* ChannelzRegistry::InternalGet(intptr_t uuid) {
  MutexLock lock(&mu_);
  if (uuid < 1 || uuid > uuid_generator_) {
    return nullptr;
  }
  int idx = FindByUuid(uuid);
  return idx < 0 ? nullptr : entities_[idx];
}

char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* json_iterator = nullptr;
  InlinedVector<BaseNode*, 10> top_level_channels;
  // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is
  // reserved). However, we want to support requests coming in with
  // start_channel_id=0, which signifies "give me everything." Hence this
  // funky looking line below.
  size_t start_idx = start_channel_id == 0 ? 0 : start_channel_id - 1;
  for (size_t i = start_idx; i < entities_.size(); ++i) {
    if (entities_[i] != nullptr &&
        entities_[i]->type() ==
            grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel) {
      top_level_channels.push_back(entities_[i]);
    }
  }
  if (!top_level_channels.empty()) {
    // create list of channels
    grpc_json* array_parent = grpc_json_create_child(
        nullptr, json, "channel", nullptr, GRPC_JSON_ARRAY, false);
    for (size_t i = 0; i < top_level_channels.size(); ++i) {
      grpc_json* channel_json = top_level_channels[i]->RenderJson();
      json_iterator =
          grpc_json_link_child(array_parent, channel_json, json_iterator);
    }
  }
  // For now we do not have any pagination rules. In the future we could
  // pick a constant for max_channels_sent for a GetTopChannels request.
  // Tracking: https://github.com/grpc/grpc/issues/16019.
  json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
                                         GRPC_JSON_TRUE, false);
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}

char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) {
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* json_iterator = nullptr;
  InlinedVector<BaseNode*, 10> servers;
  // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is
  // reserved). However, we want to support requests coming in with
  // start_server_id=0, which signifies "give me everything."
  size_t start_idx = start_server_id == 0 ? 0 : start_server_id - 1;
  for (size_t i = start_idx; i < entities_.size(); ++i) {
    if (entities_[i] != nullptr &&
        entities_[i]->type() ==
            grpc_core::channelz::BaseNode::EntityType::kServer) {
      servers.push_back(entities_[i]);
    }
  }
  if (!servers.empty()) {
    // create list of servers
    grpc_json* array_parent = grpc_json_create_child(
        nullptr, json, "server", nullptr, GRPC_JSON_ARRAY, false);
    for (size_t i = 0; i < servers.size(); ++i) {
      grpc_json* server_json = servers[i]->RenderJson();
      json_iterator =
          grpc_json_link_child(array_parent, server_json, json_iterator);
    }
  }
  // For now we do not have any pagination rules. In the future we could
  // pick a constant for max_channels_sent for a GetServers request.
  // Tracking: https://github.com/grpc/grpc/issues/16019.
  json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
                                         GRPC_JSON_TRUE, false);
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}

}  // namespace channelz
}  // namespace grpc_core

char* grpc_channelz_get_top_channels(intptr_t start_channel_id) {
  return grpc_core::channelz::ChannelzRegistry::GetTopChannels(
      start_channel_id);
}

char* grpc_channelz_get_servers(intptr_t start_server_id) {
  return grpc_core::channelz::ChannelzRegistry::GetServers(start_server_id);
}

char* grpc_channelz_get_channel(intptr_t channel_id) {
  grpc_core::channelz::BaseNode* channel_node =
      grpc_core::channelz::ChannelzRegistry::Get(channel_id);
  if (channel_node == nullptr ||
      (channel_node->type() !=
           grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel &&
       channel_node->type() !=
           grpc_core::channelz::BaseNode::EntityType::kInternalChannel)) {
    return nullptr;
  }
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* channel_json = channel_node->RenderJson();
  channel_json->key = "channel";
  grpc_json_link_child(json, channel_json, nullptr);
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}

char* grpc_channelz_get_subchannel(intptr_t subchannel_id) {
  grpc_core::channelz::BaseNode* subchannel_node =
      grpc_core::channelz::ChannelzRegistry::Get(subchannel_id);
  if (subchannel_node == nullptr ||
      subchannel_node->type() !=
          grpc_core::channelz::BaseNode::EntityType::kSubchannel) {
    return nullptr;
  }
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* subchannel_json = subchannel_node->RenderJson();
  subchannel_json->key = "subchannel";
  grpc_json_link_child(json, subchannel_json, nullptr);
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}

char* grpc_channelz_get_socket(intptr_t socket_id) {
  grpc_core::channelz::BaseNode* socket_node =
      grpc_core::channelz::ChannelzRegistry::Get(socket_id);
  if (socket_node == nullptr ||
      socket_node->type() !=
          grpc_core::channelz::BaseNode::EntityType::kSocket) {
    return nullptr;
  }
  grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
  grpc_json* json = top_level_json;
  grpc_json* socket_json = socket_node->RenderJson();
  socket_json->key = "socket";
  grpc_json_link_child(json, socket_json, nullptr);
  char* json_str = grpc_json_dump_to_string(top_level_json, 0);
  grpc_json_destroy(top_level_json);
  return json_str;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/importer/external_process_importer_host.h"

#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/importer/external_process_importer_client.h"
#include "chrome/browser/importer/in_process_importer_bridge.h"

ExternalProcessImporterHost::ExternalProcessImporterHost()
    : items_(0),
      cancelled_(false),
      import_process_launched_(false) {
}

void ExternalProcessImporterHost::Cancel() {
  cancelled_ = true;
  if (import_process_launched_)
    client_->Cancel();
  NotifyImportEnded();  // Tells the observer that we're done, and releases us.
}

void ExternalProcessImporterHost::StartImportSettings(
    const importer::SourceProfile& source_profile,
    Profile* target_profile,
    uint16 items,
    ProfileWriter* writer,
    bool first_run) {
  // We really only support importing from one host at a time.
  DCHECK(!profile_);
  DCHECK(target_profile);

  profile_ = target_profile;
  writer_ = writer;
  source_profile_ = &source_profile;
  items_ = items;

  ImporterHost::AddRef();  // Balanced in ImporterHost::NotifyImportEnded.

  CheckForFirefoxLock(source_profile, items, first_run);
  CheckForLoadedModels(items);

  InvokeTaskIfDone();
}

void ExternalProcessImporterHost::InvokeTaskIfDone() {
  if (waiting_for_bookmarkbar_model_ || !registrar_.IsEmpty() ||
      !is_source_readable_ || cancelled_)
    return;

  // This is the in-process half of the bridge, which catches data from the IPC
  // pipe and feeds it to the ProfileWriter. The external process half of the
  // bridge lives in the external process (see ProfileImportThread).
  // The ExternalProcessImporterClient created in the next line owns the bridge,
  // and will delete it.
  InProcessImporterBridge* bridge =
      new InProcessImporterBridge(writer_.get(), this);
  client_ = new ExternalProcessImporterClient(this, *source_profile_, items_,
                                              bridge);
  import_process_launched_ = true;
  client_->Start();
}

void ExternalProcessImporterHost::Loaded(BookmarkModel* model,
                                         bool ids_reassigned) {
  DCHECK(model->IsLoaded());
  model->RemoveObserver(this);
  waiting_for_bookmarkbar_model_ = false;
  installed_bookmark_observer_ = false;

  InvokeTaskIfDone();
}
<commit_msg>Coverity: No uninitialized fields in constructor. (CID 9446)<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/importer/external_process_importer_host.h"

#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/importer/external_process_importer_client.h"
#include "chrome/browser/importer/in_process_importer_bridge.h"

ExternalProcessImporterHost::ExternalProcessImporterHost()
    : client_(NULL),
      source_profile_(NULL),
      items_(0),
      cancelled_(false),
      import_process_launched_(false) {
}

void ExternalProcessImporterHost::Cancel() {
  cancelled_ = true;
  if (import_process_launched_)
    client_->Cancel();
  NotifyImportEnded();  // Tells the observer that we're done, and releases us.
}

void ExternalProcessImporterHost::StartImportSettings(
    const importer::SourceProfile& source_profile,
    Profile* target_profile,
    uint16 items,
    ProfileWriter* writer,
    bool first_run) {
  // We really only support importing from one host at a time.
  DCHECK(!profile_);
  DCHECK(target_profile);

  profile_ = target_profile;
  writer_ = writer;
  source_profile_ = &source_profile;
  items_ = items;

  ImporterHost::AddRef();  // Balanced in ImporterHost::NotifyImportEnded.

  CheckForFirefoxLock(source_profile, items, first_run);
  CheckForLoadedModels(items);

  InvokeTaskIfDone();
}

void ExternalProcessImporterHost::InvokeTaskIfDone() {
  if (waiting_for_bookmarkbar_model_ || !registrar_.IsEmpty() ||
      !is_source_readable_ || cancelled_)
    return;

  // This is the in-process half of the bridge, which catches data from the IPC
  // pipe and feeds it to the ProfileWriter. The external process half of the
  // bridge lives in the external process (see ProfileImportThread).
  // The ExternalProcessImporterClient created in the next line owns the bridge,
  // and will delete it.
  InProcessImporterBridge* bridge =
      new InProcessImporterBridge(writer_.get(), this);
  client_ = new ExternalProcessImporterClient(this, *source_profile_, items_,
                                              bridge);
  import_process_launched_ = true;
  client_->Start();
}

void ExternalProcessImporterHost::Loaded(BookmarkModel* model,
                                         bool ids_reassigned) {
  DCHECK(model->IsLoaded());
  model->RemoveObserver(this);
  waiting_for_bookmarkbar_model_ = false;
  installed_bookmark_observer_ = false;

  InvokeTaskIfDone();
}
<|endoftext|>


<commit_before>//  Natron
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
*Created by Alexandre GAUTHIER-FOICHAT on 6/1/2012.
*contact: immarespond at gmail dot com
*
*/

#include "Gui/ComboBox.h"

#include <cassert>
#include <algorithm>
#include <QLayout>
#include <QLabel>
#include <QStyle>
#include <QFont>
#include <QFontMetrics>
#include <QTextDocument> // for Qt::convertFromPlainText
#include <QMouseEvent>

#include "Gui/GuiApplicationManager.h"
#include "Gui/MenuWithToolTips.h"

using namespace Natron;

ComboBox::ComboBox(QWidget* parent)
: QFrame(parent)
, _currentIndex(0)
#if IS_MAXIMUMTEXTSIZE_USEFUL
, _maximumTextSize(0)
#endif
, pressed(false)
, animation(0)
{

    _mainLayout = new QHBoxLayout(this);
    _mainLayout->setSpacing(0);
    _mainLayout->setContentsMargins(0, 0, 0, 0);
    setLayout(_mainLayout);
    setFrameShape(QFrame::Box);

    _currentText = new QLabel(this);
    _currentText->setObjectName("ComboBoxLabel");
    setCurrentIndex(-1);
    _currentText->setMinimumWidth(10);
    _mainLayout->addWidget(_currentText);
    _currentText->setFixedHeight(fontMetrics().height() + 8);

    _dropDownIcon = new QLabel(this);
    _dropDownIcon->setObjectName("ComboBoxDropDownLabel");
    QPixmap pixC;
    appPTR->getIcon(NATRON_PIXMAP_COMBOBOX, &pixC);
    _dropDownIcon->setPixmap(pixC);
    _mainLayout->addWidget(_dropDownIcon);

    _menu = new MenuWithToolTips(this);

    setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);
}

void ComboBox::paintEvent(QPaintEvent *e)
{
//    QStyleOption opt;
//    opt.init(this);
//    QPainter p(this);
//    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
    QFrame::paintEvent(e);
}

void ComboBox::mousePressEvent(QMouseEvent* e){

    if (!e->buttons().testFlag(Qt::RightButton) && e->buttons().testFlag(Qt::LeftButton)) {
        QPixmap pixC;
        appPTR->getIcon(NATRON_PIXMAP_COMBOBOX_PRESSED, &pixC);
        _dropDownIcon->setPixmap(pixC);
        setPressed(true);
        style()->unpolish(this);
        style()->polish(this);
        createMenu();
        QFrame::mousePressEvent(e);

    }
}

void ComboBox::mouseReleaseEvent(QMouseEvent* e){
    QPixmap pixC;
    appPTR->getIcon(NATRON_PIXMAP_COMBOBOX, &pixC);
    _dropDownIcon->setPixmap(pixC);
    setPressed(false);
    style()->unpolish(this);
    style()->polish(this);
    QFrame::mouseReleaseEvent(e);
}

void ComboBox::createMenu(){
    _menu->clear();
    for (U32 i = 0 ; i < _actions.size(); ++i) {
        for (U32 j = 0; j < _separators.size(); ++j) {
            if (_separators[j] == (int)i) {
                _menu->addSeparator();
                break;
            }
        }
        _menu->addAction(_actions[i]);
    }
    QAction* triggered = _menu->exec(this->mapToGlobal(QPoint(0,height())));
    for (U32 i = 0; i < _actions.size(); ++i) {
        if (triggered == _actions[i]) {
            setCurrentIndex(i);
            break;
        }
    }

    QPixmap pixC;
    appPTR->getIcon(NATRON_PIXMAP_COMBOBOX, &pixC);
    _dropDownIcon->setPixmap(pixC);
    setPressed(false);
    style()->unpolish(this);
    style()->polish(this);

}
int ComboBox::count() const{
    return (int)_actions.size();
}
void ComboBox::insertItem(int index,const QString& item,QIcon icon,QKeySequence key,const QString& toolTip){
    assert(index >= 0);
    QAction* action =  new QAction(this);
    action->setText(item);
    if(!toolTip.isEmpty()){
        action->setToolTip(Qt::convertFromPlainText(toolTip, Qt::WhiteSpaceNormal));
    }
    if (!icon.isNull()) {
        action->setIcon(icon);
    }
    if (!key.isEmpty()) {
        action->setShortcut(key);
    }
#if IS_MAXIMUMTEXTSIZE_USEFUL
    if (item.size() > _maximumTextSize) {
        _maximumTextSize = item.size();
    }
#endif
    growMaximumWidthFromText(item);
    _actions.insert(_actions.begin()+index, action);
    /*if this is the first action we add, make it current*/
    if(_actions.size() == 1){
        setCurrentText_no_emit(itemText(0));
    }

}

void ComboBox::addItem(const QString& item,QIcon icon ,QKeySequence key,const QString& toolTip){
    QAction* action =  new QAction(this);

    action->setText(item);
    if (!icon.isNull()) {
        action->setIcon(icon);
    }
    if (!key.isEmpty()) {
        action->setShortcut(key);
    }
    if(!toolTip.isEmpty()){
        action->setToolTip(Qt::convertFromPlainText(toolTip, Qt::WhiteSpaceNormal));
    }
#if IS_MAXIMUMTEXTSIZE_USEFUL
    if (item.size() > _maximumTextSize) {
        _maximumTextSize = item.size();
    }
#endif
    growMaximumWidthFromText(item);
    _actions.push_back(action);

    /*if this is the first action we add, make it current*/
    if(_actions.size() == 1){
        setCurrentText_no_emit(itemText(0));
    }
}

void ComboBox::setCurrentText_no_emit(const QString& text) {
    setCurrentText_internal(text);
}

void ComboBox::setCurrentText(const QString& text) {
    int index = setCurrentText_internal(text);
    if (index != -1) {
        emit currentIndexChanged(index);
        emit currentIndexChanged(getCurrentIndexText());
    }
}

int ComboBox::setCurrentText_internal(const QString& text) {
    QString str(text);
    growMaximumWidthFromText(str);
    str.prepend("  ");
    str.append("  ");
    assert(_currentText);
    _currentText->setText(str);
    // if no action matches this text, set the index to a dirty value
    int index = -1;
    for (U32 i = 0; i < _actions.size(); ++i) {
        if(_actions[i]->text() == text){
            index = i;
            break;
        }
    }
    if (_currentIndex != index && index != -1) {
        _currentIndex = index;
        return index;
    }
    return -1;
}

void ComboBox::setMaximumWidthFromText(const QString& str)
{
    int w = _currentText->fontMetrics().width(str+"    ");
    setMaximumWidth(w);
}

void ComboBox::growMaximumWidthFromText(const QString& str)
{
    int w = _currentText->fontMetrics().width(str+"    ");
    if (w > maximumWidth()) {
        setMaximumWidth(w);
    }
}

int ComboBox::activeIndex() const{
    return _currentIndex;
}

QString ComboBox::getCurrentIndexText() const {
    assert(_currentIndex < (int)_actions.size());
    return _actions[_currentIndex]->text();
}

bool ComboBox::setCurrentIndex_internal(int index) {
    QString str;
    QString text;
    if (0 <= index && index < (int)_actions.size()) {
        text = _actions[index]->text();
    }
    str = text;
    /*before displaying,prepend and append the text by some spacing.
     This is a dirty way to do this but QLayout::addSpacing() doesn't preserve
     the same style for the label.*/
#if IS_MAXIMUMTEXTSIZE_USEFUL
    int dsize = _maximumTextSize - str.size();
    dsize/=2;
    str.prepend("  ");
    for (int i = 0; i < dsize ; ++i) {str.prepend(" ");}
    str.append("  ");
    for (int i = 0; i < dsize ; ++i) {str.append(" ");}
#endif
    str.prepend("  ");
    str.append("  ");
    _currentText->setText(str);

    if (_currentIndex != index && index != -1) {
        _currentIndex = index;
        return true;
    } else {
        return false;
    }

}

void ComboBox::setCurrentIndex(int index)
{
    if (setCurrentIndex_internal(index)) {
        ///emit the signal only if the entry changed
        emit currentIndexChanged(_currentIndex);
        emit currentIndexChanged(getCurrentIndexText());
    }
}

void ComboBox::setCurrentIndex_no_emit(int index) {
    setCurrentIndex_internal(index);
}

void ComboBox::addSeparator(){
    _separators.push_back(_actions.size()-1);
}
void ComboBox::insertSeparator(int index){
    assert(index >= 0);
    _separators.push_back(index);
}

QString ComboBox::itemText(int index) const{
    if(0 <= index && index < (int)_actions.size()) {
        assert(_actions[index]);
        return _actions[index]->text();
    } else {
        return "";
    }
}
int ComboBox::itemIndex(const QString& str) const{
    for (U32 i = 0; i < _actions.size(); ++i) {
        if (_actions[i]->text() == str) {
            return i;
        }
    }
    return -1;
}

void ComboBox::removeItem(const QString& item){
    for (U32 i = 0; i < _actions.size(); ++i) {
        assert(_actions[i]);
        if (_actions[i]->text() == item) {
            _actions.erase(_actions.begin()+i);
            assert(_currentText);
            if (_currentText->text() == item) {
                setCurrentIndex(i-1);
            }
            /*adjust separators that were placed after this item*/
            for (U32 j = 0; j < _separators.size(); ++j) {
                if (_separators[j] >= (int)i) {
                    --_separators[j];
                }
            }
        }
    }
#if IS_MAXIMUMTEXTSIZE_USEFUL
    /*we also need to re-calculate the maximum text size*/
    _maximumTextSize = 0;
    for (U32 i = 0; i < _actions.size(); ++i) {
        assert(_actions[i]);
        if (_actions[i]->text().size() > _maximumTextSize) {
            _maximumTextSize = _actions[i]->text().size();
        }
    }
#endif
}

void ComboBox::clear(){
    _actions.clear();
    _menu->clear();
    _separators.clear();
    _currentIndex = 0;
#if IS_MAXIMUMTEXTSIZE_USEFUL
    _maximumTextSize = 0;
#endif
}

void ComboBox::setItemText(int index,const QString& item){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setText(item);
    growMaximumWidthFromText(item);
#if IS_MAXIMUMTEXTSIZE_USEFUL
    /*we also need to re-calculate the maximum text size*/
    _maximumTextSize = 0;
    for (U32 i = 0; i < _actions.size(); ++i) {
        assert(_actions[i]);
        if (_actions[i]->text().size() > _maximumTextSize) {
            _maximumTextSize = _actions[i]->text().size();
        }
    }
#endif
}

void ComboBox::setItemShortcut(int index,const QKeySequence& sequence){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setShortcut(sequence);
}

void ComboBox::setItemIcon(int index,const QIcon& icon){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setIcon(icon);
}
void ComboBox::disableItem(int index){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setEnabled(false);
}

void ComboBox::enableItem(int index){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setEnabled(true);
}

void ComboBox::setAnimation(int i){
    animation = i;
    style()->unpolish(this);
    style()->polish(this);
    repaint();
}
<commit_msg>ComboBox: fix warning<commit_after>//  Natron
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
*Created by Alexandre GAUTHIER-FOICHAT on 6/1/2012.
*contact: immarespond at gmail dot com
*
*/

#include "Gui/ComboBox.h"

#include <cassert>
#include <algorithm>
#include <QLayout>
#include <QLabel>
#include <QStyle>
#include <QFont>
#include <QFontMetrics>
#include <QTextDocument> // for Qt::convertFromPlainText
CLANG_DIAG_OFF(unused-private-field)
#include <QMouseEvent>
CLANG_DIAG_ON(unused-private-field)

#include "Gui/GuiApplicationManager.h"
#include "Gui/MenuWithToolTips.h"

using namespace Natron;

ComboBox::ComboBox(QWidget* parent)
: QFrame(parent)
, _currentIndex(0)
#if IS_MAXIMUMTEXTSIZE_USEFUL
, _maximumTextSize(0)
#endif
, pressed(false)
, animation(0)
{

    _mainLayout = new QHBoxLayout(this);
    _mainLayout->setSpacing(0);
    _mainLayout->setContentsMargins(0, 0, 0, 0);
    setLayout(_mainLayout);
    setFrameShape(QFrame::Box);

    _currentText = new QLabel(this);
    _currentText->setObjectName("ComboBoxLabel");
    setCurrentIndex(-1);
    _currentText->setMinimumWidth(10);
    _mainLayout->addWidget(_currentText);
    _currentText->setFixedHeight(fontMetrics().height() + 8);

    _dropDownIcon = new QLabel(this);
    _dropDownIcon->setObjectName("ComboBoxDropDownLabel");
    QPixmap pixC;
    appPTR->getIcon(NATRON_PIXMAP_COMBOBOX, &pixC);
    _dropDownIcon->setPixmap(pixC);
    _mainLayout->addWidget(_dropDownIcon);

    _menu = new MenuWithToolTips(this);

    setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);
}

void ComboBox::paintEvent(QPaintEvent *e)
{
//    QStyleOption opt;
//    opt.init(this);
//    QPainter p(this);
//    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
    QFrame::paintEvent(e);
}

void ComboBox::mousePressEvent(QMouseEvent* e){

    if (!e->buttons().testFlag(Qt::RightButton) && e->buttons().testFlag(Qt::LeftButton)) {
        QPixmap pixC;
        appPTR->getIcon(NATRON_PIXMAP_COMBOBOX_PRESSED, &pixC);
        _dropDownIcon->setPixmap(pixC);
        setPressed(true);
        style()->unpolish(this);
        style()->polish(this);
        createMenu();
        QFrame::mousePressEvent(e);

    }
}

void ComboBox::mouseReleaseEvent(QMouseEvent* e){
    QPixmap pixC;
    appPTR->getIcon(NATRON_PIXMAP_COMBOBOX, &pixC);
    _dropDownIcon->setPixmap(pixC);
    setPressed(false);
    style()->unpolish(this);
    style()->polish(this);
    QFrame::mouseReleaseEvent(e);
}

void ComboBox::createMenu(){
    _menu->clear();
    for (U32 i = 0 ; i < _actions.size(); ++i) {
        for (U32 j = 0; j < _separators.size(); ++j) {
            if (_separators[j] == (int)i) {
                _menu->addSeparator();
                break;
            }
        }
        _menu->addAction(_actions[i]);
    }
    QAction* triggered = _menu->exec(this->mapToGlobal(QPoint(0,height())));
    for (U32 i = 0; i < _actions.size(); ++i) {
        if (triggered == _actions[i]) {
            setCurrentIndex(i);
            break;
        }
    }

    QPixmap pixC;
    appPTR->getIcon(NATRON_PIXMAP_COMBOBOX, &pixC);
    _dropDownIcon->setPixmap(pixC);
    setPressed(false);
    style()->unpolish(this);
    style()->polish(this);

}
int ComboBox::count() const{
    return (int)_actions.size();
}
void ComboBox::insertItem(int index,const QString& item,QIcon icon,QKeySequence key,const QString& toolTip){
    assert(index >= 0);
    QAction* action =  new QAction(this);
    action->setText(item);
    if(!toolTip.isEmpty()){
        action->setToolTip(Qt::convertFromPlainText(toolTip, Qt::WhiteSpaceNormal));
    }
    if (!icon.isNull()) {
        action->setIcon(icon);
    }
    if (!key.isEmpty()) {
        action->setShortcut(key);
    }
#if IS_MAXIMUMTEXTSIZE_USEFUL
    if (item.size() > _maximumTextSize) {
        _maximumTextSize = item.size();
    }
#endif
    growMaximumWidthFromText(item);
    _actions.insert(_actions.begin()+index, action);
    /*if this is the first action we add, make it current*/
    if(_actions.size() == 1){
        setCurrentText_no_emit(itemText(0));
    }

}

void ComboBox::addItem(const QString& item,QIcon icon ,QKeySequence key,const QString& toolTip){
    QAction* action =  new QAction(this);

    action->setText(item);
    if (!icon.isNull()) {
        action->setIcon(icon);
    }
    if (!key.isEmpty()) {
        action->setShortcut(key);
    }
    if(!toolTip.isEmpty()){
        action->setToolTip(Qt::convertFromPlainText(toolTip, Qt::WhiteSpaceNormal));
    }
#if IS_MAXIMUMTEXTSIZE_USEFUL
    if (item.size() > _maximumTextSize) {
        _maximumTextSize = item.size();
    }
#endif
    growMaximumWidthFromText(item);
    _actions.push_back(action);

    /*if this is the first action we add, make it current*/
    if(_actions.size() == 1){
        setCurrentText_no_emit(itemText(0));
    }
}

void ComboBox::setCurrentText_no_emit(const QString& text) {
    setCurrentText_internal(text);
}

void ComboBox::setCurrentText(const QString& text) {
    int index = setCurrentText_internal(text);
    if (index != -1) {
        emit currentIndexChanged(index);
        emit currentIndexChanged(getCurrentIndexText());
    }
}

int ComboBox::setCurrentText_internal(const QString& text) {
    QString str(text);
    growMaximumWidthFromText(str);
    str.prepend("  ");
    str.append("  ");
    assert(_currentText);
    _currentText->setText(str);
    // if no action matches this text, set the index to a dirty value
    int index = -1;
    for (U32 i = 0; i < _actions.size(); ++i) {
        if(_actions[i]->text() == text){
            index = i;
            break;
        }
    }
    if (_currentIndex != index && index != -1) {
        _currentIndex = index;
        return index;
    }
    return -1;
}

void ComboBox::setMaximumWidthFromText(const QString& str)
{
    int w = _currentText->fontMetrics().width(str+"    ");
    setMaximumWidth(w);
}

void ComboBox::growMaximumWidthFromText(const QString& str)
{
    int w = _currentText->fontMetrics().width(str+"    ");
    if (w > maximumWidth()) {
        setMaximumWidth(w);
    }
}

int ComboBox::activeIndex() const{
    return _currentIndex;
}

QString ComboBox::getCurrentIndexText() const {
    assert(_currentIndex < (int)_actions.size());
    return _actions[_currentIndex]->text();
}

bool ComboBox::setCurrentIndex_internal(int index) {
    QString str;
    QString text;
    if (0 <= index && index < (int)_actions.size()) {
        text = _actions[index]->text();
    }
    str = text;
    /*before displaying,prepend and append the text by some spacing.
     This is a dirty way to do this but QLayout::addSpacing() doesn't preserve
     the same style for the label.*/
#if IS_MAXIMUMTEXTSIZE_USEFUL
    int dsize = _maximumTextSize - str.size();
    dsize/=2;
    str.prepend("  ");
    for (int i = 0; i < dsize ; ++i) {str.prepend(" ");}
    str.append("  ");
    for (int i = 0; i < dsize ; ++i) {str.append(" ");}
#endif
    str.prepend("  ");
    str.append("  ");
    _currentText->setText(str);

    if (_currentIndex != index && index != -1) {
        _currentIndex = index;
        return true;
    } else {
        return false;
    }

}

void ComboBox::setCurrentIndex(int index)
{
    if (setCurrentIndex_internal(index)) {
        ///emit the signal only if the entry changed
        emit currentIndexChanged(_currentIndex);
        emit currentIndexChanged(getCurrentIndexText());
    }
}

void ComboBox::setCurrentIndex_no_emit(int index) {
    setCurrentIndex_internal(index);
}

void ComboBox::addSeparator(){
    _separators.push_back(_actions.size()-1);
}
void ComboBox::insertSeparator(int index){
    assert(index >= 0);
    _separators.push_back(index);
}

QString ComboBox::itemText(int index) const{
    if(0 <= index && index < (int)_actions.size()) {
        assert(_actions[index]);
        return _actions[index]->text();
    } else {
        return "";
    }
}
int ComboBox::itemIndex(const QString& str) const{
    for (U32 i = 0; i < _actions.size(); ++i) {
        if (_actions[i]->text() == str) {
            return i;
        }
    }
    return -1;
}

void ComboBox::removeItem(const QString& item){
    for (U32 i = 0; i < _actions.size(); ++i) {
        assert(_actions[i]);
        if (_actions[i]->text() == item) {
            _actions.erase(_actions.begin()+i);
            assert(_currentText);
            if (_currentText->text() == item) {
                setCurrentIndex(i-1);
            }
            /*adjust separators that were placed after this item*/
            for (U32 j = 0; j < _separators.size(); ++j) {
                if (_separators[j] >= (int)i) {
                    --_separators[j];
                }
            }
        }
    }
#if IS_MAXIMUMTEXTSIZE_USEFUL
    /*we also need to re-calculate the maximum text size*/
    _maximumTextSize = 0;
    for (U32 i = 0; i < _actions.size(); ++i) {
        assert(_actions[i]);
        if (_actions[i]->text().size() > _maximumTextSize) {
            _maximumTextSize = _actions[i]->text().size();
        }
    }
#endif
}

void ComboBox::clear(){
    _actions.clear();
    _menu->clear();
    _separators.clear();
    _currentIndex = 0;
#if IS_MAXIMUMTEXTSIZE_USEFUL
    _maximumTextSize = 0;
#endif
}

void ComboBox::setItemText(int index,const QString& item){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setText(item);
    growMaximumWidthFromText(item);
#if IS_MAXIMUMTEXTSIZE_USEFUL
    /*we also need to re-calculate the maximum text size*/
    _maximumTextSize = 0;
    for (U32 i = 0; i < _actions.size(); ++i) {
        assert(_actions[i]);
        if (_actions[i]->text().size() > _maximumTextSize) {
            _maximumTextSize = _actions[i]->text().size();
        }
    }
#endif
}

void ComboBox::setItemShortcut(int index,const QKeySequence& sequence){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setShortcut(sequence);
}

void ComboBox::setItemIcon(int index,const QIcon& icon){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setIcon(icon);
}
void ComboBox::disableItem(int index){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setEnabled(false);
}

void ComboBox::enableItem(int index){
    assert(0 <= index && index < (int)_actions.size());
    assert(_actions[index]);
    _actions[index]->setEnabled(true);
}

void ComboBox::setAnimation(int i){
    animation = i;
    style()->unpolish(this);
    style()->polish(this);
    repaint();
}
<|endoftext|>


<commit_before>//  illarionserver - server for the game Illarion
//  Copyright 2011 Illarion e.V.
//
//  This file is part of illarionserver.
//
//  illarionserver is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  illarionserver is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License
//  along with illarionserver.  If not, see <http://www.gnu.org/licenses/>.

#include "WaypointList.hpp"
#include "World.hpp"
#include "Field.hpp"
#include "Logger.hpp"

WaypointList::WaypointList(Character *movechar) : _movechar(movechar) {

}

const std::list<position> &WaypointList::getWaypoints() const {
    return positions;
}

void WaypointList::addWaypoint(const position &pos) {
    positions.push_back(pos);
}

bool WaypointList::getNextWaypoint(position &pos) const {
    if (positions.empty()) {
        return false;
    }

    pos = positions.front();
    return true;
}

void WaypointList::clear() {
    positions.clear();
}

bool WaypointList::checkPosition() {
    if (positions.empty()) {
        return false;
    }

    if (_movechar->getPosition() == positions.front()) {
        positions.pop_front();
    }

    return true;
}

bool WaypointList::recalcStepList() {
    if (!checkPosition()) {
        return false;
    }

    if (positions.empty()) {
        return false;
    }

    steplist.clear();
    _movechar->getStepList(positions.front(), steplist);
    return (!steplist.empty());
}

bool WaypointList::makeMove() {
    if (steplist.empty()) {
        if (!recalcStepList()) {
            return false;
        }
    }

    if (!_movechar->move(steplist.front())) {
        return recalcStepList();
    }

    steplist.pop_front();
    return true;
}
<commit_msg>Abort route if destination cannot be reached<commit_after>//  illarionserver - server for the game Illarion
//  Copyright 2011 Illarion e.V.
//
//  This file is part of illarionserver.
//
//  illarionserver is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Affero General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  illarionserver is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Affero General Public License for more details.
//
//  You should have received a copy of the GNU Affero General Public License
//  along with illarionserver.  If not, see <http://www.gnu.org/licenses/>.

#include "WaypointList.hpp"
#include "World.hpp"
#include "Field.hpp"
#include "Logger.hpp"

WaypointList::WaypointList(Character *movechar) : _movechar(movechar) {

}

const std::list<position> &WaypointList::getWaypoints() const {
    return positions;
}

void WaypointList::addWaypoint(const position &pos) {
    positions.push_back(pos);
}

bool WaypointList::getNextWaypoint(position &pos) const {
    if (positions.empty()) {
        return false;
    }

    pos = positions.front();
    return true;
}

void WaypointList::clear() {
    positions.clear();
}

bool WaypointList::checkPosition() {
    if (positions.empty()) {
        return false;
    }

    if (_movechar->getPosition() == positions.front()) {
        positions.pop_front();
    }

    return true;
}

bool WaypointList::recalcStepList() {
    if (!checkPosition()) {
        return false;
    }

    if (positions.empty()) {
        return false;
    }

    steplist.clear();
    _movechar->getStepList(positions.front(), steplist);
    return (!steplist.empty());
}

bool WaypointList::makeMove() {
    if (steplist.empty()) {
        if (!recalcStepList()) {
            return false;
        }
    }

    if (!_movechar->move(steplist.front())) {
        return steplist.size() > 1 && recalcStepList();
    }

    steplist.pop_front();
    return true;
}
<|endoftext|>