<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 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 "abstractprocessstep.h"
#include "buildconfiguration.h"
#include "buildstep.h"
#include "ioutputparser.h"
#include "project.h"
#include "target.h"

#include <utils/qtcassert.h>

#include <QtCore/QProcess>
#include <QtCore/QEventLoop>
#include <QtCore/QTimer>
#include <QtGui/QTextDocument>

using namespace ProjectExplorer;

AbstractProcessStep::AbstractProcessStep(BuildConfiguration *bc, const QString &id) :
    BuildStep(bc, id), m_timer(0), m_futureInterface(0),
    m_enabled(true), m_ignoreReturnValue(false),
    m_process(0), m_eventLoop(0), m_outputParserChain(0)
{
}

AbstractProcessStep::AbstractProcessStep(BuildConfiguration *bc,
                                         AbstractProcessStep *bs) :
    BuildStep(bc, bs), m_timer(0), m_futureInterface(0),
    m_enabled(bs->m_enabled), m_ignoreReturnValue(bs->m_ignoreReturnValue),
    m_process(0), m_eventLoop(0), m_outputParserChain(0)
{
}

AbstractProcessStep::~AbstractProcessStep()
{
    delete m_process;
    delete m_timer;
    // do not delete m_futureInterface, we do not own it.
    delete m_outputParserChain;
}

void AbstractProcessStep::setCommand(const QString &cmd)
{
    m_command = cmd;
}

QString AbstractProcessStep::workingDirectory() const
{
    return m_workingDirectory;
}

void AbstractProcessStep::setOutputParser(ProjectExplorer::IOutputParser *parser)
{
    delete m_outputParserChain;
    m_outputParserChain = parser;

    if (m_outputParserChain) {
        connect(parser, SIGNAL(addOutput(QString, QTextCharFormat)),
                this, SLOT(outputAdded(QString, QTextCharFormat)));
        connect(parser, SIGNAL(addTask(ProjectExplorer::Task)),
                this, SLOT(taskAdded(ProjectExplorer::Task)));
    }
}

void AbstractProcessStep::appendOutputParser(ProjectExplorer::IOutputParser *parser)
{
    if (!parser)
        return;

    QTC_ASSERT(m_outputParserChain, return);
    m_outputParserChain->appendOutputParser(parser);
    return;
}

ProjectExplorer::IOutputParser *AbstractProcessStep::outputParser() const
{
    return m_outputParserChain;
}

void AbstractProcessStep::setWorkingDirectory(const QString &workingDirectory)
{
    m_workingDirectory = workingDirectory;
}

void AbstractProcessStep::setArguments(const QStringList &arguments)
{
    m_arguments = arguments;
}

void AbstractProcessStep::setEnabled(bool b)
{
    m_enabled = b;
}

void AbstractProcessStep::setIgnoreReturnValue(bool b)
{
    m_ignoreReturnValue = b;
}

void AbstractProcessStep::setEnvironment(Environment env)
{
    m_environment = env;
}

bool AbstractProcessStep::init()
{
    if (QFileInfo(m_command).isRelative()) {
        QString searchInPath = m_environment.searchInPath(m_command);
        if (!searchInPath.isEmpty())
            m_command = searchInPath;
    }
    return true;
}

void AbstractProcessStep::run(QFutureInterface<bool> &fi)
{
    m_futureInterface = &fi;
    if (!m_enabled) {
        fi.reportResult(true);
        return;
    }
    QDir wd(m_workingDirectory);
    if (!wd.exists())
        wd.mkpath(wd.absolutePath());

    m_process = new QProcess();
    m_process->setWorkingDirectory(m_workingDirectory);
    m_process->setEnvironment(m_environment.toStringList());

    connect(m_process, SIGNAL(readyReadStandardOutput()),
            this, SLOT(processReadyReadStdOutput()),
            Qt::DirectConnection);
    connect(m_process, SIGNAL(readyReadStandardError()),
            this, SLOT(processReadyReadStdError()),
            Qt::DirectConnection);

    connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
            this, SLOT(slotProcessFinished(int, QProcess::ExitStatus)),
            Qt::DirectConnection);

    m_process->start(m_command, m_arguments);
    if (!m_process->waitForStarted()) {
        processStartupFailed();
        delete m_process;
        m_process = 0;
        fi.reportResult(false);
        return;
    }
    processStarted();

    m_timer = new QTimer();
    connect(m_timer, SIGNAL(timeout()), this, SLOT(checkForCancel()), Qt::DirectConnection);
    m_timer->start(500);
    m_eventLoop = new QEventLoop;
    m_eventLoop->exec();
    m_timer->stop();
    delete m_timer;
    m_timer = 0;

    // The process has finished, leftover data is read in processFinished
    processFinished(m_process->exitCode(), m_process->exitStatus());
    bool returnValue = processSucceeded(m_process->exitCode(), m_process->exitStatus()) || m_ignoreReturnValue;

    delete m_process;
    m_process = 0;
    delete m_eventLoop;
    m_eventLoop = 0;
    fi.reportResult(returnValue);
    m_futureInterface = 0;
    return;
}

void AbstractProcessStep::processStarted()
{
    QTextCharFormat textCharFormat;
    textCharFormat.setForeground(Qt::blue);
    emit addOutput(tr("Starting: \"%1\" %2\n").arg(m_command, m_arguments.join(" ")), textCharFormat);
}

void AbstractProcessStep::processFinished(int exitCode, QProcess::ExitStatus status)
{
    QTextCharFormat textCharFormat;
    if (status == QProcess::NormalExit && exitCode == 0) {
        textCharFormat.setForeground(Qt::blue);
        emit addOutput(tr("The process \"%1\" exited normally.").arg(m_command), textCharFormat);
    } else if (status == QProcess::NormalExit) {
        textCharFormat.setForeground(Qt::red);
        textCharFormat.setFontWeight(QFont::Bold);
        emit addOutput(tr("The process \"%1\" exited with code %2.").arg(m_command, m_process->exitCode()), textCharFormat);
    } else {
        textCharFormat.setForeground(Qt::red);
        textCharFormat.setFontWeight(QFont::Bold);
        emit addOutput(tr("The process \"%1\" crashed.").arg(m_command), textCharFormat);
    }
}

void AbstractProcessStep::processStartupFailed()
{
    QTextCharFormat textCharFormat;
    textCharFormat.setForeground(Qt::red);
    textCharFormat.setFontWeight(QFont::Bold);
    emit addOutput(tr("Could not start process \"%1\"").arg(m_command), textCharFormat);
}

bool AbstractProcessStep::processSucceeded(int exitCode, QProcess::ExitStatus status)
{
    return exitCode == 0 && status == QProcess::NormalExit;
}

void AbstractProcessStep::processReadyReadStdOutput()
{
    m_process->setReadChannel(QProcess::StandardOutput);
    while (m_process->canReadLine()) {
        QString line = QString::fromLocal8Bit(m_process->readLine());
        stdOutput(line);
    }
}

void AbstractProcessStep::stdOutput(const QString &line)
{
    if (m_outputParserChain)
        m_outputParserChain->stdOutput(line);
    QTextCharFormat textCharFormat;
    emit addOutput(Qt::escape(line), textCharFormat);
}

void AbstractProcessStep::processReadyReadStdError()
{
    m_process->setReadChannel(QProcess::StandardError);
    while (m_process->canReadLine()) {
        QString line = QString::fromLocal8Bit(m_process->readLine());
        stdError(line);
    }
}

void AbstractProcessStep::stdError(const QString &line)
{
    if (m_outputParserChain)
        m_outputParserChain->stdError(line);
    QTextCharFormat textCharFormat;
    textCharFormat.setForeground(Qt::red);
    emit addOutput(line, textCharFormat);
}

void AbstractProcessStep::checkForCancel()
{
    if (m_futureInterface->isCanceled() && m_timer->isActive()) {
        m_timer->stop();
        m_process->terminate();
        m_process->waitForFinished(5000);
        m_process->kill();
    }
}

void AbstractProcessStep::taskAdded(const ProjectExplorer::Task &task)
{
    // Do not bother to report issues if we do not care about the results of
    // the buildstep anyway:
    if (m_ignoreReturnValue)
        return;

    Task editable(task);
    QString filePath = QDir::cleanPath(task.file.trimmed());
    if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
        // We have no save way to decide which file in which subfolder
        // is meant. Therefore we apply following heuristics:
        // 1. Check if file is unique in whole project
        // 2. Otherwise try again without any ../
        // 3. give up.

        QList<QFileInfo> possibleFiles;
        QString fileName = QFileInfo(filePath).fileName();
        foreach (const QString &file, buildConfiguration()->target()->project()->files(ProjectExplorer::Project::AllFiles)) {
            QFileInfo candidate(file);
            if (candidate.fileName() == fileName)
                possibleFiles << candidate;
        }

        if (possibleFiles.count() == 1) {
            editable.file = possibleFiles.first().filePath();
        } else {
            // More then one filename, so do a better compare
            // Chop of any "../"
            while (filePath.startsWith(QLatin1String("../")))
                filePath.remove(0, 3);
            int count = 0;
            QString possibleFilePath;
            foreach(const QFileInfo &fi, possibleFiles) {
                if (fi.filePath().endsWith(filePath)) {
                    possibleFilePath = fi.filePath();
                    ++count;
                }
            }
            if (count == 1)
                editable.file = possibleFilePath;
            else
                qWarning() << "Could not find absolute location of file " << filePath;
        }
    }
    emit addTask(editable);
}

void AbstractProcessStep::outputAdded(const QString &string, const QTextCharFormat &textCharFormat)
{
    emit addOutput(string, textCharFormat);
}

void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus)
{
    QString line = QString::fromLocal8Bit(m_process->readAllStandardError());
    if (!line.isEmpty())
        stdError(line);

    line = QString::fromLocal8Bit(m_process->readAllStandardOutput());
    if (!line.isEmpty())
        stdOutput(line);

    m_eventLoop->exit(0);
}
<commit_msg>Fix escaped output in the compile output window<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 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 "abstractprocessstep.h"
#include "buildconfiguration.h"
#include "buildstep.h"
#include "ioutputparser.h"
#include "project.h"
#include "target.h"

#include <utils/qtcassert.h>

#include <QtCore/QProcess>
#include <QtCore/QEventLoop>
#include <QtCore/QTimer>
#include <QtGui/QTextDocument>

using namespace ProjectExplorer;

AbstractProcessStep::AbstractProcessStep(BuildConfiguration *bc, const QString &id) :
    BuildStep(bc, id), m_timer(0), m_futureInterface(0),
    m_enabled(true), m_ignoreReturnValue(false),
    m_process(0), m_eventLoop(0), m_outputParserChain(0)
{
}

AbstractProcessStep::AbstractProcessStep(BuildConfiguration *bc,
                                         AbstractProcessStep *bs) :
    BuildStep(bc, bs), m_timer(0), m_futureInterface(0),
    m_enabled(bs->m_enabled), m_ignoreReturnValue(bs->m_ignoreReturnValue),
    m_process(0), m_eventLoop(0), m_outputParserChain(0)
{
}

AbstractProcessStep::~AbstractProcessStep()
{
    delete m_process;
    delete m_timer;
    // do not delete m_futureInterface, we do not own it.
    delete m_outputParserChain;
}

void AbstractProcessStep::setCommand(const QString &cmd)
{
    m_command = cmd;
}

QString AbstractProcessStep::workingDirectory() const
{
    return m_workingDirectory;
}

void AbstractProcessStep::setOutputParser(ProjectExplorer::IOutputParser *parser)
{
    delete m_outputParserChain;
    m_outputParserChain = parser;

    if (m_outputParserChain) {
        connect(parser, SIGNAL(addOutput(QString, QTextCharFormat)),
                this, SLOT(outputAdded(QString, QTextCharFormat)));
        connect(parser, SIGNAL(addTask(ProjectExplorer::Task)),
                this, SLOT(taskAdded(ProjectExplorer::Task)));
    }
}

void AbstractProcessStep::appendOutputParser(ProjectExplorer::IOutputParser *parser)
{
    if (!parser)
        return;

    QTC_ASSERT(m_outputParserChain, return);
    m_outputParserChain->appendOutputParser(parser);
    return;
}

ProjectExplorer::IOutputParser *AbstractProcessStep::outputParser() const
{
    return m_outputParserChain;
}

void AbstractProcessStep::setWorkingDirectory(const QString &workingDirectory)
{
    m_workingDirectory = workingDirectory;
}

void AbstractProcessStep::setArguments(const QStringList &arguments)
{
    m_arguments = arguments;
}

void AbstractProcessStep::setEnabled(bool b)
{
    m_enabled = b;
}

void AbstractProcessStep::setIgnoreReturnValue(bool b)
{
    m_ignoreReturnValue = b;
}

void AbstractProcessStep::setEnvironment(Environment env)
{
    m_environment = env;
}

bool AbstractProcessStep::init()
{
    if (QFileInfo(m_command).isRelative()) {
        QString searchInPath = m_environment.searchInPath(m_command);
        if (!searchInPath.isEmpty())
            m_command = searchInPath;
    }
    return true;
}

void AbstractProcessStep::run(QFutureInterface<bool> &fi)
{
    m_futureInterface = &fi;
    if (!m_enabled) {
        fi.reportResult(true);
        return;
    }
    QDir wd(m_workingDirectory);
    if (!wd.exists())
        wd.mkpath(wd.absolutePath());

    m_process = new QProcess();
    m_process->setWorkingDirectory(m_workingDirectory);
    m_process->setEnvironment(m_environment.toStringList());

    connect(m_process, SIGNAL(readyReadStandardOutput()),
            this, SLOT(processReadyReadStdOutput()),
            Qt::DirectConnection);
    connect(m_process, SIGNAL(readyReadStandardError()),
            this, SLOT(processReadyReadStdError()),
            Qt::DirectConnection);

    connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
            this, SLOT(slotProcessFinished(int, QProcess::ExitStatus)),
            Qt::DirectConnection);

    m_process->start(m_command, m_arguments);
    if (!m_process->waitForStarted()) {
        processStartupFailed();
        delete m_process;
        m_process = 0;
        fi.reportResult(false);
        return;
    }
    processStarted();

    m_timer = new QTimer();
    connect(m_timer, SIGNAL(timeout()), this, SLOT(checkForCancel()), Qt::DirectConnection);
    m_timer->start(500);
    m_eventLoop = new QEventLoop;
    m_eventLoop->exec();
    m_timer->stop();
    delete m_timer;
    m_timer = 0;

    // The process has finished, leftover data is read in processFinished
    processFinished(m_process->exitCode(), m_process->exitStatus());
    bool returnValue = processSucceeded(m_process->exitCode(), m_process->exitStatus()) || m_ignoreReturnValue;

    delete m_process;
    m_process = 0;
    delete m_eventLoop;
    m_eventLoop = 0;
    fi.reportResult(returnValue);
    m_futureInterface = 0;
    return;
}

void AbstractProcessStep::processStarted()
{
    QTextCharFormat textCharFormat;
    textCharFormat.setForeground(Qt::blue);
    emit addOutput(tr("Starting: \"%1\" %2\n").arg(m_command, m_arguments.join(" ")), textCharFormat);
}

void AbstractProcessStep::processFinished(int exitCode, QProcess::ExitStatus status)
{
    QTextCharFormat textCharFormat;
    if (status == QProcess::NormalExit && exitCode == 0) {
        textCharFormat.setForeground(Qt::blue);
        emit addOutput(tr("The process \"%1\" exited normally.").arg(m_command), textCharFormat);
    } else if (status == QProcess::NormalExit) {
        textCharFormat.setForeground(Qt::red);
        textCharFormat.setFontWeight(QFont::Bold);
        emit addOutput(tr("The process \"%1\" exited with code %2.").arg(m_command, m_process->exitCode()), textCharFormat);
    } else {
        textCharFormat.setForeground(Qt::red);
        textCharFormat.setFontWeight(QFont::Bold);
        emit addOutput(tr("The process \"%1\" crashed.").arg(m_command), textCharFormat);
    }
}

void AbstractProcessStep::processStartupFailed()
{
    QTextCharFormat textCharFormat;
    textCharFormat.setForeground(Qt::red);
    textCharFormat.setFontWeight(QFont::Bold);
    emit addOutput(tr("Could not start process \"%1\"").arg(m_command), textCharFormat);
}

bool AbstractProcessStep::processSucceeded(int exitCode, QProcess::ExitStatus status)
{
    return exitCode == 0 && status == QProcess::NormalExit;
}

void AbstractProcessStep::processReadyReadStdOutput()
{
    m_process->setReadChannel(QProcess::StandardOutput);
    while (m_process->canReadLine()) {
        QString line = QString::fromLocal8Bit(m_process->readLine());
        stdOutput(line);
    }
}

void AbstractProcessStep::stdOutput(const QString &line)
{
    if (m_outputParserChain)
        m_outputParserChain->stdOutput(line);
    QTextCharFormat textCharFormat;
    emit addOutput(line, textCharFormat);
}

void AbstractProcessStep::processReadyReadStdError()
{
    m_process->setReadChannel(QProcess::StandardError);
    while (m_process->canReadLine()) {
        QString line = QString::fromLocal8Bit(m_process->readLine());
        stdError(line);
    }
}

void AbstractProcessStep::stdError(const QString &line)
{
    if (m_outputParserChain)
        m_outputParserChain->stdError(line);
    QTextCharFormat textCharFormat;
    textCharFormat.setForeground(Qt::red);
    emit addOutput(line, textCharFormat);
}

void AbstractProcessStep::checkForCancel()
{
    if (m_futureInterface->isCanceled() && m_timer->isActive()) {
        m_timer->stop();
        m_process->terminate();
        m_process->waitForFinished(5000);
        m_process->kill();
    }
}

void AbstractProcessStep::taskAdded(const ProjectExplorer::Task &task)
{
    // Do not bother to report issues if we do not care about the results of
    // the buildstep anyway:
    if (m_ignoreReturnValue)
        return;

    Task editable(task);
    QString filePath = QDir::cleanPath(task.file.trimmed());
    if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
        // We have no save way to decide which file in which subfolder
        // is meant. Therefore we apply following heuristics:
        // 1. Check if file is unique in whole project
        // 2. Otherwise try again without any ../
        // 3. give up.

        QList<QFileInfo> possibleFiles;
        QString fileName = QFileInfo(filePath).fileName();
        foreach (const QString &file, buildConfiguration()->target()->project()->files(ProjectExplorer::Project::AllFiles)) {
            QFileInfo candidate(file);
            if (candidate.fileName() == fileName)
                possibleFiles << candidate;
        }

        if (possibleFiles.count() == 1) {
            editable.file = possibleFiles.first().filePath();
        } else {
            // More then one filename, so do a better compare
            // Chop of any "../"
            while (filePath.startsWith(QLatin1String("../")))
                filePath.remove(0, 3);
            int count = 0;
            QString possibleFilePath;
            foreach(const QFileInfo &fi, possibleFiles) {
                if (fi.filePath().endsWith(filePath)) {
                    possibleFilePath = fi.filePath();
                    ++count;
                }
            }
            if (count == 1)
                editable.file = possibleFilePath;
            else
                qWarning() << "Could not find absolute location of file " << filePath;
        }
    }
    emit addTask(editable);
}

void AbstractProcessStep::outputAdded(const QString &string, const QTextCharFormat &textCharFormat)
{
    emit addOutput(string, textCharFormat);
}

void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus)
{
    QString line = QString::fromLocal8Bit(m_process->readAllStandardError());
    if (!line.isEmpty())
        stdError(line);

    line = QString::fromLocal8Bit(m_process->readAllStandardOutput());
    if (!line.isEmpty())
        stdOutput(line);

    m_eventLoop->exit(0);
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** 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.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "compileoutputwindow.h"
#include "buildmanager.h"
#include "showoutputtaskhandler.h"
#include "task.h"
#include "projectexplorerconstants.h"
#include "projectexplorer.h"
#include "projectexplorersettings.h"
#include "taskhub.h"

#include <coreplugin/icontext.h>
#include <find/basetextfind.h>
#include <aggregation/aggregate.h>
#include <extensionsystem/pluginmanager.h>

#include <QKeyEvent>
#include <QIcon>
#include <QTextCharFormat>
#include <QTextBlock>
#include <QTextCursor>
#include <QTextEdit>
#include <QScrollBar>
#include <QPlainTextEdit>
#include <QToolButton>

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

namespace {
const int MAX_LINECOUNT = 50000;
}

namespace ProjectExplorer {
namespace Internal {

class CompileOutputTextEdit : public Core::OutputWindow
{
public:
    CompileOutputTextEdit(const Core::Context &context) : Core::OutputWindow(context)
    {
    }

    void addTask(const Task &task, int blocknumber)
    {
        m_taskids.insert(blocknumber, task.taskId);
    }

    void clearTasks()
    {
        m_taskids.clear();
    }

protected:
     void mouseDoubleClickEvent(QMouseEvent *ev)
     {
        int line = cursorForPosition(ev->pos()).block().blockNumber();
        if (unsigned taskid = m_taskids.value(line, 0)) {
            ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
            TaskHub *hub = pm->getObject<TaskHub>();
            hub->showTaskInEditor(taskid);
        } else {
            QPlainTextEdit::mouseDoubleClickEvent(ev);
        }
    }

private:
    QHash<int, unsigned int> m_taskids;   //Map blocknumber to taskId
};

} // namespace Internal
} // namespace ProjectExplorer

CompileOutputWindow::CompileOutputWindow(BuildManager * /*bm*/, QAction *cancelBuildAction) :
    m_cancelBuildButton(new QToolButton)
{
    Core::Context context(Constants::C_COMPILE_OUTPUT);
    m_outputWindow = new CompileOutputTextEdit(context);
    m_outputWindow->setWindowTitle(tr("Compile Output"));
    m_outputWindow->setWindowIcon(QIcon(QLatin1String(Constants::ICON_WINDOW)));
    m_outputWindow->setReadOnly(true);
    m_outputWindow->setUndoRedoEnabled(false);
    m_outputWindow->setMaxLineCount(MAX_LINECOUNT);

    m_cancelBuildButton->setDefaultAction(cancelBuildAction);

    Aggregation::Aggregate *agg = new Aggregation::Aggregate;
    agg->add(m_outputWindow);
    agg->add(new Find::BaseTextFind(m_outputWindow));

    qRegisterMetaType<QTextCharFormat>("QTextCharFormat");

    m_handler = new ShowOutputTaskHandler(this);
    ExtensionSystem::PluginManager::instance()->addObject(m_handler);
    connect(ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()),
            this, SLOT(updateWordWrapMode()));
    updateWordWrapMode();
}

CompileOutputWindow::~CompileOutputWindow()
{
    ExtensionSystem::PluginManager::instance()->removeObject(m_handler);
    delete m_handler;
    delete m_cancelBuildButton;
}

void CompileOutputWindow::updateWordWrapMode()
{
    m_outputWindow->setWordWrapEnabled(ProjectExplorerPlugin::instance()->projectExplorerSettings().wrapAppOutput);
}

bool CompileOutputWindow::hasFocus() const
{
    return m_outputWindow->hasFocus();
}

bool CompileOutputWindow::canFocus() const
{
    return true;
}

void CompileOutputWindow::setFocus()
{
    m_outputWindow->setFocus();
}

QWidget *CompileOutputWindow::outputWidget(QWidget *)
{
    return m_outputWindow;
}

QList<QWidget *> CompileOutputWindow::toolBarWidgets() const
{
     return QList<QWidget *>() << m_cancelBuildButton;
}

static QColor mix_colors(QColor a, QColor b)
{
    return QColor((a.red() + 2 * b.red()) / 3, (a.green() + 2 * b.green()) / 3,
                  (a.blue() + 2* b.blue()) / 3, (a.alpha() + 2 * b.alpha()) / 3);
}

void CompileOutputWindow::appendText(const QString &text, ProjectExplorer::BuildStep::OutputFormat format)
{
    QPalette p = m_outputWindow->palette();
    QTextCharFormat textFormat;
    switch (format) {
    case BuildStep::NormalOutput:
        textFormat.setForeground(p.color(QPalette::Text));
        textFormat.setFontWeight(QFont::Normal);
        break;
    case BuildStep::ErrorOutput:
        textFormat.setForeground(mix_colors(p.color(QPalette::Text), QColor(Qt::red)));
        textFormat.setFontWeight(QFont::Normal);
        break;
    case BuildStep::MessageOutput:
        textFormat.setForeground(mix_colors(p.color(QPalette::Text), QColor(Qt::blue)));
        break;
    case BuildStep::ErrorMessageOutput:
        textFormat.setForeground(mix_colors(p.color(QPalette::Text), QColor(Qt::red)));
        textFormat.setFontWeight(QFont::Bold);
        break;

    }

    m_outputWindow->appendText(text, textFormat);
}

void CompileOutputWindow::clearContents()
{
    m_outputWindow->clear();
    m_outputWindow->clearTasks();
    m_taskPositions.clear();
}

void CompileOutputWindow::visibilityChanged(bool)
{

}

int CompileOutputWindow::priorityInStatusBar() const
{
    return 50;
}

bool CompileOutputWindow::canNext() const
{
    return false;
}

bool CompileOutputWindow::canPrevious() const
{
    return false;
}

void CompileOutputWindow::goToNext()
{

}

void CompileOutputWindow::goToPrev()
{

}

bool CompileOutputWindow::canNavigate() const
{
    return false;
}

void CompileOutputWindow::registerPositionOf(const Task &task)
{
    int blocknumber = m_outputWindow->blockCount();
    if (blocknumber > MAX_LINECOUNT)
        return;

    m_taskPositions.insert(task.taskId, blocknumber);
    m_outputWindow->addTask(task, blocknumber);
}

bool CompileOutputWindow::knowsPositionOf(const Task &task)
{
    return (m_taskPositions.contains(task.taskId));
}

void CompileOutputWindow::showPositionOf(const Task &task)
{
    int position = m_taskPositions.value(task.taskId);
    QTextCursor newCursor(m_outputWindow->document()->findBlockByNumber(position));
    newCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
    m_outputWindow->setTextCursor(newCursor);
}
<commit_msg>Make the compile output window use the text editor font<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** 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.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "compileoutputwindow.h"
#include "buildmanager.h"
#include "showoutputtaskhandler.h"
#include "task.h"
#include "projectexplorerconstants.h"
#include "projectexplorer.h"
#include "projectexplorersettings.h"
#include "taskhub.h"

#include <coreplugin/icontext.h>
#include <find/basetextfind.h>
#include <aggregation/aggregate.h>
#include <extensionsystem/pluginmanager.h>
#include <texteditor/texteditorsettings.h>
#include <texteditor/fontsettings.h>

#include <QKeyEvent>
#include <QIcon>
#include <QTextCharFormat>
#include <QTextBlock>
#include <QTextCursor>
#include <QTextEdit>
#include <QScrollBar>
#include <QPlainTextEdit>
#include <QToolButton>

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

namespace {
const int MAX_LINECOUNT = 50000;
}

namespace ProjectExplorer {
namespace Internal {

class CompileOutputTextEdit : public Core::OutputWindow
{
    Q_OBJECT
public:
    CompileOutputTextEdit(const Core::Context &context) : Core::OutputWindow(context)
    {
        fontSettingsChanged();
        connect(TextEditor::TextEditorSettings::instance(), SIGNAL(fontSettingsChanged(TextEditor::FontSettings)),
                this, SLOT(fontSettingsChanged()));
    }

    void addTask(const Task &task, int blocknumber)
    {
        m_taskids.insert(blocknumber, task.taskId);
    }

    void clearTasks()
    {
        m_taskids.clear();
    }
private slots:
    void fontSettingsChanged()
    {
        setFont(TextEditor::TextEditorSettings::instance()->fontSettings().font());
    }

protected:
     void mouseDoubleClickEvent(QMouseEvent *ev)
     {
        int line = cursorForPosition(ev->pos()).block().blockNumber();
        if (unsigned taskid = m_taskids.value(line, 0)) {
            ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
            TaskHub *hub = pm->getObject<TaskHub>();
            hub->showTaskInEditor(taskid);
        } else {
            QPlainTextEdit::mouseDoubleClickEvent(ev);
        }
    }

private:
    QHash<int, unsigned int> m_taskids;   //Map blocknumber to taskId
};

} // namespace Internal
} // namespace ProjectExplorer

CompileOutputWindow::CompileOutputWindow(BuildManager * /*bm*/, QAction *cancelBuildAction) :
    m_cancelBuildButton(new QToolButton)
{
    Core::Context context(Constants::C_COMPILE_OUTPUT);
    m_outputWindow = new CompileOutputTextEdit(context);
    m_outputWindow->setWindowTitle(tr("Compile Output"));
    m_outputWindow->setWindowIcon(QIcon(QLatin1String(Constants::ICON_WINDOW)));
    m_outputWindow->setReadOnly(true);
    m_outputWindow->setUndoRedoEnabled(false);
    m_outputWindow->setMaxLineCount(MAX_LINECOUNT);

    m_cancelBuildButton->setDefaultAction(cancelBuildAction);

    Aggregation::Aggregate *agg = new Aggregation::Aggregate;
    agg->add(m_outputWindow);
    agg->add(new Find::BaseTextFind(m_outputWindow));

    qRegisterMetaType<QTextCharFormat>("QTextCharFormat");

    m_handler = new ShowOutputTaskHandler(this);
    ExtensionSystem::PluginManager::instance()->addObject(m_handler);
    connect(ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()),
            this, SLOT(updateWordWrapMode()));
    updateWordWrapMode();
}

CompileOutputWindow::~CompileOutputWindow()
{
    ExtensionSystem::PluginManager::instance()->removeObject(m_handler);
    delete m_handler;
    delete m_cancelBuildButton;
}

void CompileOutputWindow::updateWordWrapMode()
{
    m_outputWindow->setWordWrapEnabled(ProjectExplorerPlugin::instance()->projectExplorerSettings().wrapAppOutput);
}

bool CompileOutputWindow::hasFocus() const
{
    return m_outputWindow->hasFocus();
}

bool CompileOutputWindow::canFocus() const
{
    return true;
}

void CompileOutputWindow::setFocus()
{
    m_outputWindow->setFocus();
}

QWidget *CompileOutputWindow::outputWidget(QWidget *)
{
    return m_outputWindow;
}

QList<QWidget *> CompileOutputWindow::toolBarWidgets() const
{
     return QList<QWidget *>() << m_cancelBuildButton;
}

static QColor mix_colors(QColor a, QColor b)
{
    return QColor((a.red() + 2 * b.red()) / 3, (a.green() + 2 * b.green()) / 3,
                  (a.blue() + 2* b.blue()) / 3, (a.alpha() + 2 * b.alpha()) / 3);
}

void CompileOutputWindow::appendText(const QString &text, ProjectExplorer::BuildStep::OutputFormat format)
{
    QPalette p = m_outputWindow->palette();
    QTextCharFormat textFormat;
    switch (format) {
    case BuildStep::NormalOutput:
        textFormat.setForeground(p.color(QPalette::Text));
        textFormat.setFontWeight(QFont::Normal);
        break;
    case BuildStep::ErrorOutput:
        textFormat.setForeground(mix_colors(p.color(QPalette::Text), QColor(Qt::red)));
        textFormat.setFontWeight(QFont::Normal);
        break;
    case BuildStep::MessageOutput:
        textFormat.setForeground(mix_colors(p.color(QPalette::Text), QColor(Qt::blue)));
        break;
    case BuildStep::ErrorMessageOutput:
        textFormat.setForeground(mix_colors(p.color(QPalette::Text), QColor(Qt::red)));
        textFormat.setFontWeight(QFont::Bold);
        break;

    }

    m_outputWindow->appendText(text, textFormat);
}

void CompileOutputWindow::clearContents()
{
    m_outputWindow->clear();
    m_outputWindow->clearTasks();
    m_taskPositions.clear();
}

void CompileOutputWindow::visibilityChanged(bool)
{

}

int CompileOutputWindow::priorityInStatusBar() const
{
    return 50;
}

bool CompileOutputWindow::canNext() const
{
    return false;
}

bool CompileOutputWindow::canPrevious() const
{
    return false;
}

void CompileOutputWindow::goToNext()
{

}

void CompileOutputWindow::goToPrev()
{

}

bool CompileOutputWindow::canNavigate() const
{
    return false;
}

void CompileOutputWindow::registerPositionOf(const Task &task)
{
    int blocknumber = m_outputWindow->blockCount();
    if (blocknumber > MAX_LINECOUNT)
        return;

    m_taskPositions.insert(task.taskId, blocknumber);
    m_outputWindow->addTask(task, blocknumber);
}

bool CompileOutputWindow::knowsPositionOf(const Task &task)
{
    return (m_taskPositions.contains(task.taskId));
}

void CompileOutputWindow::showPositionOf(const Task &task)
{
    int position = m_taskPositions.value(task.taskId);
    QTextCursor newCursor(m_outputWindow->document()->findBlockByNumber(position));
    newCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
    m_outputWindow->setTextCursor(newCursor);
}

#include "compileoutputwindow.moc"
<|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 "projectloadwizard.h"

#include "qt4project.h"
#include "qt4projectmanager.h"
#include "qmakestep.h"
#include "makestep.h"

#include <extensionsystem/pluginmanager.h>

#include <QtGui/QCheckBox>
#include <QtGui/QHeaderView>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWizardPage>

using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;

ProjectLoadWizard::ProjectLoadWizard(Qt4Project *project, QWidget *parent, Qt::WindowFlags flags)
    : QWizard(parent, flags), m_project(project), m_importVersion(0), m_temporaryVersion(false)
{
    QtVersionManager * vm = QtVersionManager::instance();
    QString directory = QFileInfo(project->file()->fileName()).absolutePath();
    QString importVersion =  QtVersionManager::findQMakeBinaryFromMakefile(directory);

    if (!importVersion.isNull()) {
        // This also means we have a build in there
        // First get the qt version
        m_importVersion = vm->qtVersionForQMakeBinary(importVersion);
        // Okay does not yet exist, create
        if (!m_importVersion) {
            m_importVersion = new QtVersion(importVersion);
            m_temporaryVersion = true;
        }

        QPair<QtVersion::QmakeBuildConfig, QStringList> result =
                QtVersionManager::scanMakeFile(directory, m_importVersion->defaultBuildConfig());
        m_importBuildConfig = result.first;
        m_additionalArguments = result.second;

        QString versionSpec = m_importVersion->sourcePath() + "/mkspecs/" + m_importVersion->mkspec();
        QString parsedSpec = Qt4Project::extractSpecFromArgumentList(m_additionalArguments);

        // Compare mkspecs and add to additional arguments
        if (parsedSpec.isEmpty()) {
            // using the default spec, don't modify additional arguments
        } else {
            QString parsedSpecOrginal = parsedSpec;
            if (QFileInfo(parsedSpec).isRelative())
                parsedSpec = QDir::cleanPath(directory + "/" + parsedSpec);
            m_additionalArguments = Qt4Project::removeSpecFromArgumentList(m_additionalArguments);
            if (parsedSpec != versionSpec) {
                m_additionalArguments.prepend(parsedSpecOrginal);
                m_additionalArguments.prepend("-spec");
            }
        }
    }

    // So now we have the version and the configuration for that version
    // If buildAll we create debug and release configurations,
    // if not then just either debug or release
    // The default buildConfiguration depends on QmakeBuildConfig::DebugBuild
    // Also if the qt version is not yet in the Tools Options dialog we offer to add it there

    if (m_importVersion)
        setupImportPage(m_importVersion, m_importBuildConfig, m_additionalArguments);

    setOptions(options() | QWizard::NoCancelButton | QWizard::NoBackButtonOnLastPage);
}

// We don't want to actually show the dialog if we don't show the import page
// We used to simply call ::exec() on the dialog
void ProjectLoadWizard::execDialog()
{
    if (m_importVersion)
        exec();
    else
        done(QDialog::Accepted);
}

ProjectLoadWizard::~ProjectLoadWizard()
{

}

void ProjectLoadWizard::addBuildConfiguration(QString buildConfigurationName, QtVersion *qtversion, QtVersion::QmakeBuildConfig qmakeBuildConfiguration, QStringList additionalArguments)
{
    QMakeStep *qmakeStep = m_project->qmakeStep();
    MakeStep *makeStep = m_project->makeStep();

    bool debug = qmakeBuildConfiguration & QtVersion::DebugBuild;

    // Add the buildconfiguration
    ProjectExplorer::BuildConfiguration *bc = new ProjectExplorer::BuildConfiguration(buildConfigurationName);
    m_project->addBuildConfiguration(bc);
    const QString &finalBuildConfigurationName = bc->name();
    qmakeStep->setValue(finalBuildConfigurationName, "qmakeArgs", additionalArguments);

    // set some options for qmake and make
    if (qmakeBuildConfiguration & QtVersion::BuildAll) // debug_and_release => explicit targets
        makeStep->setValue(finalBuildConfigurationName, "makeargs", QStringList() << (debug ? "debug" : "release"));

    bc->setValue("buildConfiguration", int(qmakeBuildConfiguration));

    // Finally set the qt version
    bool defaultQtVersion = (qtversion == 0);
    if (defaultQtVersion)
        m_project->setQtVersion(bc, 0);
    else
        m_project->setQtVersion(bc, qtversion->uniqueId());
}

void ProjectLoadWizard::done(int result)
{
    QtVersionManager *vm = QtVersionManager::instance();
    QWizard::done(result);
    // This normally happens on showing the final page, but since we
    // don't show it anymore, do it here

    QString directory = QFileInfo(m_project->file()->fileName()).absolutePath();
    if (m_importVersion && importCheckbox->isChecked()) {
        // Importing
        if (m_temporaryVersion)
            vm->addVersion(m_importVersion);
        // Import the existing stuff
        // qDebug()<<"Creating m_buildconfiguration entry from imported stuff";
        // qDebug()<<((m_importBuildConfig& QtVersion::BuildAll)? "debug_and_release" : "")<<((m_importBuildConfig & QtVersion::DebugBuild)? "debug" : "release");
        bool debug = m_importBuildConfig & QtVersion::DebugBuild;
        addBuildConfiguration(debug ? "Debug" : "Release", m_importVersion, m_importBuildConfig, m_additionalArguments);

        if (m_importBuildConfig & QtVersion::BuildAll) {
            // Also create the other configuration
            QtVersion::QmakeBuildConfig otherBuildConfiguration = m_importBuildConfig;
            if (debug)
                otherBuildConfiguration = QtVersion::QmakeBuildConfig(otherBuildConfiguration & ~ QtVersion::DebugBuild);
            else
                otherBuildConfiguration = QtVersion::QmakeBuildConfig(otherBuildConfiguration | QtVersion::DebugBuild);

            addBuildConfiguration(debug ? "Release" : "Debug", m_importVersion, otherBuildConfiguration, m_additionalArguments);
        }
    } else {
        // Not importing
        if (m_temporaryVersion)
            delete m_importVersion;
        // Create default
        bool buildAll = false;
        QtVersion *defaultVersion = vm->version(0);
        if (defaultVersion && defaultVersion->isValid() && (defaultVersion->defaultBuildConfig() & QtVersion::BuildAll))
            buildAll = true;
        if (buildAll) {
            addBuildConfiguration("Debug", 0, QtVersion::QmakeBuildConfig(QtVersion::BuildAll | QtVersion::DebugBuild), m_additionalArguments);
            addBuildConfiguration("Release", 0, QtVersion::BuildAll, m_additionalArguments);
        } else {
            addBuildConfiguration("Debug", 0, QtVersion::DebugBuild, m_additionalArguments);
            addBuildConfiguration("Release", 0, QtVersion::QmakeBuildConfig(0), m_additionalArguments);
        }
    }

    if (!m_project->buildConfigurations().isEmpty())
        m_project->setActiveBuildConfiguration(m_project->buildConfigurations().at(0));
}

// This function used to do the commented stuff instead of having only one page
int ProjectLoadWizard::nextId() const
{
    return -1;
}

void ProjectLoadWizard::setupImportPage(QtVersion *version, QtVersion::QmakeBuildConfig buildConfig, QStringList addtionalArguments)
{
    resize(605, 490);
    // Import Page
    importPage = new QWizardPage(this);
    importPage->setTitle(tr("Import existing settings"));
    QVBoxLayout *importLayout = new QVBoxLayout(importPage);
    importLabel = new QLabel(importPage);

    QString versionString = version->name() + " (" + QDir::toNativeSeparators(version->qmakeCommand()) + ")";
    QString buildConfigString = (buildConfig & QtVersion::BuildAll) ? QLatin1String("debug_and_release ") : QLatin1String("");
    buildConfigString.append((buildConfig & QtVersion::DebugBuild) ? QLatin1String("debug") : QLatin1String("release"));
    importLabel->setTextFormat(Qt::RichText);
    importLabel->setText(tr("Qt Creator has found an already existing build in the source directory.

"
                         "Qt Version: %1
"
                         "Build configuration: %2
"
                         "Additional QMake Arguments:%3")
                         .arg(versionString)
                         .arg(buildConfigString)
                         .arg(ProjectExplorer::Environment::joinArgumentList(addtionalArguments)));

    importLayout->addWidget(importLabel);

    importCheckbox = new QCheckBox(importPage);
    importCheckbox->setText(tr("Import existing build settings."));
    importCheckbox->setChecked(true);
    importLayout->addWidget(importCheckbox);
    import2Label = new QLabel(importPage);
    import2Label->setTextFormat(Qt::RichText);
    if (m_temporaryVersion)
        import2Label->setText(tr("Note: Importing the settings will automatically add the Qt Version identified by
%1 to the list of Qt versions.")
                              .arg(QDir::toNativeSeparators(m_importVersion->qmakeCommand())));
    importLayout->addWidget(import2Label);
    addPage(importPage);
}

<commit_msg>Remove unused variable.<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 "projectloadwizard.h"

#include "qt4project.h"
#include "qt4projectmanager.h"
#include "qmakestep.h"
#include "makestep.h"

#include <extensionsystem/pluginmanager.h>

#include <QtGui/QCheckBox>
#include <QtGui/QHeaderView>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWizardPage>

using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;

ProjectLoadWizard::ProjectLoadWizard(Qt4Project *project, QWidget *parent, Qt::WindowFlags flags)
    : QWizard(parent, flags), m_project(project), m_importVersion(0), m_temporaryVersion(false)
{
    QtVersionManager * vm = QtVersionManager::instance();
    QString directory = QFileInfo(project->file()->fileName()).absolutePath();
    QString importVersion =  QtVersionManager::findQMakeBinaryFromMakefile(directory);

    if (!importVersion.isNull()) {
        // This also means we have a build in there
        // First get the qt version
        m_importVersion = vm->qtVersionForQMakeBinary(importVersion);
        // Okay does not yet exist, create
        if (!m_importVersion) {
            m_importVersion = new QtVersion(importVersion);
            m_temporaryVersion = true;
        }

        QPair<QtVersion::QmakeBuildConfig, QStringList> result =
                QtVersionManager::scanMakeFile(directory, m_importVersion->defaultBuildConfig());
        m_importBuildConfig = result.first;
        m_additionalArguments = result.second;

        QString versionSpec = m_importVersion->sourcePath() + "/mkspecs/" + m_importVersion->mkspec();
        QString parsedSpec = Qt4Project::extractSpecFromArgumentList(m_additionalArguments);

        // Compare mkspecs and add to additional arguments
        if (parsedSpec.isEmpty()) {
            // using the default spec, don't modify additional arguments
        } else {
            QString parsedSpecOrginal = parsedSpec;
            if (QFileInfo(parsedSpec).isRelative())
                parsedSpec = QDir::cleanPath(directory + "/" + parsedSpec);
            m_additionalArguments = Qt4Project::removeSpecFromArgumentList(m_additionalArguments);
            if (parsedSpec != versionSpec) {
                m_additionalArguments.prepend(parsedSpecOrginal);
                m_additionalArguments.prepend("-spec");
            }
        }
    }

    // So now we have the version and the configuration for that version
    // If buildAll we create debug and release configurations,
    // if not then just either debug or release
    // The default buildConfiguration depends on QmakeBuildConfig::DebugBuild
    // Also if the qt version is not yet in the Tools Options dialog we offer to add it there

    if (m_importVersion)
        setupImportPage(m_importVersion, m_importBuildConfig, m_additionalArguments);

    setOptions(options() | QWizard::NoCancelButton | QWizard::NoBackButtonOnLastPage);
}

// We don't want to actually show the dialog if we don't show the import page
// We used to simply call ::exec() on the dialog
void ProjectLoadWizard::execDialog()
{
    if (m_importVersion)
        exec();
    else
        done(QDialog::Accepted);
}

ProjectLoadWizard::~ProjectLoadWizard()
{

}

void ProjectLoadWizard::addBuildConfiguration(QString buildConfigurationName, QtVersion *qtversion, QtVersion::QmakeBuildConfig qmakeBuildConfiguration, QStringList additionalArguments)
{
    QMakeStep *qmakeStep = m_project->qmakeStep();
    MakeStep *makeStep = m_project->makeStep();

    bool debug = qmakeBuildConfiguration & QtVersion::DebugBuild;

    // Add the buildconfiguration
    ProjectExplorer::BuildConfiguration *bc = new ProjectExplorer::BuildConfiguration(buildConfigurationName);
    m_project->addBuildConfiguration(bc);
    const QString &finalBuildConfigurationName = bc->name();
    qmakeStep->setValue(finalBuildConfigurationName, "qmakeArgs", additionalArguments);

    // set some options for qmake and make
    if (qmakeBuildConfiguration & QtVersion::BuildAll) // debug_and_release => explicit targets
        makeStep->setValue(finalBuildConfigurationName, "makeargs", QStringList() << (debug ? "debug" : "release"));

    bc->setValue("buildConfiguration", int(qmakeBuildConfiguration));

    // Finally set the qt version
    bool defaultQtVersion = (qtversion == 0);
    if (defaultQtVersion)
        m_project->setQtVersion(bc, 0);
    else
        m_project->setQtVersion(bc, qtversion->uniqueId());
}

void ProjectLoadWizard::done(int result)
{
    QtVersionManager *vm = QtVersionManager::instance();
    QWizard::done(result);
    // This normally happens on showing the final page, but since we
    // don't show it anymore, do it here

    if (m_importVersion && importCheckbox->isChecked()) {
        // Importing
        if (m_temporaryVersion)
            vm->addVersion(m_importVersion);
        // Import the existing stuff
        // qDebug()<<"Creating m_buildconfiguration entry from imported stuff";
        // qDebug()<<((m_importBuildConfig& QtVersion::BuildAll)? "debug_and_release" : "")<<((m_importBuildConfig & QtVersion::DebugBuild)? "debug" : "release");
        bool debug = m_importBuildConfig & QtVersion::DebugBuild;
        addBuildConfiguration(debug ? "Debug" : "Release", m_importVersion, m_importBuildConfig, m_additionalArguments);

        if (m_importBuildConfig & QtVersion::BuildAll) {
            // Also create the other configuration
            QtVersion::QmakeBuildConfig otherBuildConfiguration = m_importBuildConfig;
            if (debug)
                otherBuildConfiguration = QtVersion::QmakeBuildConfig(otherBuildConfiguration & ~ QtVersion::DebugBuild);
            else
                otherBuildConfiguration = QtVersion::QmakeBuildConfig(otherBuildConfiguration | QtVersion::DebugBuild);

            addBuildConfiguration(debug ? "Release" : "Debug", m_importVersion, otherBuildConfiguration, m_additionalArguments);
        }
    } else {
        // Not importing
        if (m_temporaryVersion)
            delete m_importVersion;
        // Create default
        bool buildAll = false;
        QtVersion *defaultVersion = vm->version(0);
        if (defaultVersion && defaultVersion->isValid() && (defaultVersion->defaultBuildConfig() & QtVersion::BuildAll))
            buildAll = true;
        if (buildAll) {
            addBuildConfiguration("Debug", 0, QtVersion::QmakeBuildConfig(QtVersion::BuildAll | QtVersion::DebugBuild), m_additionalArguments);
            addBuildConfiguration("Release", 0, QtVersion::BuildAll, m_additionalArguments);
        } else {
            addBuildConfiguration("Debug", 0, QtVersion::DebugBuild, m_additionalArguments);
            addBuildConfiguration("Release", 0, QtVersion::QmakeBuildConfig(0), m_additionalArguments);
        }
    }

    if (!m_project->buildConfigurations().isEmpty())
        m_project->setActiveBuildConfiguration(m_project->buildConfigurations().at(0));
}

// This function used to do the commented stuff instead of having only one page
int ProjectLoadWizard::nextId() const
{
    return -1;
}

void ProjectLoadWizard::setupImportPage(QtVersion *version, QtVersion::QmakeBuildConfig buildConfig, QStringList addtionalArguments)
{
    resize(605, 490);
    // Import Page
    importPage = new QWizardPage(this);
    importPage->setTitle(tr("Import existing settings"));
    QVBoxLayout *importLayout = new QVBoxLayout(importPage);
    importLabel = new QLabel(importPage);

    QString versionString = version->name() + " (" + QDir::toNativeSeparators(version->qmakeCommand()) + ")";
    QString buildConfigString = (buildConfig & QtVersion::BuildAll) ? QLatin1String("debug_and_release ") : QLatin1String("");
    buildConfigString.append((buildConfig & QtVersion::DebugBuild) ? QLatin1String("debug") : QLatin1String("release"));
    importLabel->setTextFormat(Qt::RichText);
    importLabel->setText(tr("Qt Creator has found an already existing build in the source directory.

"
                         "Qt Version: %1
"
                         "Build configuration: %2
"
                         "Additional QMake Arguments:%3")
                         .arg(versionString)
                         .arg(buildConfigString)
                         .arg(ProjectExplorer::Environment::joinArgumentList(addtionalArguments)));

    importLayout->addWidget(importLabel);

    importCheckbox = new QCheckBox(importPage);
    importCheckbox->setText(tr("Import existing build settings."));
    importCheckbox->setChecked(true);
    importLayout->addWidget(importCheckbox);
    import2Label = new QLabel(importPage);
    import2Label->setTextFormat(Qt::RichText);
    if (m_temporaryVersion)
        import2Label->setText(tr("Note: Importing the settings will automatically add the Qt Version identified by
%1 to the list of Qt versions.")
                              .arg(QDir::toNativeSeparators(m_importVersion->qmakeCommand())));
    importLayout->addWidget(import2Label);
    addPage(importPage);
}

<|endoftext|>


<commit_before>/**********************************************************************
* File:        tessedit.cpp  (Formerly tessedit.c)
* Description: Main program for merge of tess and editor.
* Author:                  Ray Smith
* Created:                 Tue Jan 07 15:21:46 GMT 1992
*
* (C) Copyright 1992, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*
**********************************************************************/

// #define USE_VLD //Uncomment for Visual Leak Detector.
#if (defined _MSC_VER && defined USE_VLD)
#include "mfcpch.h"
#include <vld.h>
#endif

// Include automatically generated configuration file if running autoconf
#ifdef HAVE_CONFIG_H
#include "config_auto.h"
#endif
#ifdef USING_GETTEXT
#include <libintl.h>
#include <locale.h>
#define _(x) gettext(x)
#else
#define _(x) (x)
#endif

#include "allheaders.h"
#include "baseapi.h"
#include "basedir.h"
#include "strngs.h"
#include "tesseractmain.h"
#include "tprintf.h"

/**********************************************************************
 *  main()
 *
 **********************************************************************/

int main(int argc, char **argv) {
#ifdef USING_GETTEXT
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);
#endif
  if ((argc == 2 && strcmp(argv[1], "-v") == 0) ||
      (argc == 2 && strcmp(argv[1], "--version") == 0)) {
    char *versionStrP;

    fprintf(stderr, "tesseract %s\n", tesseract::TessBaseAPI::Version());

    versionStrP = getLeptonicaVersion();
    fprintf(stderr, " %s\n", versionStrP);
    lept_free(versionStrP);

    versionStrP = getImagelibVersions();
    fprintf(stderr, "  %s\n", versionStrP);
    lept_free(versionStrP);

    exit(0);
  }

  // Make the order of args a bit more forgiving than it used to be.
  const char* lang = "eng";
  const char* image = NULL;
  const char* output = NULL;
  bool noocr = false;
  bool list_langs = false;
  bool print_parameters = false;

  tesseract::PageSegMode pagesegmode = tesseract::PSM_AUTO;
  int arg = 1;
  while (arg < argc && (output == NULL || argv[arg][0] == '-')) {
    if (strcmp(argv[arg], "-l") == 0 && arg + 1 < argc) {
      lang = argv[arg + 1];
      ++arg;
    } else if (strcmp(argv[arg], "-psm") == 0 && arg + 1 < argc) {
      pagesegmode = static_cast<tesseract::PageSegMode>(atoi(argv[arg + 1]));
      ++arg;
    } else if (strcmp(argv[arg], "--print-parameters") == 0) {
      noocr = true;
      print_parameters = true;
    } else if (strcmp(argv[arg], "-c") == 0 && arg + 1 < argc) {
      // handled properly after api init
      ++arg;
    } else if (image == NULL) {
      image = argv[arg];
    } else if (output == NULL) {
      output = argv[arg];
    }
    ++arg;
  }

  if (argc == 2 && strcmp(argv[1], "--list-langs") == 0) {
    list_langs = true;
    noocr = true;
  }

  if (output == NULL && noocr == false) {
    fprintf(stderr, _("Usage:%s imagename outputbase|stdout [-l lang] "
                      "[-psm pagesegmode] [-c configvar=value] "
                      "[configfile...]\n\n"), argv[0]);
    fprintf(stderr,
            _("pagesegmode values are:\n"
              "0 = Orientation and script detection (OSD) only.\n"
              "1 = Automatic page segmentation with OSD.\n"
              "2 = Automatic page segmentation, but no OSD, or OCR\n"
              "3 = Fully automatic page segmentation, but no OSD. (Default)\n"
              "4 = Assume a single column of text of variable sizes.\n"
              "5 = Assume a single uniform block of vertically aligned text.\n"
              "6 = Assume a single uniform block of text.\n"
              "7 = Treat the image as a single text line.\n"
              "8 = Treat the image as a single word.\n"
              "9 = Treat the image as a single word in a circle.\n"
              "10 = Treat the image as a single character.\n"));
    fprintf(stderr, _("multiple -c arguments are allowed.\n"));
    fprintf(stderr, _("-l lang, -psm pagesegmode and any -c options must occur"
                      "before any configfile.\n\n"));
    fprintf(stderr, _("Single options:\n"));
    fprintf(stderr, _("  -v --version: version info\n"));
    fprintf(stderr, _("  --list-langs: list available languages for tesseract "
                      "engine\n"));
    fprintf(stderr, _("  --print-parameters: print tesseract parameters to the "
                      "stdout\n"));
    exit(1);
  }

  tesseract::TessBaseAPI api;

  STRING tessdata_dir;
  truncate_path(argv[0], &tessdata_dir);
  api.SetOutputName(output);
  int rc = api.Init(tessdata_dir.string(), lang, tesseract::OEM_DEFAULT,
                &(argv[arg]), argc - arg, NULL, NULL, false);

  if (rc) {
    fprintf(stderr, _("Could not initialize tesseract.\n"));
    exit(1);
  }

  char opt1[255], opt2[255];
  for (arg = 0; arg < argc; arg++) {
    if (strcmp(argv[arg], "-c") == 0 && arg + 1 < argc) {
      strncpy(opt1, argv[arg + 1], 255);
      *(strchr(opt1, '=')) = 0;
      strncpy(opt2, strchr(argv[arg + 1], '=') + 1, 255);
      opt2[254] = 0;
      ++arg;

      if(!api.SetVariable(opt1, opt2)) {
        fprintf(stderr, _("Could not set option: %s=%s\n"), opt1, opt2);
      }
    }
  }

  if (list_langs) {
     GenericVector<STRING> languages;
     api.GetAvailableLanguagesAsVector(&languages);
     fprintf(stderr, _("List of available languages (%d):\n"),
             languages.size());
     for (int index = 0; index < languages.size(); ++index) {
       STRING& string = languages[index];
       fprintf(stderr, "%s\n", string.string());
     }
     api.End();
     exit(0);
  }

  if (print_parameters) {
     FILE* fout = stdout;
     fprintf(stdout, _("Tesseract parameters:\n"));
     api.PrintVariables(fout);
     api.End();
     exit(0);
  }

  // We have 2 possible sources of pagesegmode: a config file and
  // the command line. For backwards compatability reasons, the
  // default in tesseract is tesseract::PSM_SINGLE_BLOCK, but the
  // default for this program is tesseract::PSM_AUTO. We will let
  // the config file take priority, so the command-line default
  // can take priority over the tesseract default, so we use the
  // value from the command line only if the retrieved mode
  // is still tesseract::PSM_SINGLE_BLOCK, indicating no change
  // in any config file. Therefore the only way to force
  // tesseract::PSM_SINGLE_BLOCK is from the command line.
  // It would be simpler if we could set the value before Init,
  // but that doesn't work.
  if (api.GetPageSegMode() == tesseract::PSM_SINGLE_BLOCK)
    api.SetPageSegMode(pagesegmode);
  tprintf("Tesseract Open Source OCR Engine v%s with Leptonica\n",
           tesseract::TessBaseAPI::Version());

  FILE* fin = fopen(image, "rb");
  if (fin == NULL) {
    fprintf(stderr, _("Cannot open input file: %s\n"), image);
    exit(2);
  }
  fclose(fin);

  PIX   *pixs;
  if ((pixs = pixRead(image)) == NULL) {
    fprintf(stderr, _("Unsupported image type.\n"));
    exit(3);
  }
  pixDestroy(&pixs);

  bool output_hocr = false;
  api.GetBoolVariable("tessedit_create_hocr", &output_hocr);
  bool output_box = false;
  api.GetBoolVariable("tessedit_create_boxfile", &output_box);

  FILE* fout = stdout;
  if (strcmp(output, "-") && strcmp(output, "stdout")) {
    STRING outfile = output;
    outfile += output_hocr ? ".html" : output_box ? ".box" : ".txt";
    fout = fopen(outfile.string(), "wb");
    if (fout == NULL) {
      fprintf(stderr, _("Cannot create output file %s\n"), outfile.string());
      exit(1);
    }
  }

  STRING text_out;
  if (!api.ProcessPages(image, NULL, 0, &text_out)) {
    fprintf(stderr, _("Error during processing.\n"));
    if (fout != stdout)
      fclose(fout);
	exit(1);
  }

  fwrite(text_out.string(), 1, text_out.length(), fout);
  if (fout != stdout)
    fclose(fout);
  else
    clearerr(fout);

  return 0;                      // Normal exit
}

#ifdef _WIN32

char szAppName[] = "Tesseract";   //app name
int initialized = 0;

/**********************************************************************
* WinMain
*
* Main function for a windows program.
**********************************************************************/

int WINAPI WinMain(  //main for windows //command line
        HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpszCmdLine,
        int nCmdShow) {
  WNDCLASS wc;
  HWND hwnd;
  MSG msg;

  char **argv;
  char *argsin[2];
  int argc;
  int exit_code;

  wc.style = CS_NOCLOSE | CS_OWNDC;
  wc.lpfnWndProc = (WNDPROC) WndProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hInstance;
  wc.hIcon = NULL;         //LoadIcon (NULL, IDI_APPLICATION);
  wc.hCursor = NULL;       //LoadCursor (NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = szAppName;

  RegisterClass(&wc);

  hwnd = CreateWindow (szAppName, szAppName,
                       WS_OVERLAPPEDWINDOW | WS_DISABLED,
                       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                       CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL);

  argsin[0] = strdup (szAppName);
  argsin[1] = strdup (lpszCmdLine);
  /*allocate memory for the args. There can never be more than half*/
  /*the total number of characters in the arguments.*/
  argv = (char **)malloc(((strlen(argsin[0]) + strlen(argsin[1])) / 2 + 1) *
                         sizeof(char *));

  /*now construct argv as it should be for C.*/
  argc = parse_args (2, argsin, argv);

  //  ShowWindow (hwnd, nCmdShow);
  //  UpdateWindow (hwnd);

  if (initialized) {
    exit_code = main (argc, argv);
    free (argsin[0]);
    free (argsin[1]);
    free(argv);
    return exit_code;
  }
  while (GetMessage (&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    if (initialized) {
      exit_code = main (argc, argv);
      break;
    }
    else
      exit_code = msg.wParam;
  }
  free (argsin[0]);
  free (argsin[1]);
  free(argv);
  return exit_code;
}

/**********************************************************************
* WndProc
*
* Function to respond to messages.
**********************************************************************/

LONG WINAPI WndProc(            //message handler
        HWND hwnd,              //window with message
        UINT msg,               //message typ
        WPARAM wParam,
        LPARAM lParam) {
  HDC hdc;

  if (msg == WM_CREATE) {
    //
    // Create a rendering context.
    //
    hdc = GetDC (hwnd);
    ReleaseDC(hwnd, hdc);
    initialized = 1;
    return 0;
  }
  return DefWindowProc (hwnd, msg, wParam, lParam);
}

/**********************************************************************
* parse_args
*
* Turn a list of args into a new list of args with each separate
* whitespace spaced string being an arg.
**********************************************************************/

int
parse_args (                     /*refine arg list */
        int argc,                /*no of input args */
        char *argv[],            /*input args */
        char *arglist[]          /*output args */
        ) {
  int argcount;            /*converted argc */
  char *testchar;          /*char in option string */
  int arg;                 /*current argument */

  argcount = 0;            /*no of options */
  for (arg = 0; arg < argc; arg++) {
    testchar = argv[arg]; /*start of arg */
    do {
      while (*testchar
             && (*testchar == ' ' || *testchar == '\n'
                 || *testchar == '\t'))
        testchar++; /*skip white space */
      if (*testchar) {
        /*new arg */
        arglist[argcount++] = testchar;
        /*skip to white space */
        for (testchar++; *testchar && *testchar != ' ' && *testchar != '\n' && *testchar != '\t'; testchar++) ;
        if (*testchar)
          *testchar++ = '\0'; /*turn to separate args */
      }
    }
    while (*testchar);
  }
  return argcount;         /*new number of args */
}
#endif
<commit_msg>allow to have text file with list of images as input<commit_after>/**********************************************************************
* File:        tessedit.cpp  (Formerly tessedit.c)
* Description: Main program for merge of tess and editor.
* Author:                  Ray Smith
* Created:                 Tue Jan 07 15:21:46 GMT 1992
*
* (C) Copyright 1992, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*
**********************************************************************/

// #define USE_VLD //Uncomment for Visual Leak Detector.
#if (defined _MSC_VER && defined USE_VLD)
#include "mfcpch.h"
#include <vld.h>
#endif

// Include automatically generated configuration file if running autoconf
#ifdef HAVE_CONFIG_H
#include "config_auto.h"
#endif
#ifdef USING_GETTEXT
#include <libintl.h>
#include <locale.h>
#define _(x) gettext(x)
#else
#define _(x) (x)
#endif

#include "allheaders.h"
#include "baseapi.h"
#include "basedir.h"
#include "strngs.h"
#include "tesseractmain.h"
#include "tprintf.h"

/**********************************************************************
 *  main()
 *
 **********************************************************************/

int main(int argc, char **argv) {
#ifdef USING_GETTEXT
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);
#endif
  if ((argc == 2 && strcmp(argv[1], "-v") == 0) ||
      (argc == 2 && strcmp(argv[1], "--version") == 0)) {
    char *versionStrP;

    fprintf(stderr, "tesseract %s\n", tesseract::TessBaseAPI::Version());

    versionStrP = getLeptonicaVersion();
    fprintf(stderr, " %s\n", versionStrP);
    lept_free(versionStrP);

    versionStrP = getImagelibVersions();
    fprintf(stderr, "  %s\n", versionStrP);
    lept_free(versionStrP);

    exit(0);
  }

  // Make the order of args a bit more forgiving than it used to be.
  const char* lang = "eng";
  const char* image = NULL;
  const char* output = NULL;
  bool noocr = false;
  bool list_langs = false;
  bool print_parameters = false;

  tesseract::PageSegMode pagesegmode = tesseract::PSM_AUTO;
  int arg = 1;
  while (arg < argc && (output == NULL || argv[arg][0] == '-')) {
    if (strcmp(argv[arg], "-l") == 0 && arg + 1 < argc) {
      lang = argv[arg + 1];
      ++arg;
    } else if (strcmp(argv[arg], "-psm") == 0 && arg + 1 < argc) {
      pagesegmode = static_cast<tesseract::PageSegMode>(atoi(argv[arg + 1]));
      ++arg;
    } else if (strcmp(argv[arg], "--print-parameters") == 0) {
      noocr = true;
      print_parameters = true;
    } else if (strcmp(argv[arg], "-c") == 0 && arg + 1 < argc) {
      // handled properly after api init
      ++arg;
    } else if (image == NULL) {
      image = argv[arg];
    } else if (output == NULL) {
      output = argv[arg];
    }
    ++arg;
  }

  if (argc == 2 && strcmp(argv[1], "--list-langs") == 0) {
    list_langs = true;
    noocr = true;
  }

  if (output == NULL && noocr == false) {
    fprintf(stderr, _("Usage:%s imagename outputbase|stdout [-l lang] "
                      "[-psm pagesegmode] [-c configvar=value] "
                      "[configfile...]\n\n"), argv[0]);
    fprintf(stderr,
            _("pagesegmode values are:\n"
              "0 = Orientation and script detection (OSD) only.\n"
              "1 = Automatic page segmentation with OSD.\n"
              "2 = Automatic page segmentation, but no OSD, or OCR\n"
              "3 = Fully automatic page segmentation, but no OSD. (Default)\n"
              "4 = Assume a single column of text of variable sizes.\n"
              "5 = Assume a single uniform block of vertically aligned text.\n"
              "6 = Assume a single uniform block of text.\n"
              "7 = Treat the image as a single text line.\n"
              "8 = Treat the image as a single word.\n"
              "9 = Treat the image as a single word in a circle.\n"
              "10 = Treat the image as a single character.\n"));
    fprintf(stderr, _("multiple -c arguments are allowed.\n"));
    fprintf(stderr, _("-l lang, -psm pagesegmode and any -c options must occur"
                      "before any configfile.\n\n"));
    fprintf(stderr, _("Single options:\n"));
    fprintf(stderr, _("  -v --version: version info\n"));
    fprintf(stderr, _("  --list-langs: list available languages for tesseract "
                      "engine\n"));
    fprintf(stderr, _("  --print-parameters: print tesseract parameters to the "
                      "stdout\n"));
    exit(1);
  }

  tesseract::TessBaseAPI api;

  STRING tessdata_dir;
  truncate_path(argv[0], &tessdata_dir);
  api.SetOutputName(output);
  int rc = api.Init(tessdata_dir.string(), lang, tesseract::OEM_DEFAULT,
                &(argv[arg]), argc - arg, NULL, NULL, false);

  if (rc) {
    fprintf(stderr, _("Could not initialize tesseract.\n"));
    exit(1);
  }

  char opt1[255], opt2[255];
  for (arg = 0; arg < argc; arg++) {
    if (strcmp(argv[arg], "-c") == 0 && arg + 1 < argc) {
      strncpy(opt1, argv[arg + 1], 255);
      *(strchr(opt1, '=')) = 0;
      strncpy(opt2, strchr(argv[arg + 1], '=') + 1, 255);
      opt2[254] = 0;
      ++arg;

      if(!api.SetVariable(opt1, opt2)) {
        fprintf(stderr, _("Could not set option: %s=%s\n"), opt1, opt2);
      }
    }
  }

  if (list_langs) {
     GenericVector<STRING> languages;
     api.GetAvailableLanguagesAsVector(&languages);
     fprintf(stderr, _("List of available languages (%d):\n"),
             languages.size());
     for (int index = 0; index < languages.size(); ++index) {
       STRING& string = languages[index];
       fprintf(stderr, "%s\n", string.string());
     }
     api.End();
     exit(0);
  }

  if (print_parameters) {
     FILE* fout = stdout;
     fprintf(stdout, _("Tesseract parameters:\n"));
     api.PrintVariables(fout);
     api.End();
     exit(0);
  }

  // We have 2 possible sources of pagesegmode: a config file and
  // the command line. For backwards compatability reasons, the
  // default in tesseract is tesseract::PSM_SINGLE_BLOCK, but the
  // default for this program is tesseract::PSM_AUTO. We will let
  // the config file take priority, so the command-line default
  // can take priority over the tesseract default, so we use the
  // value from the command line only if the retrieved mode
  // is still tesseract::PSM_SINGLE_BLOCK, indicating no change
  // in any config file. Therefore the only way to force
  // tesseract::PSM_SINGLE_BLOCK is from the command line.
  // It would be simpler if we could set the value before Init,
  // but that doesn't work.
  if (api.GetPageSegMode() == tesseract::PSM_SINGLE_BLOCK)
    api.SetPageSegMode(pagesegmode);
  tprintf("Tesseract Open Source OCR Engine v%s with Leptonica\n",
           tesseract::TessBaseAPI::Version());

  FILE* fin = fopen(image, "rb");
  if (fin == NULL) {
    fprintf(stderr, _("Cannot open input file: %s\n"), image);
    exit(2);
  }
  fclose(fin);

  bool output_hocr = false;
  api.GetBoolVariable("tessedit_create_hocr", &output_hocr);
  bool output_box = false;
  api.GetBoolVariable("tessedit_create_boxfile", &output_box);

  FILE* fout = stdout;
  if (strcmp(output, "-") && strcmp(output, "stdout")) {
    STRING outfile = output;
    outfile += output_hocr ? ".html" : output_box ? ".box" : ".txt";
    fout = fopen(outfile.string(), "wb");
    if (fout == NULL) {
      fprintf(stderr, _("Cannot create output file %s\n"), outfile.string());
      exit(1);
    }
  }

  STRING text_out;
  if (!api.ProcessPages(image, NULL, 0, &text_out)) {
    fprintf(stderr, _("Error during processing.\n"));
    if (fout != stdout)
      fclose(fout);
	exit(1);
  }

  fwrite(text_out.string(), 1, text_out.length(), fout);
  if (fout != stdout)
    fclose(fout);
  else
    clearerr(fout);

  return 0;                      // Normal exit
}

#ifdef _WIN32

char szAppName[] = "Tesseract";   //app name
int initialized = 0;

/**********************************************************************
* WinMain
*
* Main function for a windows program.
**********************************************************************/

int WINAPI WinMain(  //main for windows //command line
        HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpszCmdLine,
        int nCmdShow) {
  WNDCLASS wc;
  HWND hwnd;
  MSG msg;

  char **argv;
  char *argsin[2];
  int argc;
  int exit_code;

  wc.style = CS_NOCLOSE | CS_OWNDC;
  wc.lpfnWndProc = (WNDPROC) WndProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hInstance;
  wc.hIcon = NULL;         //LoadIcon (NULL, IDI_APPLICATION);
  wc.hCursor = NULL;       //LoadCursor (NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = szAppName;

  RegisterClass(&wc);

  hwnd = CreateWindow (szAppName, szAppName,
                       WS_OVERLAPPEDWINDOW | WS_DISABLED,
                       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                       CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL);

  argsin[0] = strdup (szAppName);
  argsin[1] = strdup (lpszCmdLine);
  /*allocate memory for the args. There can never be more than half*/
  /*the total number of characters in the arguments.*/
  argv = (char **)malloc(((strlen(argsin[0]) + strlen(argsin[1])) / 2 + 1) *
                         sizeof(char *));

  /*now construct argv as it should be for C.*/
  argc = parse_args (2, argsin, argv);

  //  ShowWindow (hwnd, nCmdShow);
  //  UpdateWindow (hwnd);

  if (initialized) {
    exit_code = main (argc, argv);
    free (argsin[0]);
    free (argsin[1]);
    free(argv);
    return exit_code;
  }
  while (GetMessage (&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    if (initialized) {
      exit_code = main (argc, argv);
      break;
    }
    else
      exit_code = msg.wParam;
  }
  free (argsin[0]);
  free (argsin[1]);
  free(argv);
  return exit_code;
}

/**********************************************************************
* WndProc
*
* Function to respond to messages.
**********************************************************************/

LONG WINAPI WndProc(            //message handler
        HWND hwnd,              //window with message
        UINT msg,               //message typ
        WPARAM wParam,
        LPARAM lParam) {
  HDC hdc;

  if (msg == WM_CREATE) {
    //
    // Create a rendering context.
    //
    hdc = GetDC (hwnd);
    ReleaseDC(hwnd, hdc);
    initialized = 1;
    return 0;
  }
  return DefWindowProc (hwnd, msg, wParam, lParam);
}

/**********************************************************************
* parse_args
*
* Turn a list of args into a new list of args with each separate
* whitespace spaced string being an arg.
**********************************************************************/

int
parse_args (                     /*refine arg list */
        int argc,                /*no of input args */
        char *argv[],            /*input args */
        char *arglist[]          /*output args */
        ) {
  int argcount;            /*converted argc */
  char *testchar;          /*char in option string */
  int arg;                 /*current argument */

  argcount = 0;            /*no of options */
  for (arg = 0; arg < argc; arg++) {
    testchar = argv[arg]; /*start of arg */
    do {
      while (*testchar
             && (*testchar == ' ' || *testchar == '\n'
                 || *testchar == '\t'))
        testchar++; /*skip white space */
      if (*testchar) {
        /*new arg */
        arglist[argcount++] = testchar;
        /*skip to white space */
        for (testchar++; *testchar && *testchar != ' ' && *testchar != '\n' && *testchar != '\t'; testchar++) ;
        if (*testchar)
          *testchar++ = '\0'; /*turn to separate args */
      }
    }
    while (*testchar);
  }
  return argcount;         /*new number of args */
}
#endif
<|endoftext|>


<commit_before>#include "layer_t.hpp"
#include "input_handler.hpp"

namespace rltk {

void layer_t::make_owner_draw_backing() {
	if (!backing) {
		backing = std::make_unique<sf::RenderTexture>();
	}
	backing->create(w, h);
}

void layer_t::on_resize(const int width, const int height) {
	resize_func(this, width, height);
	if (console && console->visible) {
		console->set_offset(x,y);
		console->resize_pixels(w, h);
	} else {
		make_owner_draw_backing();
	}
}

void layer_t::render(sf::RenderWindow &window) {
	if (console) {
		if (!controls.empty()) {

			// Render start events
			for (auto it=controls.begin(); it != controls.end(); ++it) {
				if (it->second->on_render_start) {
					auto callfunc = it->second->on_render_start.get();
					callfunc(it->second.get());
				}
			}

			int mouse_x, mouse_y;
			std::tie(mouse_x, mouse_y) = get_mouse_position();

			if (mouse_x >= x && mouse_x <= (x+w) && mouse_y >= y && mouse_y <= (y+h)) {
				// Mouse over in here is possible.
				auto font_dimensions = console->get_font_size();
				const int terminal_x = (mouse_x - x) / font_dimensions.first;
				const int terminal_y = (mouse_y - y) / font_dimensions.second;

				for (auto it=controls.begin(); it != controls.end(); ++it) {
					// Mouse over
					if (it->second->mouse_in_control(terminal_x, terminal_y)) {
						if (it->second->on_mouse_over) {
							auto callfunc = it->second->on_mouse_over.get();
							callfunc(it->second.get(), terminal_x, terminal_y);
						}

						// Mouse down and up
						if (get_mouse_button_state(button::LEFT) && it->second->on_mouse_down) {
							auto callfunc = it->second->on_mouse_down.get();
							callfunc(it->second.get(), terminal_x, terminal_y);
						}
						if (!get_mouse_button_state(button::LEFT) && it->second->on_mouse_up) {
							auto callfunc = it->second->on_mouse_up.get();
							callfunc(it->second.get(), terminal_x, terminal_y);
						}
					}
				}
			}

			for (auto it=controls.begin(); it != controls.end(); ++it) {
				it->second->render(console.get());
			}
		}
		console->render(window);
	} else if (sconsole) {
		sconsole->render(window);
	} else {
		if (!backing) make_owner_draw_backing();
		backing->clear(sf::Color(0,0,0,0));
		owner_draw_func(this, *backing);
		backing->display();
		sf::Sprite compositor(backing->getTexture());
		compositor.move(x, y);
		window.draw(sf::Sprite(compositor));
	}
}

void resize_fullscreen(rltk::layer_t * l, int w, int h) {
        // Use the whole window
        l->w = w;
        l->h = h;
}

}
<commit_msg>Fix formatting<commit_after>#include "layer_t.hpp"
#include "input_handler.hpp"

namespace rltk {

void layer_t::make_owner_draw_backing() {
	if (!backing) {
		backing = std::make_unique<sf::RenderTexture>();
	}
	backing->create(w, h);
}

void layer_t::on_resize(const int width, const int height) {
	resize_func(this, width, height);
	if (console && console->visible) {
		console->set_offset(x,y);
		console->resize_pixels(w, h);
		console->dirty = true;
	} else {
		make_owner_draw_backing();
	}
}

void layer_t::render(sf::RenderWindow &window) {
	if (console) {
		if (!controls.empty()) {

			// Render start events
			for (auto it=controls.begin(); it != controls.end(); ++it) {
				if (it->second->on_render_start) {
					auto callfunc = it->second->on_render_start.get();
					callfunc(it->second.get());
				}
			}

			int mouse_x, mouse_y;
			std::tie(mouse_x, mouse_y) = get_mouse_position();

			if (mouse_x >= x && mouse_x <= (x+w) && mouse_y >= y && mouse_y <= (y+h)) {
				// Mouse over in here is possible.
				auto font_dimensions = console->get_font_size();
				const int terminal_x = (mouse_x - x) / font_dimensions.first;
				const int terminal_y = (mouse_y - y) / font_dimensions.second;

				for (auto it=controls.begin(); it != controls.end(); ++it) {
					// Mouse over
					if (it->second->mouse_in_control(terminal_x, terminal_y)) {
						if (it->second->on_mouse_over) {
							auto callfunc = it->second->on_mouse_over.get();
							callfunc(it->second.get(), terminal_x, terminal_y);
						}

						// Mouse down and up
						if (get_mouse_button_state(button::LEFT) && it->second->on_mouse_down) {
							auto callfunc = it->second->on_mouse_down.get();
							callfunc(it->second.get(), terminal_x, terminal_y);
						}
						if (!get_mouse_button_state(button::LEFT) && it->second->on_mouse_up) {
							auto callfunc = it->second->on_mouse_up.get();
							callfunc(it->second.get(), terminal_x, terminal_y);
						}
					}
				}
			}

			for (auto it=controls.begin(); it != controls.end(); ++it) {
				it->second->render(console.get());
			}
		}
		console->render(window);
	} else if (sconsole) {
		sconsole->render(window);
	} else {
		if (!backing) make_owner_draw_backing();
		backing->clear(sf::Color(0,0,0,0));
		owner_draw_func(this, *backing);
		backing->display();
		sf::Sprite compositor(backing->getTexture());
		compositor.move(x, y);
		window.draw(sf::Sprite(compositor));
	}
}

void resize_fullscreen(rltk::layer_t * l, int w, int h) {
    // Use the whole window
    l->w = w;
    l->h = h;
}

}
<|endoftext|>