<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "breakwindow.h"

#include "debuggeractions.h"
#include "debuggermanager.h"
#include "ui_breakcondition.h"
#include "ui_breakbyfunction.h"

#include <utils/qtcassert.h>

#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QFileInfoList>

#include <QtGui/QAction>
#include <QtGui/QHeaderView>
#include <QtGui/QKeyEvent>
#include <QtGui/QMenu>
#include <QtGui/QResizeEvent>
#include <QtGui/QItemSelectionModel>
#include <QtGui/QToolButton>
#include <QtGui/QTreeView>

using Debugger::Internal::BreakWindow;

///////////////////////////////////////////////////////////////////////
//
// BreakByFunctionDialog
//
///////////////////////////////////////////////////////////////////////

class BreakByFunctionDialog : public QDialog, Ui::BreakByFunctionDialog
{
public:
    explicit BreakByFunctionDialog(QWidget *parent)
      : QDialog(parent)
    {
        setupUi(this);
        connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
        connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    }
    QString functionName() const { return functionLineEdit->text(); }
};

///////////////////////////////////////////////////////////////////////
//
// BreakWindow
//
///////////////////////////////////////////////////////////////////////

BreakWindow::BreakWindow(Debugger::DebuggerManager *manager)
  : m_manager(manager), m_alwaysResizeColumnsToContents(false)
{
    QAction *act = theDebuggerAction(UseAlternatingRowColors);
    setWindowTitle(tr("Breakpoints"));
    setWindowIcon(QIcon(":/debugger/images/debugger_breakpoints.png"));
    setAlternatingRowColors(act->isChecked());
    setRootIsDecorated(false);
    setIconSize(QSize(10, 10));
    setSelectionMode(QAbstractItemView::ExtendedSelection);

    connect(this, SIGNAL(activated(QModelIndex)),
        this, SLOT(rowActivated(QModelIndex)));
    connect(act, SIGNAL(toggled(bool)),
        this, SLOT(setAlternatingRowColorsHelper(bool)));
    connect(theDebuggerAction(UseAddressInBreakpointsView), SIGNAL(toggled(bool)),
        this, SLOT(showAddressColumn(bool)));
}

void BreakWindow::showAddressColumn(bool on)
{
    setColumnHidden(6, !on);
}

static QModelIndexList normalizeIndexes(const QModelIndexList &list)
{
    QModelIndexList res;
    foreach (const QModelIndex &idx, list)
        if (idx.column() == 0)
            res.append(idx);
    return res;
}

void BreakWindow::keyPressEvent(QKeyEvent *ev)
{
    if (ev->key() == Qt::Key_Delete) {
        QItemSelectionModel *sm = selectionModel();
        QTC_ASSERT(sm, return);
        QModelIndexList si = sm->selectedIndexes();
        if (si.isEmpty())
            si.append(currentIndex().sibling(currentIndex().row(), 0));
        deleteBreakpoints(normalizeIndexes(si));
    }
    QTreeView::keyPressEvent(ev);
}

void BreakWindow::resizeEvent(QResizeEvent *ev)
{
    QTreeView::resizeEvent(ev);
}

void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
{
    QMenu menu;
    const QAbstractItemModel *itemModel = model();
    QItemSelectionModel *sm = selectionModel();
    QTC_ASSERT(sm, return);
    QModelIndexList si = sm->selectedIndexes();
    QModelIndex indexUnderMouse = indexAt(ev->pos());
    if (si.isEmpty() && indexUnderMouse.isValid())
        si.append(indexUnderMouse.sibling(indexUnderMouse.row(), 0));
    si = normalizeIndexes(si);

    const int rowCount = itemModel->rowCount();
    const unsigned engineCapabilities = m_manager->debuggerCapabilities();

    QAction *deleteAction = new QAction(tr("Delete Breakpoint"), &menu);
    deleteAction->setEnabled(si.size() > 0);

    QAction *deleteAllAction = new QAction(tr("Delete All Breakpoints"), &menu);
    deleteAllAction->setEnabled(si.size() > 0);

    // Delete by file: Find indices of breakpoints of the same file.
    QAction *deleteByFileAction = 0;
    QList<int> breakPointsOfFile;
    if (indexUnderMouse.isValid()) {
        const QModelIndex index = indexUnderMouse.sibling(indexUnderMouse.row(), 2);
        const QString file = itemModel->data(index).toString();
        if (!file.isEmpty()) {
            for (int i = 0; i < rowCount; i++)
                if (itemModel->data(itemModel->index(i, 2)).toString() == file)
                    breakPointsOfFile.push_back(i);
            if (breakPointsOfFile.size() > 1) {
                deleteByFileAction =
                    new QAction(tr("Delete Breakpoints of \"%1\"").arg(file), &menu);
                deleteByFileAction->setEnabled(true);
            }
        }
    }
    if (!deleteByFileAction) {
        deleteByFileAction = new QAction(tr("Delete Breakpoints of File"), &menu);
        deleteByFileAction->setEnabled(false);
    }

    QAction *adjustColumnAction =
        new QAction(tr("Adjust Column Widths to Contents"), &menu);

    QAction *alwaysAdjustAction =
        new QAction(tr("Always Adjust Column Widths to Contents"), &menu);

    alwaysAdjustAction->setCheckable(true);
    alwaysAdjustAction->setChecked(m_alwaysResizeColumnsToContents);

    QAction *editConditionAction =
        new QAction(tr("Edit Condition..."), &menu);
    editConditionAction->setEnabled(si.size() > 0);

    QAction *synchronizeAction =
        new QAction(tr("Synchronize Breakpoints"), &menu);
    synchronizeAction->setEnabled(
        Debugger::DebuggerManager::instance()->debuggerActionsEnabled());

    QModelIndex idx0 = (si.size() ? si.front() : QModelIndex());
    QModelIndex idx2 = idx0.sibling(idx0.row(), 2);
    bool enabled = si.isEmpty() || itemModel->data(idx0, Qt::UserRole).toBool();
    const QString str5 = enabled ? tr("Disable Breakpoint") : tr("Enable Breakpoint");
    QAction *toggleEnabledAction = new QAction(str5, &menu);
    toggleEnabledAction->setEnabled(si.size() > 0);

    const bool fullpath = si.isEmpty() || itemModel->data(idx2, Qt::UserRole).toBool();
    const QString str6 = fullpath ? tr("Use Short Path") : tr("Use Full Path");
    QAction *pathAction = new QAction(str6, &menu);
    pathAction->setEnabled(si.size() > 0);

    QAction *breakAtFunctionAction =
        new QAction(tr("Set Breakpoint at Function..."), this);
    QAction *breakAtMainAction =
        new QAction(tr("Set Breakpoint at Function \"main\""), this);
    QAction *breakAtThrowAction =
        new QAction(tr("Set Breakpoint at \"throw\""), this);
    QAction *breakAtCatchAction =
        new QAction(tr("Set Breakpoint at \"catch\""), this);

    menu.addAction(deleteAction);
    menu.addAction(editConditionAction);
    menu.addAction(toggleEnabledAction);
    menu.addAction(pathAction);
    menu.addSeparator();
    menu.addAction(deleteAllAction);
    menu.addAction(deleteByFileAction);
    menu.addSeparator();
    menu.addAction(synchronizeAction);
    menu.addSeparator();
    menu.addAction(breakAtFunctionAction);
    menu.addAction(breakAtMainAction);
    if (engineCapabilities & BreakOnThrowAndCatchCapability) {
        menu.addAction(breakAtThrowAction);
        menu.addAction(breakAtCatchAction);
    }
    menu.addSeparator();
    menu.addAction(theDebuggerAction(UseToolTipsInBreakpointsView));
    menu.addAction(theDebuggerAction(UseAddressInBreakpointsView));
    menu.addAction(adjustColumnAction);
    menu.addAction(alwaysAdjustAction);
    menu.addSeparator();
    menu.addAction(theDebuggerAction(SettingsDialog));

    QAction *act = menu.exec(ev->globalPos());

    if (act == deleteAction) {
        deleteBreakpoints(si);
    } else if (act == deleteAllAction) {
        QList<int> allRows;
        for (int i = 0; i < rowCount; i++)
            allRows.push_back(i);
        deleteBreakpoints(allRows);
    }  else if (act == deleteByFileAction)
        deleteBreakpoints(breakPointsOfFile);
    else if (act == adjustColumnAction)
        resizeColumnsToContents();
    else if (act == alwaysAdjustAction)
        setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
    else if (act == editConditionAction)
        editConditions(si);
    else if (act == synchronizeAction)
        emit breakpointSynchronizationRequested();
    else if (act == toggleEnabledAction)
        setBreakpointsEnabled(si, !enabled);
    else if (act == pathAction)
        setBreakpointsFullPath(si, !enabled);
    else if (act == breakAtFunctionAction) {
        BreakByFunctionDialog dlg(this);
        if (dlg.exec())
            emit breakByFunctionRequested(dlg.functionName());
    } else if (act == breakAtMainAction)
        emit breakByFunctionMainRequested();
     else if (act == breakAtThrowAction)
        emit breakByFunctionRequested("__cxa_throw");
     else if (act == breakAtCatchAction)
        emit breakByFunctionRequested("__cxa_begin_catch");
}

void BreakWindow::setBreakpointsEnabled(const QModelIndexList &list, bool enabled)
{
    foreach (const QModelIndex &idx, list)
        model()->setData(idx, enabled);
    emit breakpointSynchronizationRequested();
}

void BreakWindow::setBreakpointsFullPath(const QModelIndexList &list, bool fullpath)
{
    foreach (const QModelIndex &idx, list) {
        QModelIndex idx2 = idx.sibling(idx.row(), 2);
        model()->setData(idx2, fullpath);
    }
    emit breakpointSynchronizationRequested();
}

void BreakWindow::deleteBreakpoints(const QModelIndexList &indexes)
{
    QTC_ASSERT(!indexes.isEmpty(), return);
    QList<int> list;
    foreach (const QModelIndex &idx, indexes)
        list.append(idx.row());
    deleteBreakpoints(list);
}

void BreakWindow::deleteBreakpoints(QList<int> list)
{
    if (list.empty())
        return;
    const int firstRow = list.front();
    qSort(list.begin(), list.end());
    for (int i = list.size(); --i >= 0; )
        emit breakpointDeleted(list.at(i));

    const int row = qMin(firstRow, model()->rowCount() - 1);
    if (row >= 0)
        setCurrentIndex(model()->index(row, 0));
}

void BreakWindow::editConditions(const QModelIndexList &list)
{
    QDialog dlg(this);
    Ui::BreakCondition ui;
    ui.setupUi(&dlg);

    QTC_ASSERT(!list.isEmpty(), return);
    QModelIndex idx = list.front();
    int row = idx.row();
    dlg.setWindowTitle(tr("Conditions on Breakpoint %1").arg(row));
    ui.lineEditCondition->setText(model()->data(idx.sibling(row, 4)).toString());
    ui.spinBoxIgnoreCount->setValue(model()->data(idx.sibling(row, 5)).toInt());

    if (dlg.exec() == QDialog::Rejected)
        return;

    foreach (const QModelIndex &idx, list) {
        model()->setData(idx.sibling(idx.row(), 4), ui.lineEditCondition->text());
        model()->setData(idx.sibling(idx.row(), 5), ui.spinBoxIgnoreCount->value());
    }
}

void BreakWindow::resizeColumnsToContents()
{
    for (int i = model()->columnCount(); --i >= 0; )
        resizeColumnToContents(i);
}

void BreakWindow::setAlwaysResizeColumnsToContents(bool on)
{
    m_alwaysResizeColumnsToContents = on;
    QHeaderView::ResizeMode mode = on
        ? QHeaderView::ResizeToContents : QHeaderView::Interactive;
    for (int i = model()->columnCount(); --i >= 0; )
        header()->setResizeMode(i, mode);
}

void BreakWindow::rowActivated(const QModelIndex &idx)
{
    emit breakpointActivated(idx.row());
}

<commit_msg>debugger: use the right flag to select using full paths for breakpoints<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "breakwindow.h"

#include "debuggeractions.h"
#include "debuggermanager.h"
#include "ui_breakcondition.h"
#include "ui_breakbyfunction.h"

#include <utils/qtcassert.h>

#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QFileInfoList>

#include <QtGui/QAction>
#include <QtGui/QHeaderView>
#include <QtGui/QKeyEvent>
#include <QtGui/QMenu>
#include <QtGui/QResizeEvent>
#include <QtGui/QItemSelectionModel>
#include <QtGui/QToolButton>
#include <QtGui/QTreeView>

using Debugger::Internal::BreakWindow;

///////////////////////////////////////////////////////////////////////
//
// BreakByFunctionDialog
//
///////////////////////////////////////////////////////////////////////

class BreakByFunctionDialog : public QDialog, Ui::BreakByFunctionDialog
{
public:
    explicit BreakByFunctionDialog(QWidget *parent)
      : QDialog(parent)
    {
        setupUi(this);
        connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
        connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    }
    QString functionName() const { return functionLineEdit->text(); }
};

///////////////////////////////////////////////////////////////////////
//
// BreakWindow
//
///////////////////////////////////////////////////////////////////////

BreakWindow::BreakWindow(Debugger::DebuggerManager *manager)
  : m_manager(manager), m_alwaysResizeColumnsToContents(false)
{
    QAction *act = theDebuggerAction(UseAlternatingRowColors);
    setWindowTitle(tr("Breakpoints"));
    setWindowIcon(QIcon(":/debugger/images/debugger_breakpoints.png"));
    setAlternatingRowColors(act->isChecked());
    setRootIsDecorated(false);
    setIconSize(QSize(10, 10));
    setSelectionMode(QAbstractItemView::ExtendedSelection);

    connect(this, SIGNAL(activated(QModelIndex)),
        this, SLOT(rowActivated(QModelIndex)));
    connect(act, SIGNAL(toggled(bool)),
        this, SLOT(setAlternatingRowColorsHelper(bool)));
    connect(theDebuggerAction(UseAddressInBreakpointsView), SIGNAL(toggled(bool)),
        this, SLOT(showAddressColumn(bool)));
}

void BreakWindow::showAddressColumn(bool on)
{
    setColumnHidden(6, !on);
}

static QModelIndexList normalizeIndexes(const QModelIndexList &list)
{
    QModelIndexList res;
    foreach (const QModelIndex &idx, list)
        if (idx.column() == 0)
            res.append(idx);
    return res;
}

void BreakWindow::keyPressEvent(QKeyEvent *ev)
{
    if (ev->key() == Qt::Key_Delete) {
        QItemSelectionModel *sm = selectionModel();
        QTC_ASSERT(sm, return);
        QModelIndexList si = sm->selectedIndexes();
        if (si.isEmpty())
            si.append(currentIndex().sibling(currentIndex().row(), 0));
        deleteBreakpoints(normalizeIndexes(si));
    }
    QTreeView::keyPressEvent(ev);
}

void BreakWindow::resizeEvent(QResizeEvent *ev)
{
    QTreeView::resizeEvent(ev);
}

void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
{
    QMenu menu;
    const QAbstractItemModel *itemModel = model();
    QItemSelectionModel *sm = selectionModel();
    QTC_ASSERT(sm, return);
    QModelIndexList si = sm->selectedIndexes();
    QModelIndex indexUnderMouse = indexAt(ev->pos());
    if (si.isEmpty() && indexUnderMouse.isValid())
        si.append(indexUnderMouse.sibling(indexUnderMouse.row(), 0));
    si = normalizeIndexes(si);

    const int rowCount = itemModel->rowCount();
    const unsigned engineCapabilities = m_manager->debuggerCapabilities();

    QAction *deleteAction = new QAction(tr("Delete Breakpoint"), &menu);
    deleteAction->setEnabled(si.size() > 0);

    QAction *deleteAllAction = new QAction(tr("Delete All Breakpoints"), &menu);
    deleteAllAction->setEnabled(si.size() > 0);

    // Delete by file: Find indices of breakpoints of the same file.
    QAction *deleteByFileAction = 0;
    QList<int> breakPointsOfFile;
    if (indexUnderMouse.isValid()) {
        const QModelIndex index = indexUnderMouse.sibling(indexUnderMouse.row(), 2);
        const QString file = itemModel->data(index).toString();
        if (!file.isEmpty()) {
            for (int i = 0; i < rowCount; i++)
                if (itemModel->data(itemModel->index(i, 2)).toString() == file)
                    breakPointsOfFile.push_back(i);
            if (breakPointsOfFile.size() > 1) {
                deleteByFileAction =
                    new QAction(tr("Delete Breakpoints of \"%1\"").arg(file), &menu);
                deleteByFileAction->setEnabled(true);
            }
        }
    }
    if (!deleteByFileAction) {
        deleteByFileAction = new QAction(tr("Delete Breakpoints of File"), &menu);
        deleteByFileAction->setEnabled(false);
    }

    QAction *adjustColumnAction =
        new QAction(tr("Adjust Column Widths to Contents"), &menu);

    QAction *alwaysAdjustAction =
        new QAction(tr("Always Adjust Column Widths to Contents"), &menu);

    alwaysAdjustAction->setCheckable(true);
    alwaysAdjustAction->setChecked(m_alwaysResizeColumnsToContents);

    QAction *editConditionAction =
        new QAction(tr("Edit Condition..."), &menu);
    editConditionAction->setEnabled(si.size() > 0);

    QAction *synchronizeAction =
        new QAction(tr("Synchronize Breakpoints"), &menu);
    synchronizeAction->setEnabled(
        Debugger::DebuggerManager::instance()->debuggerActionsEnabled());

    QModelIndex idx0 = (si.size() ? si.front() : QModelIndex());
    QModelIndex idx2 = idx0.sibling(idx0.row(), 2);
    bool enabled = si.isEmpty() || itemModel->data(idx0, Qt::UserRole).toBool();
    const QString str5 = enabled ? tr("Disable Breakpoint") : tr("Enable Breakpoint");
    QAction *toggleEnabledAction = new QAction(str5, &menu);
    toggleEnabledAction->setEnabled(si.size() > 0);

    const bool fullpath = si.isEmpty() || itemModel->data(idx2, Qt::UserRole).toBool();
    const QString str6 = fullpath ? tr("Use Short Path") : tr("Use Full Path");
    QAction *pathAction = new QAction(str6, &menu);
    pathAction->setEnabled(si.size() > 0);

    QAction *breakAtFunctionAction =
        new QAction(tr("Set Breakpoint at Function..."), this);
    QAction *breakAtMainAction =
        new QAction(tr("Set Breakpoint at Function \"main\""), this);
    QAction *breakAtThrowAction =
        new QAction(tr("Set Breakpoint at \"throw\""), this);
    QAction *breakAtCatchAction =
        new QAction(tr("Set Breakpoint at \"catch\""), this);

    menu.addAction(deleteAction);
    menu.addAction(editConditionAction);
    menu.addAction(toggleEnabledAction);
    menu.addAction(pathAction);
    menu.addSeparator();
    menu.addAction(deleteAllAction);
    menu.addAction(deleteByFileAction);
    menu.addSeparator();
    menu.addAction(synchronizeAction);
    menu.addSeparator();
    menu.addAction(breakAtFunctionAction);
    menu.addAction(breakAtMainAction);
    if (engineCapabilities & BreakOnThrowAndCatchCapability) {
        menu.addAction(breakAtThrowAction);
        menu.addAction(breakAtCatchAction);
    }
    menu.addSeparator();
    menu.addAction(theDebuggerAction(UseToolTipsInBreakpointsView));
    menu.addAction(theDebuggerAction(UseAddressInBreakpointsView));
    menu.addAction(adjustColumnAction);
    menu.addAction(alwaysAdjustAction);
    menu.addSeparator();
    menu.addAction(theDebuggerAction(SettingsDialog));

    QAction *act = menu.exec(ev->globalPos());

    if (act == deleteAction) {
        deleteBreakpoints(si);
    } else if (act == deleteAllAction) {
        QList<int> allRows;
        for (int i = 0; i < rowCount; i++)
            allRows.push_back(i);
        deleteBreakpoints(allRows);
    }  else if (act == deleteByFileAction)
        deleteBreakpoints(breakPointsOfFile);
    else if (act == adjustColumnAction)
        resizeColumnsToContents();
    else if (act == alwaysAdjustAction)
        setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
    else if (act == editConditionAction)
        editConditions(si);
    else if (act == synchronizeAction)
        emit breakpointSynchronizationRequested();
    else if (act == toggleEnabledAction)
        setBreakpointsEnabled(si, !enabled);
    else if (act == pathAction)
        setBreakpointsFullPath(si, !fullpath);
    else if (act == breakAtFunctionAction) {
        BreakByFunctionDialog dlg(this);
        if (dlg.exec())
            emit breakByFunctionRequested(dlg.functionName());
    } else if (act == breakAtMainAction)
        emit breakByFunctionMainRequested();
     else if (act == breakAtThrowAction)
        emit breakByFunctionRequested("__cxa_throw");
     else if (act == breakAtCatchAction)
        emit breakByFunctionRequested("__cxa_begin_catch");
}

void BreakWindow::setBreakpointsEnabled(const QModelIndexList &list, bool enabled)
{
    foreach (const QModelIndex &idx, list)
        model()->setData(idx, enabled);
    emit breakpointSynchronizationRequested();
}

void BreakWindow::setBreakpointsFullPath(const QModelIndexList &list, bool fullpath)
{
    foreach (const QModelIndex &idx, list) {
        QModelIndex idx2 = idx.sibling(idx.row(), 2);
        model()->setData(idx2, fullpath);
    }
    emit breakpointSynchronizationRequested();
}

void BreakWindow::deleteBreakpoints(const QModelIndexList &indexes)
{
    QTC_ASSERT(!indexes.isEmpty(), return);
    QList<int> list;
    foreach (const QModelIndex &idx, indexes)
        list.append(idx.row());
    deleteBreakpoints(list);
}

void BreakWindow::deleteBreakpoints(QList<int> list)
{
    if (list.empty())
        return;
    const int firstRow = list.front();
    qSort(list.begin(), list.end());
    for (int i = list.size(); --i >= 0; )
        emit breakpointDeleted(list.at(i));

    const int row = qMin(firstRow, model()->rowCount() - 1);
    if (row >= 0)
        setCurrentIndex(model()->index(row, 0));
}

void BreakWindow::editConditions(const QModelIndexList &list)
{
    QDialog dlg(this);
    Ui::BreakCondition ui;
    ui.setupUi(&dlg);

    QTC_ASSERT(!list.isEmpty(), return);
    QModelIndex idx = list.front();
    int row = idx.row();
    dlg.setWindowTitle(tr("Conditions on Breakpoint %1").arg(row));
    ui.lineEditCondition->setText(model()->data(idx.sibling(row, 4)).toString());
    ui.spinBoxIgnoreCount->setValue(model()->data(idx.sibling(row, 5)).toInt());

    if (dlg.exec() == QDialog::Rejected)
        return;

    foreach (const QModelIndex &idx, list) {
        model()->setData(idx.sibling(idx.row(), 4), ui.lineEditCondition->text());
        model()->setData(idx.sibling(idx.row(), 5), ui.spinBoxIgnoreCount->value());
    }
}

void BreakWindow::resizeColumnsToContents()
{
    for (int i = model()->columnCount(); --i >= 0; )
        resizeColumnToContents(i);
}

void BreakWindow::setAlwaysResizeColumnsToContents(bool on)
{
    m_alwaysResizeColumnsToContents = on;
    QHeaderView::ResizeMode mode = on
        ? QHeaderView::ResizeToContents : QHeaderView::Interactive;
    for (int i = model()->columnCount(); --i >= 0; )
        header()->setResizeMode(i, mode);
}

void BreakWindow::rowActivated(const QModelIndex &idx)
{
    emit breakpointActivated(idx.row());
}

<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>

#include "PntRunner.h"

#include "GeoDataDocument.h"
#include "MarbleDebug.h"

#include <QtCore/QFile>
#include <QtCore/QFileInfo>

namespace Marble
{

// distance of 180deg in arcminutes
const qreal INT2RAD = M_PI / 10800.0;

PntRunner::PntRunner(QObject *parent) :
    MarbleAbstractRunner(parent)
{
}

PntRunner::~PntRunner()
{
}

GeoDataFeature::GeoDataVisualCategory PntRunner::category() const
{
    return GeoDataFeature::Folder;
}

void PntRunner::parseFile( const QString &fileName, DocumentRole role = UnknownDocument )
{
    QFileInfo fileinfo( fileName );
    if( fileinfo.suffix().compare( "pnt", Qt::CaseInsensitive ) != 0 ) {
        emit parsingFinished( 0 );
        return;
    }

    QFile  file( fileName );
    if ( !file.exists() ) {
        qWarning( "File does not exist!" );
        emit parsingFinished( 0 );
        return;
    }

    file.open( QIODevice::ReadOnly );
    QDataStream stream( &file );  // read the data serialized from the file
    stream.setByteOrder( QDataStream::LittleEndian );

    GeoDataDocument *document = new GeoDataDocument();
    document->setDocumentRole( role );

    GeoDataPlacemark  *placemark = 0;
    placemark = new GeoDataPlacemark;
    document->append( placemark );
    GeoDataMultiGeometry *geom = new GeoDataMultiGeometry;
    placemark->setGeometry( geom );

    int count = 0;
    bool error = false;
    while( !stream.atEnd() || error ){
        short  header = -1;
        short  iLat = -5400 - 1;
        short  iLon = -10800 - 1;

        stream >> header >> iLat >> iLon;

        // make sure iLat is within valid range
        if ( !( -5400 <= iLat && iLat <= 5400 ) ) {
            mDebug() << Q_FUNC_INFO << "invalid iLat =" << iLat << "(" << ( iLat * INT2RAD ) * RAD2DEG << ") in dataset" << count << "of file" << fileName;
            error = true;
        }

        // make sure iLon is within valid range
        if ( !( -10800 <= iLon && iLon <= 10800 ) ) {
            mDebug() << Q_FUNC_INFO << "invalid iLon =" << iLon << "(" << ( iLon * INT2RAD ) * RAD2DEG << ") in dataset" << count << "of file" << fileName;
            error = true;
        }

        if ( header < 1 ) {
            /* invalid header */
            mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
            error = true;
            break;
        }
        else if ( header <= 5 ) {
            /* header represents level of detail */
            /* nothing to do */
        }
        else if ( header < 1000 ) {
            /* invalid header */
            mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
            error = true;
            break;
        }
        else if ( header < 2000 ) {
            /* header represents start of coastline */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 4000 ) {
            /* header represents start of country border */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 5000 ) {
            /* header represents start of internal political border */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 6000 ) {
            /* header represents start of island */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 7000 ) {
            /* header represents start of lake */
            geom->append( new GeoDataLineString );
        }
        else if ( header < 8000 ) {
            /* header represents start of river */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 9000 ) {
            /* custom header represents start of glaciers, lakes or islands */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 10000 ) {
            /* custom header represents start of political borders */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 14000 ) {
            /* invalid header */
            mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
            error = true;
            break;
        }
        else if ( header < 15000 ) {
            /* custom header represents start of political borders */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 19000 ) {
            /* invalid header */
            mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
            error = true;
            break;
        }
        else if ( header < 20000 ) {
            /* custom header represents start of dateline */
            geom->append( new GeoDataLineString );
        }
        else {
            /* invalid header */
            mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
            error = true;
            break;
        }

        GeoDataLineString *polyline = static_cast<GeoDataLineString*>(geom->child(geom->size()-1));

        // Transforming Range of Coordinates to iLat [0,ARCMINUTE] , iLon [0,2 * ARCMINUTE]
        polyline->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD, (qreal)(iLat) * INT2RAD,
                                                  0.0, GeoDataCoordinates::Radian, 5 ) );

        ++count;
    }

    file.close();
    if ( geom->size() == 0 || error ) {
        delete document;
        document = 0;
    }

    emit parsingFinished( document );
}

}

#include "PntRunner.moc"
<commit_msg>respect level of detail also in the PntRunner<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>

#include "PntRunner.h"

#include "GeoDataDocument.h"
#include "MarbleDebug.h"

#include <QtCore/QFile>
#include <QtCore/QFileInfo>

namespace Marble
{

// distance of 180deg in arcminutes
const qreal INT2RAD = M_PI / 10800.0;

PntRunner::PntRunner(QObject *parent) :
    MarbleAbstractRunner(parent)
{
}

PntRunner::~PntRunner()
{
}

GeoDataFeature::GeoDataVisualCategory PntRunner::category() const
{
    return GeoDataFeature::Folder;
}

void PntRunner::parseFile( const QString &fileName, DocumentRole role = UnknownDocument )
{
    QFileInfo fileinfo( fileName );
    if( fileinfo.suffix().compare( "pnt", Qt::CaseInsensitive ) != 0 ) {
        emit parsingFinished( 0 );
        return;
    }

    QFile  file( fileName );
    if ( !file.exists() ) {
        qWarning( "File does not exist!" );
        emit parsingFinished( 0 );
        return;
    }

    file.open( QIODevice::ReadOnly );
    QDataStream stream( &file );  // read the data serialized from the file
    stream.setByteOrder( QDataStream::LittleEndian );

    GeoDataDocument *document = new GeoDataDocument();
    document->setDocumentRole( role );

    GeoDataPlacemark  *placemark = 0;
    placemark = new GeoDataPlacemark;
    document->append( placemark );
    GeoDataMultiGeometry *geom = new GeoDataMultiGeometry;
    placemark->setGeometry( geom );

    int count = 0;
    bool error = false;
    while( !stream.atEnd() || error ){
        short  header = -1;
        short  iLat = -5400 - 1;
        short  iLon = -10800 - 1;

        stream >> header >> iLat >> iLon;

        // make sure iLat is within valid range
        if ( !( -5400 <= iLat && iLat <= 5400 ) ) {
            mDebug() << Q_FUNC_INFO << "invalid iLat =" << iLat << "(" << ( iLat * INT2RAD ) * RAD2DEG << ") in dataset" << count << "of file" << fileName;
            error = true;
        }

        // make sure iLon is within valid range
        if ( !( -10800 <= iLon && iLon <= 10800 ) ) {
            mDebug() << Q_FUNC_INFO << "invalid iLon =" << iLon << "(" << ( iLon * INT2RAD ) * RAD2DEG << ") in dataset" << count << "of file" << fileName;
            error = true;
        }

        if ( header < 1 ) {
            /* invalid header */
            mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
            error = true;
            break;
        }
        else if ( header <= 5 ) {
            /* header represents level of detail */
            /* nothing to do */
        }
        else if ( header < 1000 ) {
            /* invalid header */
            mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
            error = true;
            break;
        }
        else if ( header < 2000 ) {
            /* header represents start of coastline */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 4000 ) {
            /* header represents start of country border */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 5000 ) {
            /* header represents start of internal political border */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 6000 ) {
            /* header represents start of island */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 7000 ) {
            /* header represents start of lake */
            geom->append( new GeoDataLineString );
        }
        else if ( header < 8000 ) {
            /* header represents start of river */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 9000 ) {
            /* custom header represents start of glaciers, lakes or islands */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 10000 ) {
            /* custom header represents start of political borders */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 14000 ) {
            /* invalid header */
            mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
            error = true;
            break;
        }
        else if ( header < 15000 ) {
            /* custom header represents start of political borders */
            geom->append( new GeoDataLinearRing );
        }
        else if ( header < 19000 ) {
            /* invalid header */
            mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
            error = true;
            break;
        }
        else if ( header < 20000 ) {
            /* custom header represents start of dateline */
            geom->append( new GeoDataLineString );
        }
        else {
            /* invalid header */
            mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
            error = true;
            break;
        }

        GeoDataLineString *polyline = static_cast<GeoDataLineString*>(geom->child(geom->size()-1));

        // Transforming Range of Coordinates to iLat [0,ARCMINUTE] , iLon [0,2 * ARCMINUTE]
        polyline->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD, (qreal)(iLat) * INT2RAD,
                                              0.0, GeoDataCoordinates::Radian,
                                              qMin( 5, (int)header  ) ) ); // if 1 <= header <= 5, header contains level of detail
                                                                           // else pick most sparse level of detail, which equals 5

        ++count;
    }

    file.close();
    if ( geom->size() == 0 || error ) {
        delete document;
        document = 0;
    }

    emit parsingFinished( document );
}

}

#include "PntRunner.moc"
<|endoftext|>


<commit_before>/*

Copyright (c) 2015, Project OSRM contributors
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.

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 HOLDER 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.

*/

#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/spirit/include/qi.hpp>

#include <osrm/route_parameters.hpp>

#include "../algorithms/polyline_compressor.hpp"

RouteParameters::RouteParameters()
    : zoom_level(18), print_instructions(false), alternate_route(true), geometry(true),
      compression(true), deprecatedAPI(false), uturn_default(false), classify(false),
      matching_beta(5), gps_precision(5), check_sum(-1), num_results(1)
{
}

void RouteParameters::setZoomLevel(const short level)
{
    if (18 >= level && 0 <= level)
    {
        zoom_level = level;
    }
}

void RouteParameters::setNumberOfResults(const short number)
{
    if (number > 0 && number <= 100)
    {
        num_results = number;
    }
}

void RouteParameters::setAlternateRouteFlag(const bool flag) { alternate_route = flag; }

void RouteParameters::setUTurn(const bool flag)
{
    // the API grammar should make sure this never happens
    BOOST_ASSERT(!uturns.empty());
    uturns.back() = flag;
}

void RouteParameters::setAllUTurns(const bool flag)
{
    // if the flag flips the default, then we erase everything.
    if (flag)
    {
        uturn_default = flag;
        uturns.clear();
        uturns.resize(coordinates.size(), uturn_default);
    }
}

void RouteParameters::setDeprecatedAPIFlag(const std::string &) { deprecatedAPI = true; }

void RouteParameters::setChecksum(const unsigned sum) { check_sum = sum; }

void RouteParameters::setInstructionFlag(const bool flag) { print_instructions = flag; }

void RouteParameters::setService(const std::string &service_string) { service = service_string; }

void RouteParameters::setClassify(const bool flag) { classify = flag; }

void RouteParameters::setMatchingBeta(const double beta) { matching_beta = beta; }

void RouteParameters::setGPSPrecision(const double precision) { gps_precision = precision; }

void RouteParameters::setOutputFormat(const std::string &format) { output_format = format; }

void RouteParameters::setJSONpParameter(const std::string &parameter)
{
    jsonp_parameter = parameter;
}

void RouteParameters::addHint(const std::string &hint)
{
    hints.resize(coordinates.size());
    if (!hints.empty())
    {
        hints.back() = hint;
    }
}

void RouteParameters::addTimestamp(const unsigned timestamp)
{
    timestamps.resize(coordinates.size());
    if (!timestamps.empty())
    {
        timestamps.back() = timestamp;
    }
}

void RouteParameters::addBearing(
    const boost::fusion::vector<int, boost::optional<int>> &received_bearing,
        boost::spirit::qi::unused_type /* unused */, bool& pass)
{
    pass = false;
    const int bearing = boost::fusion::at_c<0>(received_bearing);
    const boost::optional<int> range = boost::fusion::at_c<1>(received_bearing);
    if (bearing < 0 || bearing > 359) return;
    if (range && (*range < 0 || *range > 180)) return;
    bearings.emplace_back(std::make_pair(bearing,range));
    pass = true;
}

void RouteParameters::setLanguage(const std::string &language_string)
{
    language = language_string;
}

void RouteParameters::setGeometryFlag(const bool flag) { geometry = flag; }

void RouteParameters::setCompressionFlag(const bool flag) { compression = flag; }

void RouteParameters::addCoordinate(
    const boost::fusion::vector<double, double> &received_coordinates)
{
    coordinates.emplace_back(
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
    is_source.emplace_back(true);
    is_destination.emplace_back(true);
    uturns.push_back(uturn_default);
}

void RouteParameters::addDestination(
    const boost::fusion::vector<double, double> &received_coordinates)
{
    coordinates.emplace_back(
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
    is_source.emplace_back(false);
    is_destination.emplace_back(true);
    uturns.push_back(uturn_default);
}

void RouteParameters::addSource(
    const boost::fusion::vector<double, double> &received_coordinates)
{
    coordinates.emplace_back(
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
    is_source.emplace_back(true);
    is_destination.emplace_back(false);
    uturns.push_back(uturn_default);
}

void RouteParameters::getCoordinatesFromGeometry(const std::string &geometry_string)
{
    PolylineCompressor pc;
    coordinates = pc.decode_string(geometry_string);
}

<commit_msg>std::vector<bool>::emplace_back -> push_back for gcc 4.8<commit_after>/*

Copyright (c) 2015, Project OSRM contributors
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.

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 HOLDER 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.

*/

#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/spirit/include/qi.hpp>

#include <osrm/route_parameters.hpp>

#include "../algorithms/polyline_compressor.hpp"

RouteParameters::RouteParameters()
    : zoom_level(18), print_instructions(false), alternate_route(true), geometry(true),
      compression(true), deprecatedAPI(false), uturn_default(false), classify(false),
      matching_beta(5), gps_precision(5), check_sum(-1), num_results(1)
{
}

void RouteParameters::setZoomLevel(const short level)
{
    if (18 >= level && 0 <= level)
    {
        zoom_level = level;
    }
}

void RouteParameters::setNumberOfResults(const short number)
{
    if (number > 0 && number <= 100)
    {
        num_results = number;
    }
}

void RouteParameters::setAlternateRouteFlag(const bool flag) { alternate_route = flag; }

void RouteParameters::setUTurn(const bool flag)
{
    // the API grammar should make sure this never happens
    BOOST_ASSERT(!uturns.empty());
    uturns.back() = flag;
}

void RouteParameters::setAllUTurns(const bool flag)
{
    // if the flag flips the default, then we erase everything.
    if (flag)
    {
        uturn_default = flag;
        uturns.clear();
        uturns.resize(coordinates.size(), uturn_default);
    }
}

void RouteParameters::setDeprecatedAPIFlag(const std::string &) { deprecatedAPI = true; }

void RouteParameters::setChecksum(const unsigned sum) { check_sum = sum; }

void RouteParameters::setInstructionFlag(const bool flag) { print_instructions = flag; }

void RouteParameters::setService(const std::string &service_string) { service = service_string; }

void RouteParameters::setClassify(const bool flag) { classify = flag; }

void RouteParameters::setMatchingBeta(const double beta) { matching_beta = beta; }

void RouteParameters::setGPSPrecision(const double precision) { gps_precision = precision; }

void RouteParameters::setOutputFormat(const std::string &format) { output_format = format; }

void RouteParameters::setJSONpParameter(const std::string &parameter)
{
    jsonp_parameter = parameter;
}

void RouteParameters::addHint(const std::string &hint)
{
    hints.resize(coordinates.size());
    if (!hints.empty())
    {
        hints.back() = hint;
    }
}

void RouteParameters::addTimestamp(const unsigned timestamp)
{
    timestamps.resize(coordinates.size());
    if (!timestamps.empty())
    {
        timestamps.back() = timestamp;
    }
}

void RouteParameters::addBearing(
    const boost::fusion::vector<int, boost::optional<int>> &received_bearing,
        boost::spirit::qi::unused_type /* unused */, bool& pass)
{
    pass = false;
    const int bearing = boost::fusion::at_c<0>(received_bearing);
    const boost::optional<int> range = boost::fusion::at_c<1>(received_bearing);
    if (bearing < 0 || bearing > 359) return;
    if (range && (*range < 0 || *range > 180)) return;
    bearings.emplace_back(std::make_pair(bearing,range));
    pass = true;
}

void RouteParameters::setLanguage(const std::string &language_string)
{
    language = language_string;
}

void RouteParameters::setGeometryFlag(const bool flag) { geometry = flag; }

void RouteParameters::setCompressionFlag(const bool flag) { compression = flag; }

void RouteParameters::addCoordinate(
    const boost::fusion::vector<double, double> &received_coordinates)
{
    coordinates.emplace_back(
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
    is_source.push_back(true);
    is_destination.push_back(true);
    uturns.push_back(uturn_default);
}

void RouteParameters::addDestination(
    const boost::fusion::vector<double, double> &received_coordinates)
{
    coordinates.emplace_back(
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
    is_source.push_back(false);
    is_destination.push_back(true);
    uturns.push_back(uturn_default);
}

void RouteParameters::addSource(
    const boost::fusion::vector<double, double> &received_coordinates)
{
    coordinates.emplace_back(
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
        static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
    is_source.push_back(true);
    is_destination.push_back(false);
    uturns.push_back(uturn_default);
}

void RouteParameters::getCoordinatesFromGeometry(const std::string &geometry_string)
{
    PolylineCompressor pc;
    coordinates = pc.decode_string(geometry_string);
}

<|endoftext|>


<commit_before>#include <ossim/parallel/ossimJobMultiThreadQueue.h>

ossimJobMultiThreadQueue::ossimJobMultiThreadQueue(std::shared_ptr<ossimJobQueue> q,
                                                   ossim_uint32 nThreads)
:m_jobQueue(q?q:std::make_shared<ossimJobQueue>())
{
   setNumberOfThreads(nThreads);
}

ossimJobMultiThreadQueue::~ossimJobMultiThreadQueue()
{
   setJobQueue(0);
   cancel();
   waitForCompletion();
   m_threadQueueList.clear();
}

std::shared_ptr<ossimJobQueue> ossimJobMultiThreadQueue::getJobQueue()
{
   std::lock_guard<std::mutex> lock(m_mutex);
   return m_jobQueue;
}
const std::shared_ptr<ossimJobQueue> ossimJobMultiThreadQueue::getJobQueue()const
{
   std::lock_guard<std::mutex> lock(m_mutex);
   return m_jobQueue;
}
void ossimJobMultiThreadQueue::setJobQueue(std::shared_ptr<ossimJobQueue> q)
{
   std::lock_guard<std::mutex> lock(m_mutex);
   ossim_uint32 idx = 0;
   m_jobQueue = q;
   for(idx = 0; idx < m_threadQueueList.size(); ++idx)
   {
      m_threadQueueList[idx]->setJobQueue(m_jobQueue);
   }
}
void ossimJobMultiThreadQueue::setNumberOfThreads(ossim_uint32 nThreads)
{
   std::lock_guard<std::mutex> lock(m_mutex);
   ossim_uint32 idx = 0;
   ossim_uint32 queueSize = m_threadQueueList.size();

   if(nThreads > queueSize)
   {
      for(idx = queueSize; idx < nThreads;++idx)
      {
         std::shared_ptr<ossimJobThreadQueue> threadQueue = std::make_shared<ossimJobThreadQueue>();
         threadQueue->setJobQueue(m_jobQueue);
         m_threadQueueList.push_back(threadQueue);
      }
   }
   else if(nThreads < queueSize)
   {
      ThreadQueueList::iterator iter = m_threadQueueList.begin()+nThreads;
      while(iter != m_threadQueueList.end())
      {
         (*iter)->cancel();
         iter = m_threadQueueList.erase(iter);
      }
   }
}

ossim_uint32 ossimJobMultiThreadQueue::getNumberOfThreads() const
{
   std::lock_guard<std::mutex> lock(m_mutex);
   return static_cast<ossim_uint32>( m_threadQueueList.size() );
}

ossim_uint32 ossimJobMultiThreadQueue::numberOfBusyThreads()const
{
   ossim_uint32 result = 0;
   std::lock_guard<std::mutex> lock(m_mutex);
   ossim_uint32 idx = 0;
   ossim_uint32 queueSize = m_threadQueueList.size();
   for(idx = 0; idx < queueSize;++idx)
   {
      if(m_threadQueueList[idx]->isProcessingJob()) ++result;
   }
   return result;
}

bool ossimJobMultiThreadQueue::areAllThreadsBusy()const
{
   std::lock_guard<std::mutex> lock(m_mutex);
   ossim_uint32 idx = 0;
   ossim_uint32 queueSize = m_threadQueueList.size();
   for(idx = 0; idx < queueSize;++idx)
   {
      if(!m_threadQueueList[idx]->isProcessingJob()) return false;
   }

   return true;
}

bool ossimJobMultiThreadQueue::hasJobsToProcess()const
{
   bool result = false;
   {
      std::lock_guard<std::mutex> lock(m_mutex);
      ossim_uint32 queueSize = m_threadQueueList.size();
      ossim_uint32 idx = 0;
      for(idx = 0; ((idx<queueSize)&&!result);++idx)
      {
         result = m_threadQueueList[idx]->hasJobsToProcess();
      }
   }

   return result;
}

void ossimJobMultiThreadQueue::cancel()
{
   for(auto thread:m_threadQueueList)
   {
      thread->cancel();
   }
}

void ossimJobMultiThreadQueue::waitForCompletion()
{
   for(auto thread:m_threadQueueList)
   {
      thread->waitForCompletion();
   }
}

<commit_msg>Removed hang in the destructor<commit_after>#include <ossim/parallel/ossimJobMultiThreadQueue.h>

ossimJobMultiThreadQueue::ossimJobMultiThreadQueue(std::shared_ptr<ossimJobQueue> q,
                                                   ossim_uint32 nThreads)
:m_jobQueue(q?q:std::make_shared<ossimJobQueue>())
{
   setNumberOfThreads(nThreads);
}

ossimJobMultiThreadQueue::~ossimJobMultiThreadQueue()
{
   cancel();
   waitForCompletion();
   m_threadQueueList.clear();
}

std::shared_ptr<ossimJobQueue> ossimJobMultiThreadQueue::getJobQueue()
{
   std::lock_guard<std::mutex> lock(m_mutex);
   return m_jobQueue;
}
const std::shared_ptr<ossimJobQueue> ossimJobMultiThreadQueue::getJobQueue()const
{
   std::lock_guard<std::mutex> lock(m_mutex);
   return m_jobQueue;
}
void ossimJobMultiThreadQueue::setJobQueue(std::shared_ptr<ossimJobQueue> q)
{
   std::lock_guard<std::mutex> lock(m_mutex);
   ossim_uint32 idx = 0;
   m_jobQueue = q;
   for(idx = 0; idx < m_threadQueueList.size(); ++idx)
   {
      m_threadQueueList[idx]->setJobQueue(m_jobQueue);
   }
}
void ossimJobMultiThreadQueue::setNumberOfThreads(ossim_uint32 nThreads)
{
   std::lock_guard<std::mutex> lock(m_mutex);
   ossim_uint32 idx = 0;
   ossim_uint32 queueSize = m_threadQueueList.size();

   if(nThreads > queueSize)
   {
      for(idx = queueSize; idx < nThreads;++idx)
      {
         std::shared_ptr<ossimJobThreadQueue> threadQueue = std::make_shared<ossimJobThreadQueue>();
         threadQueue->setJobQueue(m_jobQueue);
         m_threadQueueList.push_back(threadQueue);
      }
   }
   else if(nThreads < queueSize)
   {
      ThreadQueueList::iterator iter = m_threadQueueList.begin()+nThreads;
      while(iter != m_threadQueueList.end())
      {
         (*iter)->cancel();
         iter = m_threadQueueList.erase(iter);
      }
   }
}

ossim_uint32 ossimJobMultiThreadQueue::getNumberOfThreads() const
{
   std::lock_guard<std::mutex> lock(m_mutex);
   return static_cast<ossim_uint32>( m_threadQueueList.size() );
}

ossim_uint32 ossimJobMultiThreadQueue::numberOfBusyThreads()const
{
   ossim_uint32 result = 0;
   std::lock_guard<std::mutex> lock(m_mutex);
   ossim_uint32 idx = 0;
   ossim_uint32 queueSize = m_threadQueueList.size();
   for(idx = 0; idx < queueSize;++idx)
   {
      if(m_threadQueueList[idx]->isProcessingJob()) ++result;
   }
   return result;
}

bool ossimJobMultiThreadQueue::areAllThreadsBusy()const
{
   std::lock_guard<std::mutex> lock(m_mutex);
   ossim_uint32 idx = 0;
   ossim_uint32 queueSize = m_threadQueueList.size();
   for(idx = 0; idx < queueSize;++idx)
   {
      if(!m_threadQueueList[idx]->isProcessingJob()) return false;
   }

   return true;
}

bool ossimJobMultiThreadQueue::hasJobsToProcess()const
{
   bool result = false;
   {
      std::lock_guard<std::mutex> lock(m_mutex);
      ossim_uint32 queueSize = m_threadQueueList.size();
      ossim_uint32 idx = 0;
      for(idx = 0; ((idx<queueSize)&&!result);++idx)
      {
         result = m_threadQueueList[idx]->hasJobsToProcess();
      }
   }

   return result;
}

void ossimJobMultiThreadQueue::cancel()
{
   for(auto thread:m_threadQueueList)
   {
      thread->cancel();
   }
}

void ossimJobMultiThreadQueue::waitForCompletion()
{
   for(auto thread:m_threadQueueList)
   {
      thread->waitForCompletion();
   }
}

<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "cpphoverhandler.h"
#include "cppeditor.h"
#include "cppplugin.h"

#include <coreplugin/icore.h>
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <cpptools/cppmodelmanagerinterface.h>
#include <extensionsystem/pluginmanager.h>
#include <texteditor/itexteditor.h>
#include <texteditor/basetexteditor.h>
#include <debugger/debuggerconstants.h>

#include <CoreTypes.h>
#include <FullySpecifiedType.h>
#include <Literals.h>
#include <Control.h>
#include <Names.h>
#include <Scope.h>
#include <Symbol.h>
#include <Symbols.h>
#include <cplusplus/ExpressionUnderCursor.h>
#include <cplusplus/Overview.h>
#include <cplusplus/TypeOfExpression.h>
#include <cplusplus/SimpleLexer.h>

#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QSettings>
#include <QtGui/QToolTip>
#include <QtGui/QTextCursor>
#include <QtGui/QTextBlock>
#include <QtHelp/QHelpEngineCore>

using namespace CppEditor::Internal;
using namespace CPlusPlus;
using namespace Core;

CppHoverHandler::CppHoverHandler(QObject *parent)
    : QObject(parent)
    , m_helpEngineNeedsSetup(false)
{
    m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();

    ICore *core = ICore::instance();
    QFileInfo fi(core->settings()->fileName());
    // FIXME shouldn't the help engine create the directory if it doesn't exist?
    QDir directory(fi.absolutePath()+"/qtcreator");
    if (!directory.exists())
        directory.mkpath(directory.absolutePath());

    m_helpEngine = new QHelpEngineCore(directory.absolutePath()
                                       + QLatin1String("/helpcollection.qhc"), this);
    //m_helpEngine->setAutoSaveFilter(false);
    if (!m_helpEngine->setupData())
        qWarning() << "Could not initialize help engine:" << m_helpEngine->error();
    m_helpEngine->setCurrentFilter(tr("Unfiltered"));
    m_helpEngineNeedsSetup = m_helpEngine->registeredDocumentations().count() == 0;

    // Listen for editor opened events in order to connect to tooltip/helpid requests
    connect(core->editorManager(), SIGNAL(editorOpened(Core::IEditor *)),
            this, SLOT(editorOpened(Core::IEditor *)));
}

void CppHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos)
{
    updateHelpIdAndTooltip(editor, pos);
}

void CppHoverHandler::editorOpened(IEditor *editor)
{
    CPPEditorEditable *cppEditor = qobject_cast<CPPEditorEditable *>(editor);
    if (!cppEditor)
        return;

    connect(cppEditor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*, QPoint, int)),
            this, SLOT(showToolTip(TextEditor::ITextEditor*, QPoint, int)));

    connect(cppEditor, SIGNAL(contextHelpIdRequested(TextEditor::ITextEditor*, int)),
            this, SLOT(updateContextHelpId(TextEditor::ITextEditor*, int)));
}

void CppHoverHandler::showToolTip(TextEditor::ITextEditor *editor, const QPoint &point, int pos)
{
    if (!editor)
        return;

    ICore *core = ICore::instance();
    const int dbgcontext = core->uniqueIDManager()->uniqueIdentifier(Debugger::Constants::C_GDBDEBUGGER);

    if (core->hasContext(dbgcontext))
        return;

    updateHelpIdAndTooltip(editor, pos);

    if (m_toolTip.isEmpty())
        QToolTip::hideText();
    else {
        const QPoint pnt = point - QPoint(0,
#ifdef Q_WS_WIN
        24
#else
        16
#endif
        );

        QToolTip::showText(pnt, m_toolTip);
    }
}

static QString buildHelpId(Symbol *symbol, Name *name)
{
    Scope *scope = 0;

    if (symbol) {
        scope = symbol->scope();
        name = symbol->name();
    }

    if (! name)
        return QString();

    Overview overview;
    overview.setShowArgumentNames(false);
    overview.setShowReturnTypes(false);

    QStringList qualifiedNames;
    qualifiedNames.prepend(overview.prettyName(name));

    for (; scope; scope = scope->enclosingScope()) {
        Symbol *owner = scope->owner();

        if (owner && owner->name() && ! scope->isEnumScope()) {
            Name *name = owner->name();
            Identifier *id = 0;

            if (NameId *nameId = name->asNameId())
                id = nameId->identifier();

            else if (TemplateNameId *nameId = name->asTemplateNameId())
                id = nameId->identifier();

            if (id)
                qualifiedNames.prepend(QString::fromLatin1(id->chars(), id->size()));
        }
    }

    return qualifiedNames.join(QLatin1String("::"));
}

// ### move me
static FullySpecifiedType resolve(const FullySpecifiedType &ty,
                                  const LookupContext &context,
                                  Symbol **resolvedSymbol,
                                  Name **resolvedName)
{
    Control *control = context.control();

    if (const PointerType *ptrTy = ty->asPointerType()) {
        return control->pointerType(resolve(ptrTy->elementType(), context,
                                            resolvedSymbol, resolvedName));

    } else if (const ReferenceType *refTy = ty->asReferenceType()) {
        return control->referenceType(resolve(refTy->elementType(), context,
                                              resolvedSymbol, resolvedName));

    } else if (const PointerToMemberType *ptrToMemTy = ty->asPointerToMemberType()) {
        return control->pointerToMemberType(ptrToMemTy->memberName(),
                                            resolve(ptrToMemTy->elementType(), context,
                                                    resolvedSymbol, resolvedName));

    } else if (const NamedType *namedTy = ty->asNamedType()) {
        if (resolvedName)
            *resolvedName = namedTy->name();

        const QList<Symbol *> candidates = context.resolve(namedTy->name());

        foreach (Symbol *c, candidates) {
            if (c->isClass() || c->isEnum()) {
                if (resolvedSymbol)
                    *resolvedSymbol = c;

                return c->type();
            }
        }

    } else if (const Namespace *nsTy = ty->asNamespaceType()) {
        if (resolvedName)
            *resolvedName = nsTy->name();

        if (resolvedSymbol)
            *resolvedSymbol = const_cast<Namespace *>(nsTy);

    } else if (const Class *classTy = ty->asClassType()) {
        if (resolvedName)
            *resolvedName = classTy->name();

        if (resolvedSymbol)
            *resolvedSymbol = const_cast<Class *>(classTy);

    } else if (const ForwardClassDeclaration *fwdClassTy = ty->asForwardClassDeclarationType()) {
        if (resolvedName)
            *resolvedName = fwdClassTy->name();

        if (resolvedSymbol)
            *resolvedSymbol = const_cast<ForwardClassDeclaration *>(fwdClassTy);

    } else if (const Enum *enumTy = ty->asEnumType()) {
        if (resolvedName)
            *resolvedName = enumTy->name();

        if (resolvedSymbol)
            *resolvedSymbol = const_cast<Enum *>(enumTy);

    } else if (const Function *funTy = ty->asFunctionType()) {
        if (resolvedName)
            *resolvedName = funTy->name();

        if (resolvedSymbol)
            *resolvedSymbol = const_cast<Function *>(funTy);

    }

    return ty;
}

void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos)
{
    m_helpId.clear();
    m_toolTip.clear();

    if (!m_modelManager)
        return;

    TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
    if (!edit)
        return;

    const Snapshot documents = m_modelManager->snapshot();
    const QString fileName = editor->file()->fileName();
    Document::Ptr doc = documents.value(fileName);
    if (!doc)
        return; // nothing to do

    QTextCursor tc(edit->document());
    tc.setPosition(pos);
    const unsigned lineNumber = tc.block().blockNumber() + 1;

    // Find the last symbol up to the cursor position
    int line = 0, column = 0;
    editor->convertPosition(tc.position(), &line, &column);
    Symbol *lastSymbol = doc->findSymbolAt(line, column);

    TypeOfExpression typeOfExpression;
    typeOfExpression.setSnapshot(documents);

    // We only want to show F1 if the tooltip matches the help id
    bool showF1 = true;

    foreach (Document::DiagnosticMessage m, doc->diagnosticMessages()) {
        if (m.line() == lineNumber) {
            m_toolTip = m.text();
            showF1 = false;
            break;
        }
    }

    if (m_toolTip.isEmpty()) {
        foreach (const Document::Include &incl, doc->includes()) {
            if (incl.line() == lineNumber) {
                m_toolTip = QDir::toNativeSeparators(incl.fileName());
                m_helpId = QFileInfo(incl.fileName()).fileName();
                break;
            }
        }
    }

    if (m_helpId.isEmpty()) {
        // Move to the end of a qualified name
        bool stop = false;
        while (!stop) {
            const QChar ch = editor->characterAt(tc.position());
            if (ch.isLetterOrNumber() || ch == QLatin1Char('_'))
                tc.setPosition(tc.position() + 1);
            else if (ch == QLatin1Char(':') && editor->characterAt(tc.position() + 1) == QLatin1Char(':')) {
                tc.setPosition(tc.position() + 2);
            } else {
                stop = true;
            }
        }

        // Fetch the expression's code
        ExpressionUnderCursor expressionUnderCursor;
        const QString expression = expressionUnderCursor(tc);

        const QList<TypeOfExpression::Result> types =
                typeOfExpression(expression, doc, lastSymbol);

        if (!types.isEmpty()) {
            const TypeOfExpression::Result result = types.first();

            FullySpecifiedType firstType = result.first; // result of `type of expression'.
            Symbol *lookupSymbol = result.second;        // lookup symbol

            Symbol *resolvedSymbol = lookupSymbol;
            Name *resolvedName = lookupSymbol ? lookupSymbol->name() : 0;
            firstType = resolve(firstType, typeOfExpression.lookupContext(),
                                &resolvedSymbol, &resolvedName);

            if (resolvedSymbol && resolvedSymbol->scope()->isClassScope()) {
                Class *enclosingClass = resolvedSymbol->scope()->owner()->asClass();
                if (Identifier *id = enclosingClass->identifier()) {
                    if (id->isEqualTo(resolvedSymbol->identifier()))
                        resolvedSymbol = enclosingClass;
                }
            }

            m_helpId = buildHelpId(resolvedSymbol, resolvedName);

            if (m_toolTip.isEmpty()) {
                Symbol *symbol = result.second;
                if (resolvedSymbol)
                    symbol = resolvedSymbol;

                Overview overview;
                overview.setShowArgumentNames(true);
                overview.setShowReturnTypes(true);
                overview.setShowFullyQualifiedNamed(true);

                if (symbol == resolvedSymbol && symbol->isClass()) {
                    m_toolTip = m_helpId;

                } else if (lookupSymbol && (lookupSymbol->isDeclaration() || lookupSymbol->isArgument())) {
                    m_toolTip = overview.prettyType(firstType, buildHelpId(lookupSymbol, lookupSymbol->name()));

                } else if (firstType->isClassType() || firstType->isEnumType() ||
                           firstType->isForwardClassDeclarationType()) {
                    m_toolTip = m_helpId;

                } else {
                    m_toolTip = overview.prettyType(firstType, m_helpId);

                }
            }
        }
    }

    if (m_toolTip.isEmpty()) {
        foreach (const Document::MacroUse &use, doc->macroUses()) {
            if (use.contains(pos)) {
                const Macro m = use.macro();
                m_toolTip = m.toString();
                m_helpId = m.name();
                break;
            }
        }
    }

    if (m_helpEngineNeedsSetup
        && m_helpEngine->registeredDocumentations().count() > 0) {
        m_helpEngine->setupData();
        m_helpEngineNeedsSetup = false;
    }

    if (!m_toolTip.isEmpty())
        m_toolTip = Qt::escape(m_toolTip);

    if (!m_helpId.isEmpty() && !m_helpEngine->linksForIdentifier(m_helpId).isEmpty()) {
        if (showF1) {
            m_toolTip = QString(QLatin1String("

<nobr>%1	"
                                              "

"))
                        .arg(m_toolTip);
        }
        editor->setContextHelpId(m_helpId);
    } else if (!m_toolTip.isEmpty()) {
        m_toolTip = QString(QLatin1String("<nobr>%1")).arg(m_toolTip);
    }
}
<commit_msg>Fixed possible crash when building the helpId<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "cpphoverhandler.h"
#include "cppeditor.h"
#include "cppplugin.h"

#include <coreplugin/icore.h>
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <cpptools/cppmodelmanagerinterface.h>
#include <extensionsystem/pluginmanager.h>
#include <texteditor/itexteditor.h>
#include <texteditor/basetexteditor.h>
#include <debugger/debuggerconstants.h>

#include <CoreTypes.h>
#include <FullySpecifiedType.h>
#include <Literals.h>
#include <Control.h>
#include <Names.h>
#include <Scope.h>
#include <Symbol.h>
#include <Symbols.h>
#include <cplusplus/ExpressionUnderCursor.h>
#include <cplusplus/Overview.h>
#include <cplusplus/TypeOfExpression.h>
#include <cplusplus/SimpleLexer.h>

#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QSettings>
#include <QtGui/QToolTip>
#include <QtGui/QTextCursor>
#include <QtGui/QTextBlock>
#include <QtHelp/QHelpEngineCore>

using namespace CppEditor::Internal;
using namespace CPlusPlus;
using namespace Core;

CppHoverHandler::CppHoverHandler(QObject *parent)
    : QObject(parent)
    , m_helpEngineNeedsSetup(false)
{
    m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();

    ICore *core = ICore::instance();
    QFileInfo fi(core->settings()->fileName());
    // FIXME shouldn't the help engine create the directory if it doesn't exist?
    QDir directory(fi.absolutePath()+"/qtcreator");
    if (!directory.exists())
        directory.mkpath(directory.absolutePath());

    m_helpEngine = new QHelpEngineCore(directory.absolutePath()
                                       + QLatin1String("/helpcollection.qhc"), this);
    //m_helpEngine->setAutoSaveFilter(false);
    if (!m_helpEngine->setupData())
        qWarning() << "Could not initialize help engine:" << m_helpEngine->error();
    m_helpEngine->setCurrentFilter(tr("Unfiltered"));
    m_helpEngineNeedsSetup = m_helpEngine->registeredDocumentations().count() == 0;

    // Listen for editor opened events in order to connect to tooltip/helpid requests
    connect(core->editorManager(), SIGNAL(editorOpened(Core::IEditor *)),
            this, SLOT(editorOpened(Core::IEditor *)));
}

void CppHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos)
{
    updateHelpIdAndTooltip(editor, pos);
}

void CppHoverHandler::editorOpened(IEditor *editor)
{
    CPPEditorEditable *cppEditor = qobject_cast<CPPEditorEditable *>(editor);
    if (!cppEditor)
        return;

    connect(cppEditor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*, QPoint, int)),
            this, SLOT(showToolTip(TextEditor::ITextEditor*, QPoint, int)));

    connect(cppEditor, SIGNAL(contextHelpIdRequested(TextEditor::ITextEditor*, int)),
            this, SLOT(updateContextHelpId(TextEditor::ITextEditor*, int)));
}

void CppHoverHandler::showToolTip(TextEditor::ITextEditor *editor, const QPoint &point, int pos)
{
    if (!editor)
        return;

    ICore *core = ICore::instance();
    const int dbgcontext = core->uniqueIDManager()->uniqueIdentifier(Debugger::Constants::C_GDBDEBUGGER);

    if (core->hasContext(dbgcontext))
        return;

    updateHelpIdAndTooltip(editor, pos);

    if (m_toolTip.isEmpty())
        QToolTip::hideText();
    else {
        const QPoint pnt = point - QPoint(0,
#ifdef Q_WS_WIN
        24
#else
        16
#endif
        );

        QToolTip::showText(pnt, m_toolTip);
    }
}

static QString buildHelpId(Symbol *symbol, Name *name)
{
    Scope *scope = 0;

    if (symbol) {
        scope = symbol->scope();
        name = symbol->name();
    }

    if (! name)
        return QString();

    Overview overview;
    overview.setShowArgumentNames(false);
    overview.setShowReturnTypes(false);

    QStringList qualifiedNames;
    qualifiedNames.prepend(overview.prettyName(name));

    for (; scope; scope = scope->enclosingScope()) {
        Symbol *owner = scope->owner();

        if (owner && owner->name() && ! scope->isEnumScope()) {
            Name *name = owner->name();
            Identifier *id = 0;

            if (NameId *nameId = name->asNameId())
                id = nameId->identifier();

            else if (TemplateNameId *nameId = name->asTemplateNameId())
                id = nameId->identifier();

            if (id)
                qualifiedNames.prepend(QString::fromLatin1(id->chars(), id->size()));
        }
    }

    return qualifiedNames.join(QLatin1String("::"));
}

// ### move me
static FullySpecifiedType resolve(const FullySpecifiedType &ty,
                                  const LookupContext &context,
                                  Symbol **resolvedSymbol,
                                  Name **resolvedName)
{
    Control *control = context.control();

    if (const PointerType *ptrTy = ty->asPointerType()) {
        return control->pointerType(resolve(ptrTy->elementType(), context,
                                            resolvedSymbol, resolvedName));

    } else if (const ReferenceType *refTy = ty->asReferenceType()) {
        return control->referenceType(resolve(refTy->elementType(), context,
                                              resolvedSymbol, resolvedName));

    } else if (const PointerToMemberType *ptrToMemTy = ty->asPointerToMemberType()) {
        return control->pointerToMemberType(ptrToMemTy->memberName(),
                                            resolve(ptrToMemTy->elementType(), context,
                                                    resolvedSymbol, resolvedName));

    } else if (const NamedType *namedTy = ty->asNamedType()) {
        if (resolvedName)
            *resolvedName = namedTy->name();

        const QList<Symbol *> candidates = context.resolve(namedTy->name());

        foreach (Symbol *c, candidates) {
            if (c->isClass() || c->isEnum()) {
                if (resolvedSymbol)
                    *resolvedSymbol = c;

                return c->type();
            }
        }

    } else if (const Namespace *nsTy = ty->asNamespaceType()) {
        if (resolvedName)
            *resolvedName = nsTy->name();

        if (resolvedSymbol)
            *resolvedSymbol = const_cast<Namespace *>(nsTy);

    } else if (const Class *classTy = ty->asClassType()) {
        if (resolvedName)
            *resolvedName = classTy->name();

        if (resolvedSymbol)
            *resolvedSymbol = const_cast<Class *>(classTy);

    } else if (const ForwardClassDeclaration *fwdClassTy = ty->asForwardClassDeclarationType()) {
        if (resolvedName)
            *resolvedName = fwdClassTy->name();

        if (resolvedSymbol)
            *resolvedSymbol = const_cast<ForwardClassDeclaration *>(fwdClassTy);

    } else if (const Enum *enumTy = ty->asEnumType()) {
        if (resolvedName)
            *resolvedName = enumTy->name();

        if (resolvedSymbol)
            *resolvedSymbol = const_cast<Enum *>(enumTy);

    } else if (const Function *funTy = ty->asFunctionType()) {
        if (resolvedName)
            *resolvedName = funTy->name();

        if (resolvedSymbol)
            *resolvedSymbol = const_cast<Function *>(funTy);

    }

    return ty;
}

void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos)
{
    m_helpId.clear();
    m_toolTip.clear();

    if (!m_modelManager)
        return;

    TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
    if (!edit)
        return;

    const Snapshot documents = m_modelManager->snapshot();
    const QString fileName = editor->file()->fileName();
    Document::Ptr doc = documents.value(fileName);
    if (!doc)
        return; // nothing to do

    QTextCursor tc(edit->document());
    tc.setPosition(pos);
    const unsigned lineNumber = tc.block().blockNumber() + 1;

    // Find the last symbol up to the cursor position
    int line = 0, column = 0;
    editor->convertPosition(tc.position(), &line, &column);
    Symbol *lastSymbol = doc->findSymbolAt(line, column);

    TypeOfExpression typeOfExpression;
    typeOfExpression.setSnapshot(documents);

    // We only want to show F1 if the tooltip matches the help id
    bool showF1 = true;

    foreach (Document::DiagnosticMessage m, doc->diagnosticMessages()) {
        if (m.line() == lineNumber) {
            m_toolTip = m.text();
            showF1 = false;
            break;
        }
    }

    if (m_toolTip.isEmpty()) {
        foreach (const Document::Include &incl, doc->includes()) {
            if (incl.line() == lineNumber) {
                m_toolTip = QDir::toNativeSeparators(incl.fileName());
                m_helpId = QFileInfo(incl.fileName()).fileName();
                break;
            }
        }
    }

    if (m_helpId.isEmpty()) {
        // Move to the end of a qualified name
        bool stop = false;
        while (!stop) {
            const QChar ch = editor->characterAt(tc.position());
            if (ch.isLetterOrNumber() || ch == QLatin1Char('_'))
                tc.setPosition(tc.position() + 1);
            else if (ch == QLatin1Char(':') && editor->characterAt(tc.position() + 1) == QLatin1Char(':')) {
                tc.setPosition(tc.position() + 2);
            } else {
                stop = true;
            }
        }

        // Fetch the expression's code
        ExpressionUnderCursor expressionUnderCursor;
        const QString expression = expressionUnderCursor(tc);

        const QList<TypeOfExpression::Result> types =
                typeOfExpression(expression, doc, lastSymbol);

        if (!types.isEmpty()) {
            const TypeOfExpression::Result result = types.first();

            FullySpecifiedType firstType = result.first; // result of `type of expression'.
            Symbol *lookupSymbol = result.second;        // lookup symbol

            Symbol *resolvedSymbol = lookupSymbol;
            Name *resolvedName = lookupSymbol ? lookupSymbol->name() : 0;
            firstType = resolve(firstType, typeOfExpression.lookupContext(),
                                &resolvedSymbol, &resolvedName);

            if (resolvedSymbol && resolvedSymbol->scope()->isClassScope()) {
                Class *enclosingClass = resolvedSymbol->scope()->owner()->asClass();
                if (Identifier *id = enclosingClass->identifier()) {
                    if (id->isEqualTo(resolvedSymbol->identifier()))
                        resolvedSymbol = enclosingClass;
                }
            }

            m_helpId = buildHelpId(resolvedSymbol, resolvedName);

            if (m_toolTip.isEmpty()) {
                Symbol *symbol = result.second;
                if (resolvedSymbol)
                    symbol = resolvedSymbol;

                Overview overview;
                overview.setShowArgumentNames(true);
                overview.setShowReturnTypes(true);
                overview.setShowFullyQualifiedNamed(true);

                if (symbol && symbol == resolvedSymbol && symbol->isClass()) {
                    m_toolTip = m_helpId;

                } else if (lookupSymbol && (lookupSymbol->isDeclaration() || lookupSymbol->isArgument())) {
                    m_toolTip = overview.prettyType(firstType, buildHelpId(lookupSymbol, lookupSymbol->name()));

                } else if (firstType->isClassType() || firstType->isEnumType() ||
                           firstType->isForwardClassDeclarationType()) {
                    m_toolTip = m_helpId;

                } else {
                    m_toolTip = overview.prettyType(firstType, m_helpId);

                }
            }
        }
    }

    if (m_toolTip.isEmpty()) {
        foreach (const Document::MacroUse &use, doc->macroUses()) {
            if (use.contains(pos)) {
                const Macro m = use.macro();
                m_toolTip = m.toString();
                m_helpId = m.name();
                break;
            }
        }
    }

    if (m_helpEngineNeedsSetup
        && m_helpEngine->registeredDocumentations().count() > 0) {
        m_helpEngine->setupData();
        m_helpEngineNeedsSetup = false;
    }

    if (!m_toolTip.isEmpty())
        m_toolTip = Qt::escape(m_toolTip);

    if (!m_helpId.isEmpty() && !m_helpEngine->linksForIdentifier(m_helpId).isEmpty()) {
        if (showF1) {
            m_toolTip = QString(QLatin1String("

<nobr>%1	"
                                              "

"))
                        .arg(m_toolTip);
        }
        editor->setContextHelpId(m_helpId);
    } else if (!m_toolTip.isEmpty()) {
        m_toolTip = QString(QLatin1String("<nobr>%1")).arg(m_toolTip);
    }
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_jvmfwk.hxx"

#include "osl/thread.h"
#include "sunjre.hxx"
#include "sunversion.hxx"
#include "diagnostics.h"

using namespace rtl;
using namespace std;

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
namespace jfw_plugin
{

Reference<VendorBase> SunInfo::createInstance()
{
    return new SunInfo;
}

char const* const* SunInfo::getJavaExePaths(int * size)
{
    static char const * ar[] = {
#if defined(WNT) || defined(OS2)
        "java.exe",
        "bin/java.exe",
        "jre/bin/java.exe"
#elif UNX
        "java",
        "bin/java",
        "jre/bin/java"
#endif
    };
        *size = sizeof (ar) / sizeof (char*);
    return ar;
}

char const* const* SunInfo::getRuntimePaths(int * size)
{
    static char const* ar[]= {
#if defined(WNT)
        "/bin/client/jvm.dll",
        "/bin/hotspot/jvm.dll",
        "/bin/classic/jvm.dll",
        // The 64-bit JRE has the jvm in bin/server
        "/bin/server/jvm.dll"
#elif defined(OS2)
        "/bin/classic/jvm.dll",
#elif UNX
        "/lib/" JFW_PLUGIN_ARCH "/client/libjvm.so",
        "/lib/" JFW_PLUGIN_ARCH "/server/libjvm.so",
        "/lib/" JFW_PLUGIN_ARCH "/classic/libjvm.so"
#endif

    };
    *size = sizeof(ar) / sizeof (char*);
    return ar;
}

char const* const* SunInfo::getLibraryPaths(int* size)
{
#ifdef UNX
    static char const * ar[] = {

        "/lib/" JFW_PLUGIN_ARCH "/client",
#if defined(OPENBSD)
        "/lib/" JFW_PLUGIN_ARCH "/server",
#endif
        "/lib/" JFW_PLUGIN_ARCH "/native_threads",
        "/lib/" JFW_PLUGIN_ARCH

    };
    *size = sizeof(ar) / sizeof (char*);
    return ar;
#else
    size = 0;
    return NULL;
#endif
}

int SunInfo::compareVersions(const rtl::OUString& sSecond) const
{
    OUString sFirst = getVersion();

    SunVersion version1(sFirst);
    JFW_ENSURE(version1, OUSTR("[Java framework] sunjavaplugin"SAL_DLLEXTENSION
                               " does not know the version: ")
               + sFirst + OUSTR(" as valid for a SUN JRE."));
    SunVersion version2(sSecond);
    if ( ! version2)
        throw MalformedVersionException();

    if(version1 == version2)
        return 0;
    if(version1 > version2)
        return 1;
    else
        return -1;
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>search for server jvm if client jvm not found<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_jvmfwk.hxx"

#include "osl/thread.h"
#include "sunjre.hxx"
#include "sunversion.hxx"
#include "diagnostics.h"

using namespace rtl;
using namespace std;

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
namespace jfw_plugin
{

Reference<VendorBase> SunInfo::createInstance()
{
    return new SunInfo;
}

char const* const* SunInfo::getJavaExePaths(int * size)
{
    static char const * ar[] = {
#if defined(WNT) || defined(OS2)
        "java.exe",
        "bin/java.exe",
        "jre/bin/java.exe"
#elif UNX
        "java",
        "bin/java",
        "jre/bin/java"
#endif
    };
        *size = sizeof (ar) / sizeof (char*);
    return ar;
}

char const* const* SunInfo::getRuntimePaths(int * size)
{
    static char const* ar[]= {
#if defined(WNT)
        "/bin/client/jvm.dll",
        "/bin/hotspot/jvm.dll",
        "/bin/classic/jvm.dll",
        // The 64-bit JRE has the jvm in bin/server
        "/bin/server/jvm.dll"
#elif defined(OS2)
        "/bin/classic/jvm.dll",
#elif UNX
        "/lib/" JFW_PLUGIN_ARCH "/client/libjvm.so",
        "/lib/" JFW_PLUGIN_ARCH "/server/libjvm.so",
        "/lib/" JFW_PLUGIN_ARCH "/classic/libjvm.so"
#endif

    };
    *size = sizeof(ar) / sizeof (char*);
    return ar;
}

char const* const* SunInfo::getLibraryPaths(int* size)
{
#ifdef UNX
    static char const * ar[] = {

        "/lib/" JFW_PLUGIN_ARCH "/client",
        "/lib/" JFW_PLUGIN_ARCH "/server",
        "/lib/" JFW_PLUGIN_ARCH "/native_threads",
        "/lib/" JFW_PLUGIN_ARCH

    };
    *size = sizeof(ar) / sizeof (char*);
    return ar;
#else
    size = 0;
    return NULL;
#endif
}

int SunInfo::compareVersions(const rtl::OUString& sSecond) const
{
    OUString sFirst = getVersion();

    SunVersion version1(sFirst);
    JFW_ENSURE(version1, OUSTR("[Java framework] sunjavaplugin"SAL_DLLEXTENSION
                               " does not know the version: ")
               + sFirst + OUSTR(" as valid for a SUN JRE."));
    SunVersion version2(sSecond);
    if ( ! version2)
        throw MalformedVersionException();

    if(version1 == version2)
        return 0;
    if(version1 > version2)
        return 1;
    else
        return -1;
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#pragma once

class Solution {
public:
    int strStr(char* haystack, char* needle) {
        if (*haystack == '\0' && *needle == '\0') {
            return 0;
        }

        int idx;

        for (int i = 0; haystack[i] != '\0'; ++i) {
            if (haystack[i] == needle[0]) {

                for (idx = 0; needle[idx] != '\0'; ++idx) {
                    if (haystack[i + idx] != needle[idx]) {
                        idx = -1;
                        break;
                    }
                }

                if (idx != -1) {
                    return idx;
                }
            }
        }

        return -1;
    }
};
<commit_msg>return the proper index<commit_after>#pragma once

class Solution {
public:
    int strStr(char* haystack, char* needle) {
        if (*haystack == '\0' && *needle == '\0') {
            return 0;
        }

        int idx;

        for (int i = 0; haystack[i] != '\0'; ++i) {
            if (haystack[i] == needle[0]) {

                for (idx = 0; needle[idx] != '\0'; ++idx) {
                    if (haystack[i + idx] != needle[idx]) {
                        idx = -1;
                        break;
                    }
                }

                if (idx != -1) {
                    return i;
                }
            }
        }

        return -1;
    }
};
<|endoftext|>


<commit_before>//
// BatchEncoder - GetProgress LameEnc
// Copyright (C) 2005-2017 Wiesław Šoltés <wieslaw.soltes@gmail.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>

#include "GetProgress.h"

int GetProgress(char *szLineBuff, int nLineLen)
{
    //
    //  LameEnc
    //

    int nStart;
    int nEnd;
    char szPercentage[32];
    int j;
    int nProgress;

    memset(szPercentage, 0x00, 32);

    // check for percentage progress from console output (stdout)
    // '( 6%)'

    nStart = 0;
    nEnd = 0;

    for (j = 0; j < (int)nLineLen; j++)
    {
        if (szLineBuff[j] == '(')
        {
            nStart = j;
        }
        if (szLineBuff[j] == ')')
        {
            nEnd = j;
            break;
        }
    }

    if (nEnd > 0)
    {
        if ((nEnd - nStart) == 3)
        {
            szPercentage[0] = szLineBuff[nStart + 1];
            szPercentage[1] = '\0';
            nProgress = atoi(szPercentage);

            return nProgress;
        }
        else if ((nEnd - nStart) == 4)
        {
            szPercentage[0] = szLineBuff[nStart + 1];
            szPercentage[1] = szLineBuff[nStart + 2];
            szPercentage[2] = '\0';
            nProgress = atoi(szPercentage);

            return nProgress;
        }
        else if ((nEnd - nStart) == 5)
        {
            szPercentage[0] = szLineBuff[nStart + 1];
            szPercentage[1] = szLineBuff[nStart + 2];
            szPercentage[2] = szLineBuff[nStart + 3];
            szPercentage[3] = '\0';
            nProgress = atoi(szPercentage);

            return nProgress;
        }
    }

    return -1;
}
<commit_msg>Update GetProgress.cpp<commit_after>// Copyright (c) Wiesław Šoltés. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>

#include "GetProgress.h"

int GetProgress(char *szLineBuff, int nLineLen)
{
    //
    //  LameEnc
    //

    int nStart;
    int nEnd;
    char szPercentage[32];
    int j;
    int nProgress;

    memset(szPercentage, 0x00, 32);

    // check for percentage progress from console output (stdout)
    // '( 6%)'

    nStart = 0;
    nEnd = 0;

    for (j = 0; j < (int)nLineLen; j++)
    {
        if (szLineBuff[j] == '(')
        {
            nStart = j;
        }
        if (szLineBuff[j] == ')')
        {
            nEnd = j;
            break;
        }
    }

    if (nEnd > 0)
    {
        if ((nEnd - nStart) == 3)
        {
            szPercentage[0] = szLineBuff[nStart + 1];
            szPercentage[1] = '\0';
            nProgress = atoi(szPercentage);

            return nProgress;
        }
        else if ((nEnd - nStart) == 4)
        {
            szPercentage[0] = szLineBuff[nStart + 1];
            szPercentage[1] = szLineBuff[nStart + 2];
            szPercentage[2] = '\0';
            nProgress = atoi(szPercentage);

            return nProgress;
        }
        else if ((nEnd - nStart) == 5)
        {
            szPercentage[0] = szLineBuff[nStart + 1];
            szPercentage[1] = szLineBuff[nStart + 2];
            szPercentage[2] = szLineBuff[nStart + 3];
            szPercentage[3] = '\0';
            nProgress = atoi(szPercentage);

            return nProgress;
        }
    }

    return -1;
}
<|endoftext|>


<commit_before><commit_msg>Backed out changeset: 80fd32765ba5 ('number' holds error code passed via OGRE_EXCEPT_EX, i.e. HRESULT on D3D11)<commit_after><|endoftext|>