<commit_before>/* -*- mode: c++; c-basic-offset:4 -*-
    importcertificatecommand.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra 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; either version 2 of the License, or
    (at your option) any later version.

    Kleopatra 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "importcertificatecommand.h"

#include <kleo/cryptobackendfactory.h>
#include <kleo/importjob.h>

#include <gpgme++/global.h>
#include <gpgme++/importresult.h>

#include <KLocale>
#include <KMessageBox>
#include <KJob>

#include <QByteArray>
#include <QFile>
#include <QFileDialog>
#include <QPointer>
#include <QString>
#include <QWidget>

#include <memory>

using namespace GpgME;
using namespace Kleo;

class ImportCertificateCommand::Private {
    friend class ::ImportCertificateCommand;
    ImportCertificateCommand * const q;
public:
    explicit Private( ImportCertificateCommand * qq );
    ~Private();

    bool ensureHaveFile();
    void startImport( const QByteArray& data );
    void importResult( const GpgME::ImportResult& );
    GpgME::Protocol checkProtocol( const QByteArray& data, const QString& filename ) const;
    void showError( const GpgME::Error& error );
    void showDetails( const ImportResult& result );

private:
    QWidget* parent;
    QPointer<ImportJob> importJob;
    QString filename;
};

ImportCertificateCommand::Private::Private( ImportCertificateCommand * qq )
    : q( qq ), parent( 0 ), importJob( 0 )
{

}

ImportCertificateCommand::Private::~Private()
{
    if ( importJob )
        importJob->slotCancel();
}

ImportCertificateCommand::ImportCertificateCommand( KeyListController * parent )
  : Command( parent ), d( new Private( this ) )
{

}

ImportCertificateCommand::~ImportCertificateCommand() {}

void ImportCertificateCommand::setParentWidget( QWidget* parent )
{
    d->parent = parent;
}

QString ImportCertificateCommand::fileName() const
{
    return d->filename;
}

void ImportCertificateCommand::setFileName( const QString& fileName )
{
    d->filename = fileName;
}

void ImportCertificateCommand::doStart()
{
    if ( !d->ensureHaveFile() )
    {
        emit canceled();
        return;
    }
    //TODO: use KIO here
    QFile in( d->filename );
    if ( !in.open( QIODevice::ReadOnly ) )
    {
        KMessageBox::error( d->parent, i18n( "Could not open file %1 for reading", d->filename ), i18n( "Certificate Import Failed" ) );

        emit finished(); //TODO: correct signal??
        return;
    }
    d->startImport( in.readAll() );
    emit info( i18n( "Importing certificate..." ) );
}

bool ImportCertificateCommand::Private::ensureHaveFile()
{
   if ( filename.isNull() )
        filename = QFileDialog::getOpenFileName( parent, i18n( "Select Certificate File" ), QString(), i18n( "Certificates (*.asc *.pem *.der *.p7c *.p12)" )  );
   return !filename.isNull();
}

void ImportCertificateCommand::Private::showDetails( const ImportResult& res )
{
      const KLocalizedString normalLine = ki18n("
%1	%2
");
        const KLocalizedString boldLine = ki18n("
%1	%2
");

        QStringList lines;
        lines.push_back( normalLine.subs( i18n("Total number processed:") )
                         .subs( res.numConsidered() ).toString() );
        lines.push_back( normalLine.subs( i18n("Imported:") )
                         .subs( res.numImported() ).toString() );
        if ( res.newSignatures() )
            lines.push_back( normalLine.subs( i18n("New signatures:") )
                             .subs( res.newSignatures() ).toString() );
        if ( res.newUserIDs() )
            lines.push_back( normalLine.subs( i18n("New user IDs:") )
                             .subs( res.newUserIDs() ).toString() );
        if ( res.numKeysWithoutUserID() )
            lines.push_back( normalLine.subs( i18n("Keys without user IDs:") )
                             .subs( res.numKeysWithoutUserID() ).toString() );
        if ( res.newSubkeys() )
            lines.push_back( normalLine.subs( i18n("New subkeys:") )
                             .subs( res.newSubkeys() ).toString() );
        if ( res.newRevocations() )
            lines.push_back( boldLine.subs( i18n("Newly revoked:") )
                             .subs( res.newRevocations() ).toString() );
        if ( res.notImported() )
            lines.push_back( boldLine.subs( i18n("Not imported:") )
                             .subs( res.notImported() ).toString() );
        if ( res.numUnchanged() )
            lines.push_back( normalLine.subs( i18n("Unchanged:") )
                             .subs( res.numUnchanged() ).toString() );
        if ( res.numSecretKeysConsidered() )
            lines.push_back( normalLine.subs( i18n("Secret keys processed:") )
                             .subs( res.numSecretKeysConsidered() ).toString() );
        if ( res.numSecretKeysImported() )
            lines.push_back( normalLine.subs( i18n("Secret keys imported:") )
                             .subs( res.numSecretKeysImported() ).toString() );
        if ( res.numSecretKeysConsidered() - res.numSecretKeysImported() - res.numSecretKeysUnchanged() > 0 )
            lines.push_back( boldLine.subs( i18n("Secret keys not imported:") )
                             .subs(  res.numSecretKeysConsidered()
                                     - res.numSecretKeysImported()
                                     - res.numSecretKeysUnchanged() ).toString() );
        if ( res.numSecretKeysUnchanged() )
            lines.push_back( normalLine.subs( i18n("Secret keys unchanged:") )
                             .subs( res.numSecretKeysUnchanged() ).toString() );

        KMessageBox::information( parent,
                                  i18n( "<qt>
Detailed results of importing %1:
"
                                        "
%2
</qt>" ,
                                        filename, lines.join( QString() ) ),
                                  i18n( "Certificate Import Result" ) );
}

void ImportCertificateCommand::Private::showError( const GpgME::Error& err )
{
  assert( err );
  const QString msg = i18n( "<qt>
An error occurred while trying "
			    "to import the certificate %1:
"
			    "
%2
</qt>",
                            filename,
                            QString::fromLocal8Bit( err.asString() ) );
  KMessageBox::error( parent, msg, i18n( "Certificate Import Failed" ) );
}

void ImportCertificateCommand::Private::importResult( const GpgME::ImportResult& result )
{
    if ( result.error().isCanceled() ) {
        emit q->canceled();
        return;
    }

    if ( result.error() ) {
        showError( result.error() );
        emit q->finished();
        return;
    }

    showDetails( result );
    emit q->finished();
}

GpgME::Protocol ImportCertificateCommand::Private::checkProtocol( const QByteArray& data, const QString& filename ) const
{
    QStringList smimeSuffixes;
    smimeSuffixes << ".pem" << ".der", ".p7c", ".p12";
    Q_FOREACH ( const QString& i, smimeSuffixes )
        if ( filename.endsWith( i, Qt::CaseInsensitive ) )
            return GpgME::CMS;
    if ( filename.endsWith( ".asc", Qt::CaseInsensitive ) )
        return GpgME::OpenPGP;
    return GpgME::UnknownProtocol;
}

void ImportCertificateCommand::Private::startImport( const QByteArray& data )
{
    const GpgME::Protocol protocol = checkProtocol( data, filename );
    if ( protocol == GpgME::UnknownProtocol ) //TODO: might use exceptions here
    {
        KMessageBox::error( parent, i18n( "Could not determine certificate type.", filename ), i18n( "Certificate Import Failed" ) );
        emit q->canceled(); //TODO: use correct signal
        return;
    }

    std::auto_ptr<ImportJob> job( CryptoBackendFactory::instance()->protocol( protocol )->importJob() );
    assert( job.get() );
    connect( job.get(), SIGNAL(result( GpgME::ImportResult ) ),
             q, SLOT( importResult( GpgME::ImportResult ) ) );
    connect( job.get(), SIGNAL( process( QString, int, int ) ),
             q, SIGNAL( process( QString, int, int ) ) );
    const GpgME::Error err = job->start( data );

    importJob = job.release();
}

void ImportCertificateCommand::doCancel()
{
    if ( d->importJob )
        d->importJob->slotCancel();
}

#include "moc_importcertificatecommand.cpp"

<commit_msg>Compile<commit_after>/* -*- mode: c++; c-basic-offset:4 -*-
    importcertificatecommand.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra 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; either version 2 of the License, or
    (at your option) any later version.

    Kleopatra 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "importcertificatecommand.h"

#include <kleo/cryptobackendfactory.h>
#include <kleo/importjob.h>

#include <gpgme++/global.h>
#include <gpgme++/importresult.h>

#include <KLocale>
#include <KMessageBox>
#include <KJob>

#include <QByteArray>
#include <QFile>
#include <QFileDialog>
#include <QPointer>
#include <QString>
#include <QWidget>

#include <memory>
#include <cassert>

using namespace GpgME;
using namespace Kleo;

class ImportCertificateCommand::Private {
    friend class ::ImportCertificateCommand;
    ImportCertificateCommand * const q;
public:
    explicit Private( ImportCertificateCommand * qq );
    ~Private();

    bool ensureHaveFile();
    void startImport( const QByteArray& data );
    void importResult( const GpgME::ImportResult& );
    GpgME::Protocol checkProtocol( const QByteArray& data, const QString& filename ) const;
    void showError( const GpgME::Error& error );
    void showDetails( const ImportResult& result );

private:
    QWidget* parent;
    QPointer<ImportJob> importJob;
    QString filename;
};

ImportCertificateCommand::Private::Private( ImportCertificateCommand * qq )
    : q( qq ), parent( 0 ), importJob( 0 )
{

}

ImportCertificateCommand::Private::~Private()
{
    if ( importJob )
        importJob->slotCancel();
}

ImportCertificateCommand::ImportCertificateCommand( KeyListController * parent )
  : Command( parent ), d( new Private( this ) )
{

}

ImportCertificateCommand::~ImportCertificateCommand() {}

void ImportCertificateCommand::setParentWidget( QWidget* parent )
{
    d->parent = parent;
}

QString ImportCertificateCommand::fileName() const
{
    return d->filename;
}

void ImportCertificateCommand::setFileName( const QString& fileName )
{
    d->filename = fileName;
}

void ImportCertificateCommand::doStart()
{
    if ( !d->ensureHaveFile() )
    {
        emit canceled();
        return;
    }
    //TODO: use KIO here
    QFile in( d->filename );
    if ( !in.open( QIODevice::ReadOnly ) )
    {
        KMessageBox::error( d->parent, i18n( "Could not open file %1 for reading", d->filename ), i18n( "Certificate Import Failed" ) );

        emit finished(); //TODO: correct signal??
        return;
    }
    d->startImport( in.readAll() );
    emit info( i18n( "Importing certificate..." ) );
}

bool ImportCertificateCommand::Private::ensureHaveFile()
{
   if ( filename.isNull() )
        filename = QFileDialog::getOpenFileName( parent, i18n( "Select Certificate File" ), QString(), i18n( "Certificates (*.asc *.pem *.der *.p7c *.p12)" )  );
   return !filename.isNull();
}

void ImportCertificateCommand::Private::showDetails( const ImportResult& res )
{
      const KLocalizedString normalLine = ki18n("
%1	%2
");
        const KLocalizedString boldLine = ki18n("
%1	%2
");

        QStringList lines;
        lines.push_back( normalLine.subs( i18n("Total number processed:") )
                         .subs( res.numConsidered() ).toString() );
        lines.push_back( normalLine.subs( i18n("Imported:") )
                         .subs( res.numImported() ).toString() );
        if ( res.newSignatures() )
            lines.push_back( normalLine.subs( i18n("New signatures:") )
                             .subs( res.newSignatures() ).toString() );
        if ( res.newUserIDs() )
            lines.push_back( normalLine.subs( i18n("New user IDs:") )
                             .subs( res.newUserIDs() ).toString() );
        if ( res.numKeysWithoutUserID() )
            lines.push_back( normalLine.subs( i18n("Keys without user IDs:") )
                             .subs( res.numKeysWithoutUserID() ).toString() );
        if ( res.newSubkeys() )
            lines.push_back( normalLine.subs( i18n("New subkeys:") )
                             .subs( res.newSubkeys() ).toString() );
        if ( res.newRevocations() )
            lines.push_back( boldLine.subs( i18n("Newly revoked:") )
                             .subs( res.newRevocations() ).toString() );
        if ( res.notImported() )
            lines.push_back( boldLine.subs( i18n("Not imported:") )
                             .subs( res.notImported() ).toString() );
        if ( res.numUnchanged() )
            lines.push_back( normalLine.subs( i18n("Unchanged:") )
                             .subs( res.numUnchanged() ).toString() );
        if ( res.numSecretKeysConsidered() )
            lines.push_back( normalLine.subs( i18n("Secret keys processed:") )
                             .subs( res.numSecretKeysConsidered() ).toString() );
        if ( res.numSecretKeysImported() )
            lines.push_back( normalLine.subs( i18n("Secret keys imported:") )
                             .subs( res.numSecretKeysImported() ).toString() );
        if ( res.numSecretKeysConsidered() - res.numSecretKeysImported() - res.numSecretKeysUnchanged() > 0 )
            lines.push_back( boldLine.subs( i18n("Secret keys not imported:") )
                             .subs(  res.numSecretKeysConsidered()
                                     - res.numSecretKeysImported()
                                     - res.numSecretKeysUnchanged() ).toString() );
        if ( res.numSecretKeysUnchanged() )
            lines.push_back( normalLine.subs( i18n("Secret keys unchanged:") )
                             .subs( res.numSecretKeysUnchanged() ).toString() );

        KMessageBox::information( parent,
                                  i18n( "<qt>
Detailed results of importing %1:
"
                                        "
%2
</qt>" ,
                                        filename, lines.join( QString() ) ),
                                  i18n( "Certificate Import Result" ) );
}

void ImportCertificateCommand::Private::showError( const GpgME::Error& err )
{
  assert( err );
  const QString msg = i18n( "<qt>
An error occurred while trying "
			    "to import the certificate %1:
"
			    "
%2
</qt>",
                            filename,
                            QString::fromLocal8Bit( err.asString() ) );
  KMessageBox::error( parent, msg, i18n( "Certificate Import Failed" ) );
}

void ImportCertificateCommand::Private::importResult( const GpgME::ImportResult& result )
{
    if ( result.error().isCanceled() ) {
        emit q->canceled();
        return;
    }

    if ( result.error() ) {
        showError( result.error() );
        emit q->finished();
        return;
    }

    showDetails( result );
    emit q->finished();
}

GpgME::Protocol ImportCertificateCommand::Private::checkProtocol( const QByteArray& data, const QString& filename ) const
{
    // PENDING(frank) use Kleo::classify!
    QStringList smimeSuffixes;
    smimeSuffixes << ".pem" << ".der" << ".p7c" << ".p12";
    Q_FOREACH ( const QString& i, smimeSuffixes )
        if ( filename.endsWith( i, Qt::CaseInsensitive ) )
            return GpgME::CMS;
    if ( filename.endsWith( ".asc", Qt::CaseInsensitive ) )
        return GpgME::OpenPGP;
    return GpgME::UnknownProtocol;
}

void ImportCertificateCommand::Private::startImport( const QByteArray& data )
{
    const GpgME::Protocol protocol = checkProtocol( data, filename );
    if ( protocol == GpgME::UnknownProtocol ) //TODO: might use exceptions here
    {
        KMessageBox::error( parent, i18n( "Could not determine certificate type.", filename ), i18n( "Certificate Import Failed" ) );
        emit q->canceled(); //TODO: use correct signal
        return;
    }

    std::auto_ptr<ImportJob> job( CryptoBackendFactory::instance()->protocol( protocol )->importJob() );
    assert( job.get() );
    connect( job.get(), SIGNAL(result( GpgME::ImportResult ) ),
             q, SLOT( importResult( GpgME::ImportResult ) ) );
    connect( job.get(), SIGNAL( process( QString, int, int ) ),
             q, SIGNAL( process( QString, int, int ) ) );
    const GpgME::Error err = job->start( data );

    importJob = job.release();
}

void ImportCertificateCommand::doCancel()
{
    if ( d->importJob )
        d->importJob->slotCancel();
}

#include "moc_importcertificatecommand.cpp"

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "puppetcreator.h"

#include <QProcess>
#include <QTemporaryDir>
#include <QCoreApplication>
#include <QCryptographicHash>
#include <QDateTime>
#include <QMessageBox>

#include <projectexplorer/kit.h>
#include <projectexplorer/toolchain.h>
#include <utils/environment.h>
#include <coreplugin/icore.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
#include <coreplugin/icore.h>

#include <qmldesignerwarning.h>
#include "puppetbuildprogressdialog.h"

namespace QmlDesigner {

bool PuppetCreator::m_useOnlyFallbackPuppet = !qgetenv("USE_ONLY_FALLBACK_PUPPET").isEmpty();
QHash<Core::Id, PuppetCreator::PuppetType> PuppetCreator::m_qml1PuppetForKitPuppetHash;
QHash<Core::Id, PuppetCreator::PuppetType> PuppetCreator::m_qml2PuppetForKitPuppetHash;

QByteArray PuppetCreator::qtHash() const
{
    if (m_kit) {
        QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitInformation::qtVersion(m_kit);
        if (currentQtVersion)
            return QCryptographicHash::hash(currentQtVersion->qmakeProperty("QT_INSTALL_DATA").toUtf8(), QCryptographicHash::Sha1).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
    }

    return QByteArray();
}

QDateTime PuppetCreator::qtLastModified() const
{
    if (m_kit) {
        QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitInformation::qtVersion(m_kit);
        if (currentQtVersion)
            return QFileInfo(currentQtVersion->qmakeProperty("QT_INSTALL_LIBS")).lastModified();
    }

    return QDateTime();
}

PuppetCreator::PuppetCreator(ProjectExplorer::Kit *kit, const QString &qtCreatorVersion)
    : m_qtCreatorVersion(qtCreatorVersion),
      m_kit(kit),
      m_availablePuppetType(FallbackPuppet)
{
}

PuppetCreator::~PuppetCreator()
{
}

void PuppetCreator::createPuppetExecutableIfMissing(PuppetCreator::QmlPuppetVersion puppetVersion)
{
    if (puppetVersion == Qml1Puppet)
        createQml1PuppetExecutableIfMissing();
    else
        createQml2PuppetExecutableIfMissing();
}

QProcess *PuppetCreator::createPuppetProcess(PuppetCreator::QmlPuppetVersion puppetVersion, const QString &puppetMode, const QString &socketToken, QObject *handlerObject, const char *outputSlot, const char *finishSlot) const
{
    QString puppetPath;
    if (puppetVersion == Qml1Puppet)
        puppetPath = qmlpuppetPath(m_availablePuppetType);
     else
        puppetPath = qml2puppetPath(m_availablePuppetType);

    return puppetProcess(puppetPath,
                         puppetMode,
                         socketToken,
                         handlerObject,
                         outputSlot,
                         finishSlot);
}

QProcess *PuppetCreator::puppetProcess(const QString &puppetPath,
                                       const QString &puppetMode,
                                       const QString &socketToken,
                                       QObject *handlerObject,
                                       const char *outputSlot,
                                       const char *finishSlot) const
{
    QProcess *puppetProcess = new QProcess;
    puppetProcess->setObjectName(puppetMode);
    puppetProcess->setProcessEnvironment(processEnvironment());
    QObject::connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), puppetProcess, SLOT(kill()));
    QObject::connect(puppetProcess, SIGNAL(finished(int,QProcess::ExitStatus)), handlerObject, finishSlot);
    bool fowardQmlpuppetOutput = !qgetenv("FORWARD_QMLPUPPET_OUTPUT").isEmpty();
    if (fowardQmlpuppetOutput) {
        puppetProcess->setProcessChannelMode(QProcess::MergedChannels);
        QObject::connect(puppetProcess, SIGNAL(readyRead()), handlerObject, outputSlot);
    }
    puppetProcess->start(puppetPath, QStringList() << socketToken << puppetMode << "-graphicssystem raster");

    if (!qgetenv("DEBUG_QML_PUPPET").isEmpty())
        QMessageBox::information(Core::ICore::dialogParent(),
                                 QStringLiteral("Puppet is starting ..."),
                                 QStringLiteral("You can now attach your debugger to the puppet."));

    return puppetProcess;
}

bool PuppetCreator::build(const QString &qmlPuppetProjectFilePath) const
{
    PuppetBuildProgressDialog progressDialog;

    m_compileLog.clear();

    QTemporaryDir buildDirectory;

    bool buildSucceeded = false;

    if (qtIsSupported()) {
        if (buildDirectory.isValid()) {
            QStringList qmakeArguments;
            qmakeArguments.append(QStringLiteral("-r"));
            qmakeArguments.append(QStringLiteral("-after"));
            qmakeArguments.append(QStringLiteral("DESTDIR=") + qmlpuppetDirectory(UserSpacePuppet));
#ifndef QT_DEBUG
            qmakeArguments.append(QStringLiteral("CONFIG+=release"));
#endif
            qmakeArguments.append(qmlPuppetProjectFilePath);
            buildSucceeded = startBuildProcess(buildDirectory.path(), qmakeCommand(), qmakeArguments);
            if (buildSucceeded) {
                progressDialog.show();
                buildSucceeded = startBuildProcess(buildDirectory.path(), buildCommand(), QStringList(), &progressDialog);
                progressDialog.hide();
            }

            if (!buildSucceeded)
                QmlDesignerWarning::show(QCoreApplication::translate("PuppetCreator", "Emulation layer building was unsuccessful"),
                                         QCoreApplication::translate("PuppetCreator",
                                                                     "The emulation layer(Qml Puppet) cannot was built. "
                                                                     "So now the fallback version will be used "
                                                                     "which is not supporting all features."
                                                                     ));
        }
    } else {
        QmlDesignerWarning::show(QCoreApplication::translate("PuppetCreator", "Qt Version is not supported"),
                                 QCoreApplication::translate("PuppetCreator",
                                                             "The emulation layer(Qml Puppet) cannot be built because the Qt version is to old "
                                                             "or it can not run native on your computer. So now the fallback version will be used "
                                                             "which is not supporting all features."
                                                             ));
    }

    return buildSucceeded;
}

void PuppetCreator::createQml1PuppetExecutableIfMissing()
{
    if (!m_useOnlyFallbackPuppet && m_kit) {
        if (m_qml1PuppetForKitPuppetHash.contains(m_kit->id())) {
            m_availablePuppetType = m_qml1PuppetForKitPuppetHash.value(m_kit->id());
        } else if (checkQmlpuppetIsReady()) {
            m_availablePuppetType = UserSpacePuppet;
        } else {
            bool buildSucceeded = build(qmlpuppetProjectFile());
            if (buildSucceeded)
                m_availablePuppetType = UserSpacePuppet;
            else
                m_availablePuppetType = FallbackPuppet;
        }

        m_qml1PuppetForKitPuppetHash.insert(m_kit->id(), m_availablePuppetType);

    } else {
        m_availablePuppetType = FallbackPuppet;
    }
}

void PuppetCreator::createQml2PuppetExecutableIfMissing()
{
    if (!m_useOnlyFallbackPuppet && m_kit) {
        if (m_qml2PuppetForKitPuppetHash.contains(m_kit->id())) {
            m_availablePuppetType = m_qml2PuppetForKitPuppetHash.value(m_kit->id());
        } else if (checkQml2puppetIsReady()) {
            m_availablePuppetType = UserSpacePuppet;
        } else {
            bool buildSucceeded = build(qml2puppetProjectFile());
            if (buildSucceeded)
                m_availablePuppetType = UserSpacePuppet;
            else
                m_availablePuppetType = FallbackPuppet;
        }

        m_qml2PuppetForKitPuppetHash.insert(m_kit->id(), m_availablePuppetType);

    } else {
        m_availablePuppetType = FallbackPuppet;
    }
}

QString PuppetCreator::qmlpuppetDirectory(PuppetType puppetType) const
{

    if (puppetType == UserSpacePuppet)
        return Core::ICore::userResourcePath()
                + QStringLiteral("/qmlpuppet/")
                + QCoreApplication::applicationVersion() + QStringLiteral("/")
                + qtHash();

    return qmlpuppetFallbackDirectory();
}

QString PuppetCreator::qmlpuppetFallbackDirectory() const
{
    return QCoreApplication::applicationDirPath();
}

QString PuppetCreator::qml2puppetPath(PuppetType puppetType) const
{
    return qmlpuppetDirectory(puppetType) + QStringLiteral("/qml2puppet") + QStringLiteral(QTC_HOST_EXE_SUFFIX);
}

QString PuppetCreator::qmlpuppetPath(PuppetType puppetType) const
{
    return qmlpuppetDirectory(puppetType) + QStringLiteral("/qmlpuppet") + QStringLiteral(QTC_HOST_EXE_SUFFIX);
}

QProcessEnvironment PuppetCreator::processEnvironment() const
{
    Utils::Environment environment = Utils::Environment::systemEnvironment();
    m_kit->addToEnvironment(environment);
    environment.set("QML_BAD_GUI_RENDER_LOOP", "true");
    environment.set("QML_USE_MOCKUPS", "true");
    environment.set("QML_PUPPET_MODE", "true");

    return environment.toProcessEnvironment();
}

QString PuppetCreator::buildCommand() const
{
    Utils::Environment environment = Utils::Environment::systemEnvironment();
    m_kit->addToEnvironment(environment);

    ProjectExplorer::ToolChain *toolChain = ProjectExplorer::ToolChainKitInformation::toolChain(m_kit);

    if (toolChain)
        return toolChain->makeCommand(environment);

    return QString();
}

QString PuppetCreator::qmakeCommand() const
{
    QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitInformation::qtVersion(m_kit);
    if (currentQtVersion)
        return currentQtVersion->qmakeCommand().toString();

    return QString();
}

QString PuppetCreator::compileLog() const
{
    return m_compileLog;
}

bool PuppetCreator::startBuildProcess(const QString &buildDirectoryPath,
                                      const QString &command,
                                      const QStringList &processArguments,
                                      PuppetBuildProgressDialog *progressDialog) const
{
    if (command.isEmpty())
        return false;

    QProcess process;
    process.setProcessChannelMode(QProcess::MergedChannels);
    process.setProcessEnvironment(processEnvironment());
    process.setWorkingDirectory(buildDirectoryPath);
    process.start(command, processArguments);
    process.waitForStarted();
    while (process.waitForReadyRead(-1)) {
        QByteArray newOutput = process.readAllStandardOutput();
        if (progressDialog)
            progressDialog->newBuildOutput(newOutput);

        m_compileLog.append(newOutput);
    }

    process.waitForFinished();

    if (process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0)
        return true;
    else
        return false;
}

QString PuppetCreator::puppetSourceDirectoryPath()
{
    return Core::ICore::resourcePath() + QStringLiteral("/qml/qmlpuppet");
}

QString PuppetCreator::qml2puppetProjectFile()
{
    return puppetSourceDirectoryPath() + QStringLiteral("/qml2puppet/qml2puppet.pro");
}

QString PuppetCreator::qmlpuppetProjectFile()
{
    return puppetSourceDirectoryPath() + QStringLiteral("/qmlpuppet/qmlpuppet.pro");
}

bool PuppetCreator::checkPuppetIsReady(const QString &puppetPath) const
{
    QFileInfo puppetFileInfo(puppetPath);

    return puppetFileInfo.exists() && puppetFileInfo.lastModified() > qtLastModified();
}

bool PuppetCreator::checkQml2puppetIsReady() const
{
    return checkPuppetIsReady(qml2puppetPath(UserSpacePuppet));
}

bool PuppetCreator::checkQmlpuppetIsReady() const
{
    return checkPuppetIsReady(qmlpuppetPath(UserSpacePuppet));
}

bool PuppetCreator::qtIsSupported() const
{
    QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitInformation::qtVersion(m_kit);

    if (currentQtVersion
            && currentQtVersion->isValid()
            && currentQtVersion->qtVersion() >= QtSupport::QtVersionNumber(5, 2, 0)
            && (currentQtVersion->type() == QLatin1String(QtSupport::Constants::DESKTOPQT)
                || currentQtVersion->type() == QLatin1String(QtSupport::Constants::SIMULATORQT)))
        return true;

    return false;
}

bool PuppetCreator::checkPuppetVersion(const QString &qmlPuppetPath)
{

    QProcess qmlPuppetVersionProcess;
    qmlPuppetVersionProcess.start(qmlPuppetPath, QStringList() << "--version");
    qmlPuppetVersionProcess.waitForReadyRead(6000);

    QByteArray versionString = qmlPuppetVersionProcess.readAll();

    bool canConvert;
    unsigned int versionNumber = versionString.toUInt(&canConvert);

    return canConvert && versionNumber == 2;

}

} // namespace QmlDesigner
<commit_msg>QmlDesigner: Fix spelling in PuppetCreator::build<commit_after>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "puppetcreator.h"

#include <QProcess>
#include <QTemporaryDir>
#include <QCoreApplication>
#include <QCryptographicHash>
#include <QDateTime>
#include <QMessageBox>

#include <projectexplorer/kit.h>
#include <projectexplorer/toolchain.h>
#include <utils/environment.h>
#include <coreplugin/icore.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
#include <coreplugin/icore.h>

#include <qmldesignerwarning.h>
#include "puppetbuildprogressdialog.h"

namespace QmlDesigner {

bool PuppetCreator::m_useOnlyFallbackPuppet = !qgetenv("USE_ONLY_FALLBACK_PUPPET").isEmpty();
QHash<Core::Id, PuppetCreator::PuppetType> PuppetCreator::m_qml1PuppetForKitPuppetHash;
QHash<Core::Id, PuppetCreator::PuppetType> PuppetCreator::m_qml2PuppetForKitPuppetHash;

QByteArray PuppetCreator::qtHash() const
{
    if (m_kit) {
        QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitInformation::qtVersion(m_kit);
        if (currentQtVersion)
            return QCryptographicHash::hash(currentQtVersion->qmakeProperty("QT_INSTALL_DATA").toUtf8(), QCryptographicHash::Sha1).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
    }

    return QByteArray();
}

QDateTime PuppetCreator::qtLastModified() const
{
    if (m_kit) {
        QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitInformation::qtVersion(m_kit);
        if (currentQtVersion)
            return QFileInfo(currentQtVersion->qmakeProperty("QT_INSTALL_LIBS")).lastModified();
    }

    return QDateTime();
}

PuppetCreator::PuppetCreator(ProjectExplorer::Kit *kit, const QString &qtCreatorVersion)
    : m_qtCreatorVersion(qtCreatorVersion),
      m_kit(kit),
      m_availablePuppetType(FallbackPuppet)
{
}

PuppetCreator::~PuppetCreator()
{
}

void PuppetCreator::createPuppetExecutableIfMissing(PuppetCreator::QmlPuppetVersion puppetVersion)
{
    if (puppetVersion == Qml1Puppet)
        createQml1PuppetExecutableIfMissing();
    else
        createQml2PuppetExecutableIfMissing();
}

QProcess *PuppetCreator::createPuppetProcess(PuppetCreator::QmlPuppetVersion puppetVersion, const QString &puppetMode, const QString &socketToken, QObject *handlerObject, const char *outputSlot, const char *finishSlot) const
{
    QString puppetPath;
    if (puppetVersion == Qml1Puppet)
        puppetPath = qmlpuppetPath(m_availablePuppetType);
     else
        puppetPath = qml2puppetPath(m_availablePuppetType);

    return puppetProcess(puppetPath,
                         puppetMode,
                         socketToken,
                         handlerObject,
                         outputSlot,
                         finishSlot);
}

QProcess *PuppetCreator::puppetProcess(const QString &puppetPath,
                                       const QString &puppetMode,
                                       const QString &socketToken,
                                       QObject *handlerObject,
                                       const char *outputSlot,
                                       const char *finishSlot) const
{
    QProcess *puppetProcess = new QProcess;
    puppetProcess->setObjectName(puppetMode);
    puppetProcess->setProcessEnvironment(processEnvironment());
    QObject::connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), puppetProcess, SLOT(kill()));
    QObject::connect(puppetProcess, SIGNAL(finished(int,QProcess::ExitStatus)), handlerObject, finishSlot);
    bool fowardQmlpuppetOutput = !qgetenv("FORWARD_QMLPUPPET_OUTPUT").isEmpty();
    if (fowardQmlpuppetOutput) {
        puppetProcess->setProcessChannelMode(QProcess::MergedChannels);
        QObject::connect(puppetProcess, SIGNAL(readyRead()), handlerObject, outputSlot);
    }
    puppetProcess->start(puppetPath, QStringList() << socketToken << puppetMode << "-graphicssystem raster");

    if (!qgetenv("DEBUG_QML_PUPPET").isEmpty())
        QMessageBox::information(Core::ICore::dialogParent(),
                                 QStringLiteral("Puppet is starting ..."),
                                 QStringLiteral("You can now attach your debugger to the puppet."));

    return puppetProcess;
}

bool PuppetCreator::build(const QString &qmlPuppetProjectFilePath) const
{
    PuppetBuildProgressDialog progressDialog;

    m_compileLog.clear();

    QTemporaryDir buildDirectory;

    bool buildSucceeded = false;

    if (qtIsSupported()) {
        if (buildDirectory.isValid()) {
            QStringList qmakeArguments;
            qmakeArguments.append(QStringLiteral("-r"));
            qmakeArguments.append(QStringLiteral("-after"));
            qmakeArguments.append(QStringLiteral("DESTDIR=") + qmlpuppetDirectory(UserSpacePuppet));
#ifndef QT_DEBUG
            qmakeArguments.append(QStringLiteral("CONFIG+=release"));
#endif
            qmakeArguments.append(qmlPuppetProjectFilePath);
            buildSucceeded = startBuildProcess(buildDirectory.path(), qmakeCommand(), qmakeArguments);
            if (buildSucceeded) {
                progressDialog.show();
                buildSucceeded = startBuildProcess(buildDirectory.path(), buildCommand(), QStringList(), &progressDialog);
                progressDialog.hide();
            }

            if (!buildSucceeded)
                QmlDesignerWarning::show(QCoreApplication::translate("PuppetCreator", "Emulation layer building was unsuccessful"),
                                         QCoreApplication::translate("PuppetCreator",
                                                                     "The emulation layer (Qml Puppet) cannot be built. "
                                                                     "The fallback emulation layer, which does not support all features, will be used."
                                                                     ));
        }
    } else {
        QmlDesignerWarning::show(QCoreApplication::translate("PuppetCreator", "Qt Version is not supported"),
                                 QCoreApplication::translate("PuppetCreator",
                                                             "The emulation layer (Qml Puppet) cannot be built because the Qt version is too old "
                                                             "or it cannot run natively on your computer. "
                                                             "The fallback emulation layer, which does not support all features, will be used."
                                                             ));
    }

    return buildSucceeded;
}

void PuppetCreator::createQml1PuppetExecutableIfMissing()
{
    if (!m_useOnlyFallbackPuppet && m_kit) {
        if (m_qml1PuppetForKitPuppetHash.contains(m_kit->id())) {
            m_availablePuppetType = m_qml1PuppetForKitPuppetHash.value(m_kit->id());
        } else if (checkQmlpuppetIsReady()) {
            m_availablePuppetType = UserSpacePuppet;
        } else {
            bool buildSucceeded = build(qmlpuppetProjectFile());
            if (buildSucceeded)
                m_availablePuppetType = UserSpacePuppet;
            else
                m_availablePuppetType = FallbackPuppet;
        }

        m_qml1PuppetForKitPuppetHash.insert(m_kit->id(), m_availablePuppetType);

    } else {
        m_availablePuppetType = FallbackPuppet;
    }
}

void PuppetCreator::createQml2PuppetExecutableIfMissing()
{
    if (!m_useOnlyFallbackPuppet && m_kit) {
        if (m_qml2PuppetForKitPuppetHash.contains(m_kit->id())) {
            m_availablePuppetType = m_qml2PuppetForKitPuppetHash.value(m_kit->id());
        } else if (checkQml2puppetIsReady()) {
            m_availablePuppetType = UserSpacePuppet;
        } else {
            bool buildSucceeded = build(qml2puppetProjectFile());
            if (buildSucceeded)
                m_availablePuppetType = UserSpacePuppet;
            else
                m_availablePuppetType = FallbackPuppet;
        }

        m_qml2PuppetForKitPuppetHash.insert(m_kit->id(), m_availablePuppetType);

    } else {
        m_availablePuppetType = FallbackPuppet;
    }
}

QString PuppetCreator::qmlpuppetDirectory(PuppetType puppetType) const
{

    if (puppetType == UserSpacePuppet)
        return Core::ICore::userResourcePath()
                + QStringLiteral("/qmlpuppet/")
                + QCoreApplication::applicationVersion() + QStringLiteral("/")
                + qtHash();

    return qmlpuppetFallbackDirectory();
}

QString PuppetCreator::qmlpuppetFallbackDirectory() const
{
    return QCoreApplication::applicationDirPath();
}

QString PuppetCreator::qml2puppetPath(PuppetType puppetType) const
{
    return qmlpuppetDirectory(puppetType) + QStringLiteral("/qml2puppet") + QStringLiteral(QTC_HOST_EXE_SUFFIX);
}

QString PuppetCreator::qmlpuppetPath(PuppetType puppetType) const
{
    return qmlpuppetDirectory(puppetType) + QStringLiteral("/qmlpuppet") + QStringLiteral(QTC_HOST_EXE_SUFFIX);
}

QProcessEnvironment PuppetCreator::processEnvironment() const
{
    Utils::Environment environment = Utils::Environment::systemEnvironment();
    m_kit->addToEnvironment(environment);
    environment.set("QML_BAD_GUI_RENDER_LOOP", "true");
    environment.set("QML_USE_MOCKUPS", "true");
    environment.set("QML_PUPPET_MODE", "true");

    return environment.toProcessEnvironment();
}

QString PuppetCreator::buildCommand() const
{
    Utils::Environment environment = Utils::Environment::systemEnvironment();
    m_kit->addToEnvironment(environment);

    ProjectExplorer::ToolChain *toolChain = ProjectExplorer::ToolChainKitInformation::toolChain(m_kit);

    if (toolChain)
        return toolChain->makeCommand(environment);

    return QString();
}

QString PuppetCreator::qmakeCommand() const
{
    QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitInformation::qtVersion(m_kit);
    if (currentQtVersion)
        return currentQtVersion->qmakeCommand().toString();

    return QString();
}

QString PuppetCreator::compileLog() const
{
    return m_compileLog;
}

bool PuppetCreator::startBuildProcess(const QString &buildDirectoryPath,
                                      const QString &command,
                                      const QStringList &processArguments,
                                      PuppetBuildProgressDialog *progressDialog) const
{
    if (command.isEmpty())
        return false;

    QProcess process;
    process.setProcessChannelMode(QProcess::MergedChannels);
    process.setProcessEnvironment(processEnvironment());
    process.setWorkingDirectory(buildDirectoryPath);
    process.start(command, processArguments);
    process.waitForStarted();
    while (process.waitForReadyRead(-1)) {
        QByteArray newOutput = process.readAllStandardOutput();
        if (progressDialog)
            progressDialog->newBuildOutput(newOutput);

        m_compileLog.append(newOutput);
    }

    process.waitForFinished();

    if (process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0)
        return true;
    else
        return false;
}

QString PuppetCreator::puppetSourceDirectoryPath()
{
    return Core::ICore::resourcePath() + QStringLiteral("/qml/qmlpuppet");
}

QString PuppetCreator::qml2puppetProjectFile()
{
    return puppetSourceDirectoryPath() + QStringLiteral("/qml2puppet/qml2puppet.pro");
}

QString PuppetCreator::qmlpuppetProjectFile()
{
    return puppetSourceDirectoryPath() + QStringLiteral("/qmlpuppet/qmlpuppet.pro");
}

bool PuppetCreator::checkPuppetIsReady(const QString &puppetPath) const
{
    QFileInfo puppetFileInfo(puppetPath);

    return puppetFileInfo.exists() && puppetFileInfo.lastModified() > qtLastModified();
}

bool PuppetCreator::checkQml2puppetIsReady() const
{
    return checkPuppetIsReady(qml2puppetPath(UserSpacePuppet));
}

bool PuppetCreator::checkQmlpuppetIsReady() const
{
    return checkPuppetIsReady(qmlpuppetPath(UserSpacePuppet));
}

bool PuppetCreator::qtIsSupported() const
{
    QtSupport::BaseQtVersion *currentQtVersion = QtSupport::QtKitInformation::qtVersion(m_kit);

    if (currentQtVersion
            && currentQtVersion->isValid()
            && currentQtVersion->qtVersion() >= QtSupport::QtVersionNumber(5, 2, 0)
            && (currentQtVersion->type() == QLatin1String(QtSupport::Constants::DESKTOPQT)
                || currentQtVersion->type() == QLatin1String(QtSupport::Constants::SIMULATORQT)))
        return true;

    return false;
}

bool PuppetCreator::checkPuppetVersion(const QString &qmlPuppetPath)
{

    QProcess qmlPuppetVersionProcess;
    qmlPuppetVersionProcess.start(qmlPuppetPath, QStringList() << "--version");
    qmlPuppetVersionProcess.waitForReadyRead(6000);

    QByteArray versionString = qmlPuppetVersionProcess.readAll();

    bool canConvert;
    unsigned int versionNumber = versionString.toUInt(&canConvert);

    return canConvert && versionNumber == 2;

}

} // namespace QmlDesigner
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "CursesUI.h"

using namespace std;

CursesUI::CursesUI(const map<PlayerId, string>& p, PlayerId m) :
  players(p), me(m), maxHistory(20), currentHistory(0) {

  // initialize ncurses
  initscr();
  nonl();
  cbreak();
  noecho();

  // create main output window
  mainWin = newwin(LINES - 5, 0, 0, 0);
  wsetscrreg(mainWin, 0, LINES - 2);
  scrollok(mainWin, TRUE);
  wrefresh(mainWin);

  // create target window
  targetWin = newwin(1, 0, LINES - 2, 0);
  wattron(targetWin, A_UNDERLINE);
  targetIter = players.begin();
  updateTargetWin();

  // create command window
  cmdWin = newwin(0, 0, LINES - 1, 0);
  keypad(cmdWin, TRUE);
  nodelay(cmdWin, TRUE);
  updateCmdWin();

  // register commands for tab completion
  comp.registerWord("/lagstats");
  comp.registerWord("/idlestats");
  comp.registerWord("/flaghistory");
  comp.registerWord("/password ");
  comp.registerWord("/report ");
  comp.registerWord("/shutdownserver");
  comp.registerWord("/superkill");
  comp.registerWord("/gameover");
  comp.registerWord("/flag ");
  comp.registerWord("reset");
  comp.registerWord("up");
  comp.registerWord("show");
  comp.registerWord("/kick ");
  comp.registerWord("/playerlist");
  comp.registerWord("/ban ");
  comp.registerWord("/banlist");
  comp.registerWord("/countdown");
  comp.registerWord("/lagwarn ");
  comp.registerWord("/quit");
}

CursesUI::~CursesUI() {
  endwin();
}

void CursesUI::outputMessage(const string& msg) {
  waddstr(mainWin, (msg + "\n").c_str());
  wrefresh(mainWin);
}

bool CursesUI::checkCommand(string& str) {
  wrefresh(cmdWin);
  str = "";
  int i;
  int c = wgetch(cmdWin);
  switch (c) {
  case ERR:
    return false;

    // clear command (21 is Ctrl-U)
  case 21:
    cmd = "";
    updateCmdWin();

    // delete last character
  case KEY_BACKSPACE:
  case KEY_DC:
  case 127:
    cmd = cmd.substr(0, cmd.size() - 1);
    updateCmdWin();
    return false;

    // send command
  case 13:
    if (history.size() == maxHistory)
      history.erase(history.begin());
    history.push_back(cmd);
    str = cmd;
    cmd = "";
    currentHistory = history.size();
    updateCmdWin();
    return true;

    // scroll main window - doesn't work
  case KEY_NPAGE:
    wscrl(mainWin, 1);
    return false;
  case KEY_PPAGE:
    wscrl(mainWin, -1);
    return false;

    // change target
  case KEY_LEFT:
    if (targetIter == players.begin())
      for (unsigned int i = 0; i < players.size() - 1; i++)
	++targetIter;
    else
      targetIter--;
    updateTargetWin();
    return false;
  case KEY_RIGHT:
    targetIter++;
    if (targetIter == players.end())
      targetIter = players.begin();
    updateTargetWin();
    return false;

    // command history
  case KEY_UP:
    if (currentHistory != 0)
      --currentHistory;
    cmd = history[currentHistory];
    updateCmdWin();
    return false;
  case KEY_DOWN:
    if (currentHistory < history.size())
      ++currentHistory;
    if (currentHistory == history.size())
      cmd = "";
    else
      cmd = history[currentHistory];
    updateCmdWin();
    return false;

    // kick target
  case KEY_F(5):
    if (targetIter != players.end() && targetIter->first != me) {
      cmd = "/kick ";
      cmd += targetIter->second;
      targetIter = players.find(me);
      updateCmdWin();
      updateTargetWin();
    }
    return false;

    // we don't have the IP in 1.9
#ifdef V17

    // ban target
  case KEY_F(6):
    if (targetIter != players.end()) {
      cmd = "/ban ";
      cmd += inet_ntoa(targetIter->first.serverHost);
      targetIter = players.find(me);
      updateCmdWin();
      updateTargetWin();
    }
    return false;

#endif

    // tab - autocomplete
  case '\t':
    i = cmd.find_last_of(" \t");
    cmd = cmd.substr(0, i+1) + comp.complete(cmd.substr(i+1));
    updateCmdWin();
    return false;

  default:
    if (c < 32 || c > 127 || cmd.size() >= CMDLENGTH)
      return false;
    cmd += char(c);
    updateCmdWin();
    return false;
  }
}

void CursesUI::addedPlayer(PlayerId p) {
  comp.registerWord(players.find(p)->second);
}

void CursesUI::removingPlayer(PlayerId p) {
  if (targetIter->first == p) {
    targetIter = players.find(me);
    updateTargetWin();
  }
  comp.unregisterWord(players.find(p)->second);
}

PlayerId CursesUI::getTarget() const {
  if (targetIter->first == me)
    return AllPlayers;
  return targetIter->first;
}

void CursesUI::updateTargetWin() {
  wclear(targetWin);
  wmove(targetWin, 0, 0);
  wmove(targetWin, 1, 1);
  string tmp = "Send to ";
  tmp = tmp + (targetIter == players.end() || targetIter->first == me ?
	       "all" : targetIter->second) + ":";
  waddstr(targetWin, tmp.c_str());
  wrefresh(targetWin);
}

void CursesUI::updateCmdWin() {
  wclear(cmdWin);
  wmove(cmdWin, 1, 1);
  waddstr(cmdWin, cmd.c_str());
  wmove(cmdWin, 1, 1 + cmd.size());
  wrefresh(cmdWin);
}
<commit_msg>Removed old 1.7 quick-ban code from bzadmin<commit_after>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "CursesUI.h"

using namespace std;

CursesUI::CursesUI(const map<PlayerId, string>& p, PlayerId m) :
  players(p), me(m), maxHistory(20), currentHistory(0) {

  // initialize ncurses
  initscr();
  nonl();
  cbreak();
  noecho();

  // create main output window
  mainWin = newwin(LINES - 5, 0, 0, 0);
  wsetscrreg(mainWin, 0, LINES - 2);
  scrollok(mainWin, TRUE);
  wrefresh(mainWin);

  // create target window
  targetWin = newwin(1, 0, LINES - 2, 0);
  wattron(targetWin, A_UNDERLINE);
  targetIter = players.begin();
  updateTargetWin();

  // create command window
  cmdWin = newwin(0, 0, LINES - 1, 0);
  keypad(cmdWin, TRUE);
  nodelay(cmdWin, TRUE);
  updateCmdWin();

  // register commands for tab completion
  comp.registerWord("/lagstats");
  comp.registerWord("/idlestats");
  comp.registerWord("/flaghistory");
  comp.registerWord("/password ");
  comp.registerWord("/report ");
  comp.registerWord("/shutdownserver");
  comp.registerWord("/superkill");
  comp.registerWord("/gameover");
  comp.registerWord("/flag ");
  comp.registerWord("reset");
  comp.registerWord("up");
  comp.registerWord("show");
  comp.registerWord("/kick ");
  comp.registerWord("/playerlist");
  comp.registerWord("/ban ");
  comp.registerWord("/banlist");
  comp.registerWord("/countdown");
  comp.registerWord("/lagwarn ");
  comp.registerWord("/quit");
}

CursesUI::~CursesUI() {
  endwin();
}

void CursesUI::outputMessage(const string& msg) {
  waddstr(mainWin, (msg + "\n").c_str());
  wrefresh(mainWin);
}

bool CursesUI::checkCommand(string& str) {
  wrefresh(cmdWin);
  str = "";
  int i;
  int c = wgetch(cmdWin);
  switch (c) {
  case ERR:
    return false;

    // clear command (21 is Ctrl-U)
  case 21:
    cmd = "";
    updateCmdWin();

    // delete last character
  case KEY_BACKSPACE:
  case KEY_DC:
  case 127:
    cmd = cmd.substr(0, cmd.size() - 1);
    updateCmdWin();
    return false;

    // send command
  case 13:
    if (history.size() == maxHistory)
      history.erase(history.begin());
    history.push_back(cmd);
    str = cmd;
    cmd = "";
    currentHistory = history.size();
    updateCmdWin();
    return true;

    // scroll main window - doesn't work
  case KEY_NPAGE:
    wscrl(mainWin, 1);
    return false;
  case KEY_PPAGE:
    wscrl(mainWin, -1);
    return false;

    // change target
  case KEY_LEFT:
    if (targetIter == players.begin())
      for (unsigned int i = 0; i < players.size() - 1; i++)
	++targetIter;
    else
      targetIter--;
    updateTargetWin();
    return false;
  case KEY_RIGHT:
    targetIter++;
    if (targetIter == players.end())
      targetIter = players.begin();
    updateTargetWin();
    return false;

    // command history
  case KEY_UP:
    if (currentHistory != 0)
      --currentHistory;
    cmd = history[currentHistory];
    updateCmdWin();
    return false;
  case KEY_DOWN:
    if (currentHistory < history.size())
      ++currentHistory;
    if (currentHistory == history.size())
      cmd = "";
    else
      cmd = history[currentHistory];
    updateCmdWin();
    return false;

    // kick target
  case KEY_F(5):
    if (targetIter != players.end() && targetIter->first != me) {
      cmd = "/kick ";
      cmd += targetIter->second;
      targetIter = players.find(me);
      updateCmdWin();
      updateTargetWin();
    }
    return false;

    // tab - autocomplete
  case '\t':
    i = cmd.find_last_of(" \t");
    cmd = cmd.substr(0, i+1) + comp.complete(cmd.substr(i+1));
    updateCmdWin();
    return false;

  default:
    if (c < 32 || c > 127 || cmd.size() >= CMDLENGTH)
      return false;
    cmd += char(c);
    updateCmdWin();
    return false;
  }
}

void CursesUI::addedPlayer(PlayerId p) {
  comp.registerWord(players.find(p)->second);
}

void CursesUI::removingPlayer(PlayerId p) {
  if (targetIter->first == p) {
    targetIter = players.find(me);
    updateTargetWin();
  }
  comp.unregisterWord(players.find(p)->second);
}

PlayerId CursesUI::getTarget() const {
  if (targetIter->first == me)
    return AllPlayers;
  return targetIter->first;
}

void CursesUI::updateTargetWin() {
  wclear(targetWin);
  wmove(targetWin, 0, 0);
  wmove(targetWin, 1, 1);
  string tmp = "Send to ";
  tmp = tmp + (targetIter == players.end() || targetIter->first == me ?
	       "all" : targetIter->second) + ":";
  waddstr(targetWin, tmp.c_str());
  wrefresh(targetWin);
}

void CursesUI::updateCmdWin() {
  wclear(cmdWin);
  wmove(cmdWin, 1, 1);
  waddstr(cmdWin, cmd.c_str());
  wmove(cmdWin, 1, 1 + cmd.size());
  wrefresh(cmdWin);
}
<|endoftext|>


<commit_before>/*  Copyright (C) 2009 Imperial College London and others.

Please see the AUTHORS file in the main source directory for a full list
of copyright holders.

Prof. C Pain
Applied Modelling and Computation Group
Department of Earth Science and Engineering
Imperial College London

amcgsoftware@imperial.ac.uk

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation,
version 2.1 of the License.

This library 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 for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
USA
*/

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <math.h>

#include "SampleNetCDF2.h"
#include "confdefs.h"

using namespace std;

extern "C" {
#define get_field_values_fc F77_FUNC(get_field_values, GET_FIELD_VALUES)
        void get_field_values_fc(const char* filename, const double *X, const double *Y, double *Z, int *nodes);

}

void get_field_values_fc(const char* filename, const double *X, const double *Y, double *Z, int *n){

        string file=string(filename);
        SampleNetCDF2 map(file);

        const int nodes = *n;
        double *x = new double[nodes];
        double *y = new double[nodes];
        for (int i = 0; i < nodes; i++) {
          x[i] = X[i];
          y[i] = Y[i];
          if(map.HasPoint(x[i], y[i])){
                Z[i]=map.GetValue(x[i], y[i]);
          }else{
                cerr<<"Point not found in netcdf file\n";
                Z[i]=0.0;
          }
        }

        delete [] x;
        delete [] y;

}<commit_msg>Contributes to fixing bug lp:920944. The netCDF reader used when reading a file specified under ../from_netcdf/file options now gives more feedback when the point requested is not present.  It reports the coordinates and filename to facilitate easier debugging.<commit_after>/*  Copyright (C) 2009 Imperial College London and others.

Please see the AUTHORS file in the main source directory for a full list
of copyright holders.

Prof. C Pain
Applied Modelling and Computation Group
Department of Earth Science and Engineering
Imperial College London

amcgsoftware@imperial.ac.uk

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation,
version 2.1 of the License.

This library 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 for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
USA
*/

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <math.h>

#include "SampleNetCDF2.h"
#include "confdefs.h"

using namespace std;

extern "C" {
#define get_field_values_fc F77_FUNC(get_field_values, GET_FIELD_VALUES)
        void get_field_values_fc(const char* filename, const double *X, const double *Y, double *Z, int *nodes);

}

void get_field_values_fc(const char* filename, const double *X, const double *Y, double *Z, int *n){

        string file=string(filename);
        SampleNetCDF2 map(file);

        const int nodes = *n;
        double *x = new double[nodes];
        double *y = new double[nodes];
        for (int i = 0; i < nodes; i++) {
          x[i] = X[i];
          y[i] = Y[i];
          if(map.HasPoint(x[i], y[i])){
                Z[i]=map.GetValue(x[i], y[i]);
          }else{
                cerr << "Point [ " << x[i] << ", " << y[i] << "] not found in netCDF file, " << file << ".\n";
                Z[i]=0.0;
          }
        }

        delete [] x;
        delete [] y;

}
<|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 "basicproposalitemlistmodel.h"
#include "basicproposalitem.h"
#include "texteditorsettings.h"
#include "completionsettings.h"

#include <QDebug>
#include <QRegExp>
#include <QtAlgorithms>
#include <QHash>

#include <algorithm>

using namespace TextEditor;

uint qHash(const BasicProposalItem &item)
{
    return qHash(item.text());
}

namespace {

const int kMaxSort = 1000;
const int kMaxPrefixFilter = 100;

struct ContentLessThan
{
    bool operator()(const BasicProposalItem *a, const BasicProposalItem *b)
    {
        // If order is different, show higher ones first.
        if (a->order() != b->order())
            return a->order() > b->order();

        // The order is case-insensitive in principle, but case-sensitive when this
        // would otherwise mean equality
        const QString &lowera = a->text().toLower();
        const QString &lowerb = b->text().toLower();
        if (lowera == lowerb)
            return lessThan(a->text(), b->text());
        else
            return lessThan(lowera, lowerb);
    }

    bool lessThan(const QString &a, const QString &b)
    {
        return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), CharLessThan());
    }

    struct CharLessThan
    {
        bool operator()(const QChar &a, const QChar &b)
        {
            if (a == QLatin1Char('_'))
                return false;
            else if (b == QLatin1Char('_'))
                return true;
            else
                return a < b;
        }
    };
};

} // Anonymous

BasicProposalItemListModel::BasicProposalItemListModel()
{}

BasicProposalItemListModel::BasicProposalItemListModel(const QList<BasicProposalItem *> &items)
    : m_originalItems(items)
    , m_currentItems(items)
{
    mapPersistentIds();
}

BasicProposalItemListModel::~BasicProposalItemListModel()
{
    qDeleteAll(m_originalItems);
}

void BasicProposalItemListModel::loadContent(const QList<BasicProposalItem *> &items)
{
    m_originalItems = items;
    m_currentItems = items;
    mapPersistentIds();
}

void BasicProposalItemListModel::mapPersistentIds()
{
    for (int i = 0; i < m_originalItems.size(); ++i)
        m_idByText.insert(m_originalItems.at(i)->text(), i);
}

void BasicProposalItemListModel::reset()
{
    m_currentItems = m_originalItems;
}

int BasicProposalItemListModel::size() const
{
    return m_currentItems.size();
}

QString BasicProposalItemListModel::text(int index) const
{
    return m_currentItems.at(index)->text();
}

QIcon BasicProposalItemListModel::icon(int index) const
{
    return m_currentItems.at(index)->icon();
}

QString BasicProposalItemListModel::detail(int index) const
{
    return m_currentItems.at(index)->detail();
}

void BasicProposalItemListModel::removeDuplicates()
{
    QHash<QString, QVariant> unique;
    QList<BasicProposalItem *>::iterator it = m_originalItems.begin();
    while (it != m_originalItems.end()) {
        const BasicProposalItem *item = *it;
        if (unique.contains(item->text())
                && unique.value(item->text(), QVariant()) == item->data()) {
            it = m_originalItems.erase(it);
        } else {
            unique.insert(item->text(), item->data());
            ++it;
        }
    }
}

void BasicProposalItemListModel::filter(const QString &prefix)
{
    if (prefix.isEmpty())
        return;

    /*
     * This code builds a regular expression in order to more intelligently match
     * camel-case style. This means upper-case characters will be rewritten as follows:
     *
     *   A => [a-z0-9_]*A (for any but the first capital letter)
     *
     * Meaning it allows any sequence of lower-case characters to preceed an
     * upper-case character. So for example gAC matches getActionController.
     *
     * It also implements the first-letter-only case sensitivity.
     */
    const TextEditor::CaseSensitivity caseSensitivity =
        TextEditorSettings::instance()->completionSettings().m_caseSensitivity;

    QString keyRegExp;
    keyRegExp += QLatin1Char('^');
    bool first = true;
    const QLatin1String wordContinuation("[a-z0-9_]*");
    foreach (const QChar &c, prefix) {
        if (caseSensitivity == TextEditor::CaseInsensitive ||
            (caseSensitivity == TextEditor::FirstLetterCaseSensitive && !first)) {

            keyRegExp += QLatin1String("(?:");
            if (c.isUpper() && !first)
                keyRegExp += wordContinuation;
            keyRegExp += QRegExp::escape(c.toUpper());
            keyRegExp += QLatin1Char('|');
            keyRegExp += QRegExp::escape(c.toLower());
            keyRegExp += QLatin1Char(')');
        } else {
            if (c.isUpper() && !first)
                keyRegExp += wordContinuation;
            keyRegExp += QRegExp::escape(c);
        }

        first = false;
    }
    QRegExp regExp(keyRegExp);

    m_currentItems.clear();
    for (QList<BasicProposalItem *>::const_iterator it = m_originalItems.begin();
         it != m_originalItems.end();
         ++it) {
        BasicProposalItem *item = *it;
        if (regExp.indexIn(item->text()) == 0)
            m_currentItems.append(item);
    }
}

bool BasicProposalItemListModel::isSortable(const QString &prefix) const
{
    Q_UNUSED(prefix);

    if (m_currentItems.size() < kMaxSort)
        return true;
    return false;
}

void BasicProposalItemListModel::sort()
{
    qStableSort(m_currentItems.begin(), m_currentItems.end(), ContentLessThan());
}

int BasicProposalItemListModel::persistentId(int index) const
{
    return m_idByText.value(m_currentItems.at(index)->text());
}

bool BasicProposalItemListModel::supportsPrefixExpansion() const
{
    return true;
}

bool BasicProposalItemListModel::keepPerfectMatch(AssistReason reason) const
{
    return reason != IdleEditor;
}

QString BasicProposalItemListModel::proposalPrefix() const
{
    if (m_currentItems.size() >= kMaxPrefixFilter)
        return QString();

    // Compute common prefix
    QString firstKey = m_currentItems.first()->text();
    QString lastKey = m_currentItems.last()->text();
    const int length = qMin(firstKey.length(), lastKey.length());
    firstKey.truncate(length);
    lastKey.truncate(length);

    while (firstKey != lastKey) {
        firstKey.chop(1);
        lastKey.chop(1);
    }

    return firstKey;
}

IAssistProposalItem *BasicProposalItemListModel::proposalItem(int index) const
{
    return m_currentItems.at(index);
}

QPair<QList<BasicProposalItem *>::iterator,
      QList<BasicProposalItem *>::iterator>
BasicProposalItemListModel::currentItems()
{
    return qMakePair(m_currentItems.begin(), m_currentItems.end());
}
<commit_msg>[CodeAssist] Logical sort of proposals.<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 "basicproposalitemlistmodel.h"
#include "basicproposalitem.h"
#include "texteditorsettings.h"
#include "completionsettings.h"

#include <QDebug>
#include <QRegExp>
#include <QtAlgorithms>
#include <QHash>

#include <algorithm>

using namespace TextEditor;

uint qHash(const BasicProposalItem &item)
{
    return qHash(item.text());
}

namespace {

const int kMaxSort = 1000;
const int kMaxPrefixFilter = 100;

struct ContentLessThan
{
    bool operator()(const BasicProposalItem *a, const BasicProposalItem *b)
    {
        // If order is different, show higher ones first.
        if (a->order() != b->order())
            return a->order() > b->order();

        // The order is case-insensitive in principle, but case-sensitive when this
        // would otherwise mean equality
        const QString &lowera = a->text().toLower();
        const QString &lowerb = b->text().toLower();
        if (lowera == lowerb)
            return lessThan(a->text(), b->text());
        else
            return lessThan(lowera, lowerb);
    }

    bool lessThan(const QString &a, const QString &b)
    {
        QString::const_iterator pa = a.begin();
        QString::const_iterator pb = b.begin();

        CharLessThan charLessThan;
        enum { Letter, SmallerNumber, BiggerNumber } state = Letter;
        for (; pa != a.end() && pb != b.end(); ++pa, ++pb) {
            if (*pa == *pb)
                continue;
            if (state != Letter) {
                if (!pa->isDigit() || !pb->isDigit())
                    break;
            } else if (pa->isDigit() && pb->isDigit()) {
                if (charLessThan(*pa, *pb))
                    state = SmallerNumber;
                else
                    state = BiggerNumber;
            } else {
                return charLessThan(*pa, *pb);
            }
        }

        if (state == Letter)
            return pa == a.end() && pb != b.end();
        if (pa != a.end() && pa->isDigit())
            return false;                   //more digits
        if (pb != b.end() && pb->isDigit())
            return true;                    //fewer digits
        return state == SmallerNumber;      //same length, compare first different digit in the sequence
    }

    struct CharLessThan
    {
        bool operator()(const QChar &a, const QChar &b)
        {
            if (a == QLatin1Char('_'))
                return false;
            else if (b == QLatin1Char('_'))
                return true;
            else
                return a < b;
        }
    };
};

} // Anonymous

BasicProposalItemListModel::BasicProposalItemListModel()
{}

BasicProposalItemListModel::BasicProposalItemListModel(const QList<BasicProposalItem *> &items)
    : m_originalItems(items)
    , m_currentItems(items)
{
    mapPersistentIds();
}

BasicProposalItemListModel::~BasicProposalItemListModel()
{
    qDeleteAll(m_originalItems);
}

void BasicProposalItemListModel::loadContent(const QList<BasicProposalItem *> &items)
{
    m_originalItems = items;
    m_currentItems = items;
    mapPersistentIds();
}

void BasicProposalItemListModel::mapPersistentIds()
{
    for (int i = 0; i < m_originalItems.size(); ++i)
        m_idByText.insert(m_originalItems.at(i)->text(), i);
}

void BasicProposalItemListModel::reset()
{
    m_currentItems = m_originalItems;
}

int BasicProposalItemListModel::size() const
{
    return m_currentItems.size();
}

QString BasicProposalItemListModel::text(int index) const
{
    return m_currentItems.at(index)->text();
}

QIcon BasicProposalItemListModel::icon(int index) const
{
    return m_currentItems.at(index)->icon();
}

QString BasicProposalItemListModel::detail(int index) const
{
    return m_currentItems.at(index)->detail();
}

void BasicProposalItemListModel::removeDuplicates()
{
    QHash<QString, QVariant> unique;
    QList<BasicProposalItem *>::iterator it = m_originalItems.begin();
    while (it != m_originalItems.end()) {
        const BasicProposalItem *item = *it;
        if (unique.contains(item->text())
                && unique.value(item->text(), QVariant()) == item->data()) {
            it = m_originalItems.erase(it);
        } else {
            unique.insert(item->text(), item->data());
            ++it;
        }
    }
}

void BasicProposalItemListModel::filter(const QString &prefix)
{
    if (prefix.isEmpty())
        return;

    /*
     * This code builds a regular expression in order to more intelligently match
     * camel-case style. This means upper-case characters will be rewritten as follows:
     *
     *   A => [a-z0-9_]*A (for any but the first capital letter)
     *
     * Meaning it allows any sequence of lower-case characters to preceed an
     * upper-case character. So for example gAC matches getActionController.
     *
     * It also implements the first-letter-only case sensitivity.
     */
    const TextEditor::CaseSensitivity caseSensitivity =
        TextEditorSettings::instance()->completionSettings().m_caseSensitivity;

    QString keyRegExp;
    keyRegExp += QLatin1Char('^');
    bool first = true;
    const QLatin1String wordContinuation("[a-z0-9_]*");
    foreach (const QChar &c, prefix) {
        if (caseSensitivity == TextEditor::CaseInsensitive ||
            (caseSensitivity == TextEditor::FirstLetterCaseSensitive && !first)) {

            keyRegExp += QLatin1String("(?:");
            if (c.isUpper() && !first)
                keyRegExp += wordContinuation;
            keyRegExp += QRegExp::escape(c.toUpper());
            keyRegExp += QLatin1Char('|');
            keyRegExp += QRegExp::escape(c.toLower());
            keyRegExp += QLatin1Char(')');
        } else {
            if (c.isUpper() && !first)
                keyRegExp += wordContinuation;
            keyRegExp += QRegExp::escape(c);
        }

        first = false;
    }
    QRegExp regExp(keyRegExp);

    m_currentItems.clear();
    for (QList<BasicProposalItem *>::const_iterator it = m_originalItems.begin();
         it != m_originalItems.end();
         ++it) {
        BasicProposalItem *item = *it;
        if (regExp.indexIn(item->text()) == 0)
            m_currentItems.append(item);
    }
}

bool BasicProposalItemListModel::isSortable(const QString &prefix) const
{
    Q_UNUSED(prefix);

    if (m_currentItems.size() < kMaxSort)
        return true;
    return false;
}

void BasicProposalItemListModel::sort()
{
    qStableSort(m_currentItems.begin(), m_currentItems.end(), ContentLessThan());
}

int BasicProposalItemListModel::persistentId(int index) const
{
    return m_idByText.value(m_currentItems.at(index)->text());
}

bool BasicProposalItemListModel::supportsPrefixExpansion() const
{
    return true;
}

bool BasicProposalItemListModel::keepPerfectMatch(AssistReason reason) const
{
    return reason != IdleEditor;
}

QString BasicProposalItemListModel::proposalPrefix() const
{
    if (m_currentItems.size() >= kMaxPrefixFilter)
        return QString();

    // Compute common prefix
    QString firstKey = m_currentItems.first()->text();
    QString lastKey = m_currentItems.last()->text();
    const int length = qMin(firstKey.length(), lastKey.length());
    firstKey.truncate(length);
    lastKey.truncate(length);

    while (firstKey != lastKey) {
        firstKey.chop(1);
        lastKey.chop(1);
    }

    return firstKey;
}

IAssistProposalItem *BasicProposalItemListModel::proposalItem(int index) const
{
    return m_currentItems.at(index);
}

QPair<QList<BasicProposalItem *>::iterator,
      QList<BasicProposalItem *>::iterator>
BasicProposalItemListModel::currentItems()
{
    return qMakePair(m_currentItems.begin(), m_currentItems.end());
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef INCLUDED_SC_SOURCE_FILTER_INC_HTMLEXP_HXX
#define INCLUDED_SC_SOURCE_FILTER_INC_HTMLEXP_HXX

#include "global.hxx"
#include <rtl/textenc.h>
#include <tools/gen.hxx>
#include <tools/color.hxx>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/scoped_ptr.hpp>

#include "expbase.hxx"

class ScDocument;
class SfxItemSet;
class SdrPage;
class Graphic;
class SdrObject;
class OutputDevice;
class ScDrawLayer;
class EditTextObject;

namespace editeng { class SvxBorderLine; }

struct ScHTMLStyle
{   // Defaults aus StyleSheet
    Color               aBackgroundColor;
    OUString            aFontFamilyName;
    sal_uInt32          nFontHeight;        // Item-Value
    sal_uInt16          nFontSizeNumber;    // HTML value 1-7
    sal_uInt8           nDefaultScriptType; // Font values are valid for the default script type
    bool                bInitialized;

    ScHTMLStyle() :
        nFontHeight(0),
        nFontSizeNumber(2),
        nDefaultScriptType(),
        bInitialized(false)
    {}

    const ScHTMLStyle& operator=( const ScHTMLStyle& rScHTMLStyle )
    {
        aBackgroundColor   = rScHTMLStyle.aBackgroundColor;
        aFontFamilyName    = rScHTMLStyle.aFontFamilyName;
        nFontHeight        = rScHTMLStyle.nFontHeight;
        nFontSizeNumber    = rScHTMLStyle.nFontSizeNumber;
        nDefaultScriptType = rScHTMLStyle.nDefaultScriptType;
        bInitialized       = rScHTMLStyle.bInitialized;
        return *this;
    }
};

struct ScHTMLGraphEntry
{
    ScRange             aRange;         // ueberlagerter Zellbereich
    Size                aSize;          // Groesse in Pixeln
    Size                aSpace;         // Spacing in Pixeln
    SdrObject*          pObject;
    bool                bInCell;        // ob in Zelle ausgegeben wird
    bool                bWritten;

    ScHTMLGraphEntry( SdrObject* pObj, const ScRange& rRange,
                      const Size& rSize,  bool bIn, const Size& rSpace ) :
        aRange( rRange ),
        aSize( rSize ),
        aSpace( rSpace ),
        pObject( pObj ),
        bInCell( bIn ),
        bWritten( false )
    {}
};

#define SC_HTML_FONTSIZES 7
const short nIndentMax = 23;

class ScHTMLExport : public ScExportBase
{
    // default HtmlFontSz[1-7]
    static const sal_uInt16 nDefaultFontSize[SC_HTML_FONTSIZES];
    // HtmlFontSz[1-7] in s*3.ini [user]
    static sal_uInt16       nFontSize[SC_HTML_FONTSIZES];
    static const char*  pFontSizeCss[SC_HTML_FONTSIZES];
    static const sal_uInt16 nCellSpacing;
    static const sal_Char sIndentSource[];

    typedef boost::scoped_ptr<std::map<OUString, OUString>> FileNameMapPtr;
    typedef boost::ptr_vector< ScHTMLGraphEntry > GraphEntryList;

    GraphEntryList   aGraphList;
    ScHTMLStyle      aHTMLStyle;
    OUString         aBaseURL;
    OUString         aStreamPath;
    OUString         aFilterOptions;
    OUString         aCId;           // Content-Id fuer Mail-Export
    OutputDevice*    pAppWin;        // fuer Pixelei
    FileNameMapPtr   pFileNameMap;        // fuer CopyLocalFileToINet
    OUString         aNonConvertibleChars;   // collect nonconvertible characters
    rtl_TextEncoding eDestEnc;
    SCTAB            nUsedTables;
    short            nIndent;
    sal_Char         sIndent[nIndentMax+1];
    bool             bAll;           // ganzes Dokument
    bool             bTabHasGraphics;
    bool             bTabAlignedLeft;
    bool             bCalcAsShown;
    bool             bCopyLocalFileToINet;
    bool             bTableDataWidth;
    bool             bTableDataHeight;
    bool             mbSkipImages;

    const SfxItemSet& PageDefaults( SCTAB nTab );

    void WriteBody();
    void WriteHeader();
    void WriteOverview();
    void WriteTables();
    void WriteCell( SCCOL nCol, SCROW nRow, SCTAB nTab );
    void WriteGraphEntry( ScHTMLGraphEntry* );
    void WriteImage( OUString& rLinkName,
                     const Graphic&, const OString& rImgOptions,
                     sal_uLong nXOutFlags = 0 );
            // nXOutFlags fuer XOutBitmap::WriteGraphic

    // write to stream if and only if URL fields in edit cell
    bool WriteFieldText( const EditTextObject* pData );

    // kopiere ggfs. eine lokale Datei ins Internet
    bool CopyLocalFileToINet( OUString& rFileNm, const OUString& rTargetNm, bool bFileToFile = false );
    bool HasCId()
    {
        return !aCId.isEmpty();
    }
    void MakeCIdURL( OUString& rURL );

    void PrepareGraphics( ScDrawLayer*, SCTAB nTab,
                          SCCOL nStartCol, SCROW nStartRow,
                          SCCOL nEndCol, SCROW nEndRow );

    void FillGraphList( const SdrPage*, SCTAB nTab,
                        SCCOL nStartCol, SCROW nStartRow,
                        SCCOL nEndCol, SCROW nEndRow );

    OString BorderToStyle(const char* pBorderName,
                          const editeng::SvxBorderLine* pLine,
                          bool& bInsertSemicolon);

    sal_uInt16  GetFontSizeNumber( sal_uInt16 nHeight );
    const char* GetFontSizeCss( sal_uInt16 nHeight );
    sal_uInt16  ToPixel( sal_uInt16 nTwips );
    Size        MMToPixel( const Size& r100thMMSize );
    void        IncIndent( short nVal );

    const sal_Char* GetIndentStr()
    {
        return sIndent;
    }

public:
                        ScHTMLExport( SvStream&, const OUString&, ScDocument*, const ScRange&,
                                      bool bAll, const OUString& aStreamPath, const OUString& rFilterOptions );
    virtual             ~ScHTMLExport();
    sal_uLong           Write();
    const OUString&     GetNonConvertibleChars() const
    {
        return aNonConvertibleChars;
    }
};

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>fix htmlexp.hxx compilation -> add space between ">>"<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef INCLUDED_SC_SOURCE_FILTER_INC_HTMLEXP_HXX
#define INCLUDED_SC_SOURCE_FILTER_INC_HTMLEXP_HXX

#include "global.hxx"
#include <rtl/textenc.h>
#include <tools/gen.hxx>
#include <tools/color.hxx>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/scoped_ptr.hpp>

#include "expbase.hxx"

class ScDocument;
class SfxItemSet;
class SdrPage;
class Graphic;
class SdrObject;
class OutputDevice;
class ScDrawLayer;
class EditTextObject;

namespace editeng { class SvxBorderLine; }

struct ScHTMLStyle
{   // Defaults aus StyleSheet
    Color               aBackgroundColor;
    OUString            aFontFamilyName;
    sal_uInt32          nFontHeight;        // Item-Value
    sal_uInt16          nFontSizeNumber;    // HTML value 1-7
    sal_uInt8           nDefaultScriptType; // Font values are valid for the default script type
    bool                bInitialized;

    ScHTMLStyle() :
        nFontHeight(0),
        nFontSizeNumber(2),
        nDefaultScriptType(),
        bInitialized(false)
    {}

    const ScHTMLStyle& operator=( const ScHTMLStyle& rScHTMLStyle )
    {
        aBackgroundColor   = rScHTMLStyle.aBackgroundColor;
        aFontFamilyName    = rScHTMLStyle.aFontFamilyName;
        nFontHeight        = rScHTMLStyle.nFontHeight;
        nFontSizeNumber    = rScHTMLStyle.nFontSizeNumber;
        nDefaultScriptType = rScHTMLStyle.nDefaultScriptType;
        bInitialized       = rScHTMLStyle.bInitialized;
        return *this;
    }
};

struct ScHTMLGraphEntry
{
    ScRange             aRange;         // ueberlagerter Zellbereich
    Size                aSize;          // Groesse in Pixeln
    Size                aSpace;         // Spacing in Pixeln
    SdrObject*          pObject;
    bool                bInCell;        // ob in Zelle ausgegeben wird
    bool                bWritten;

    ScHTMLGraphEntry( SdrObject* pObj, const ScRange& rRange,
                      const Size& rSize,  bool bIn, const Size& rSpace ) :
        aRange( rRange ),
        aSize( rSize ),
        aSpace( rSpace ),
        pObject( pObj ),
        bInCell( bIn ),
        bWritten( false )
    {}
};

#define SC_HTML_FONTSIZES 7
const short nIndentMax = 23;

class ScHTMLExport : public ScExportBase
{
    // default HtmlFontSz[1-7]
    static const sal_uInt16 nDefaultFontSize[SC_HTML_FONTSIZES];
    // HtmlFontSz[1-7] in s*3.ini [user]
    static sal_uInt16       nFontSize[SC_HTML_FONTSIZES];
    static const char*  pFontSizeCss[SC_HTML_FONTSIZES];
    static const sal_uInt16 nCellSpacing;
    static const sal_Char sIndentSource[];

    typedef boost::scoped_ptr<std::map<OUString, OUString> > FileNameMapPtr;
    typedef boost::ptr_vector<ScHTMLGraphEntry> GraphEntryList;

    GraphEntryList   aGraphList;
    ScHTMLStyle      aHTMLStyle;
    OUString         aBaseURL;
    OUString         aStreamPath;
    OUString         aFilterOptions;
    OUString         aCId;           // Content-Id fuer Mail-Export
    OutputDevice*    pAppWin;        // fuer Pixelei
    FileNameMapPtr   pFileNameMap;        // fuer CopyLocalFileToINet
    OUString         aNonConvertibleChars;   // collect nonconvertible characters
    rtl_TextEncoding eDestEnc;
    SCTAB            nUsedTables;
    short            nIndent;
    sal_Char         sIndent[nIndentMax+1];
    bool             bAll;           // ganzes Dokument
    bool             bTabHasGraphics;
    bool             bTabAlignedLeft;
    bool             bCalcAsShown;
    bool             bCopyLocalFileToINet;
    bool             bTableDataWidth;
    bool             bTableDataHeight;
    bool             mbSkipImages;

    const SfxItemSet& PageDefaults( SCTAB nTab );

    void WriteBody();
    void WriteHeader();
    void WriteOverview();
    void WriteTables();
    void WriteCell( SCCOL nCol, SCROW nRow, SCTAB nTab );
    void WriteGraphEntry( ScHTMLGraphEntry* );
    void WriteImage( OUString& rLinkName,
                     const Graphic&, const OString& rImgOptions,
                     sal_uLong nXOutFlags = 0 );
            // nXOutFlags fuer XOutBitmap::WriteGraphic

    // write to stream if and only if URL fields in edit cell
    bool WriteFieldText( const EditTextObject* pData );

    // kopiere ggfs. eine lokale Datei ins Internet
    bool CopyLocalFileToINet( OUString& rFileNm, const OUString& rTargetNm, bool bFileToFile = false );
    bool HasCId()
    {
        return !aCId.isEmpty();
    }
    void MakeCIdURL( OUString& rURL );

    void PrepareGraphics( ScDrawLayer*, SCTAB nTab,
                          SCCOL nStartCol, SCROW nStartRow,
                          SCCOL nEndCol, SCROW nEndRow );

    void FillGraphList( const SdrPage*, SCTAB nTab,
                        SCCOL nStartCol, SCROW nStartRow,
                        SCCOL nEndCol, SCROW nEndRow );

    OString BorderToStyle(const char* pBorderName,
                          const editeng::SvxBorderLine* pLine,
                          bool& bInsertSemicolon);

    sal_uInt16  GetFontSizeNumber( sal_uInt16 nHeight );
    const char* GetFontSizeCss( sal_uInt16 nHeight );
    sal_uInt16  ToPixel( sal_uInt16 nTwips );
    Size        MMToPixel( const Size& r100thMMSize );
    void        IncIndent( short nVal );

    const sal_Char* GetIndentStr()
    {
        return sIndent;
    }

public:
                        ScHTMLExport( SvStream&, const OUString&, ScDocument*, const ScRange&,
                                      bool bAll, const OUString& aStreamPath, const OUString& rFilterOptions );
    virtual             ~ScHTMLExport();
    sal_uLong           Write();
    const OUString&     GetNonConvertibleChars() const
    {
        return aNonConvertibleChars;
    }
};

#endif

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