<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreGLES2HardwareBuffer.h"
#include "OgreRoot.h"
#include "OgreGLES2RenderSystem.h"
#include "OgreGLES2StateCacheManager.h"
#include "OgreDefaultHardwareBufferManager.h"

namespace Ogre {
    GLES2HardwareBuffer::GLES2HardwareBuffer(GLenum target, size_t sizeInBytes, uint32 usage, bool useShadowBuffer)
        : HardwareBuffer(usage, false, useShadowBuffer || HANDLE_CONTEXT_LOSS), mTarget(target)
    {
        mSizeInBytes = sizeInBytes;
        mRenderSystem = static_cast<GLES2RenderSystem*>(Root::getSingleton().getRenderSystem());
        createBuffer();

        if (useShadowBuffer || HANDLE_CONTEXT_LOSS)
        {
            mShadowBuffer.reset(new DefaultHardwareBuffer(mSizeInBytes));
        }
    }

    GLES2HardwareBuffer::~GLES2HardwareBuffer()
    {
        destroyBuffer();
    }

    void GLES2HardwareBuffer::createBuffer()
    {
        OGRE_CHECK_GL_ERROR(glGenBuffers(1, &mBufferId));

        if (!mBufferId)
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                        "Cannot create GL ES buffer",
                        "GLES2HardwareBuffer::createBuffer");
        }

        mRenderSystem->_getStateCacheManager()->bindGLBuffer(mTarget, mBufferId);
        OGRE_CHECK_GL_ERROR(glBufferData(mTarget, mSizeInBytes, NULL, getGLUsage(mUsage)));
    }

    void GLES2HardwareBuffer::destroyBuffer()
    {
        // Delete the cached value
        if(GLES2StateCacheManager* stateCacheManager = mRenderSystem->_getStateCacheManager())
            stateCacheManager->deleteGLBuffer(mTarget, mBufferId);
    }

    void* GLES2HardwareBuffer::lockImpl(size_t offset, size_t length,
                                        HardwareBuffer::LockOptions options)
    {
        GLenum access = 0;

        // Use glMapBuffer
        mRenderSystem->_getStateCacheManager()->bindGLBuffer(mTarget, mBufferId);

        bool writeOnly =
            options == HardwareBuffer::HBL_WRITE_ONLY ||
            ((mUsage & HBU_DETAIL_WRITE_ONLY) &&
             options != HardwareBuffer::HBL_READ_ONLY && options != HardwareBuffer::HBL_NORMAL);

        void* pBuffer = NULL;
        if(mRenderSystem->getCapabilities()->hasCapability(RSC_MAPBUFFER))
        {
            if (writeOnly)
            {
                access = GL_MAP_WRITE_BIT_EXT;
                if (options == HardwareBuffer::HBL_DISCARD ||
                    options == HardwareBuffer::HBL_NO_OVERWRITE)
                {
                    // Discard the buffer
                    access |= GL_MAP_INVALIDATE_RANGE_BIT_EXT;
                }
            }
            else if (options == HardwareBuffer::HBL_READ_ONLY)
                access = GL_MAP_READ_BIT_EXT;
            else
                access = GL_MAP_READ_BIT_EXT | GL_MAP_WRITE_BIT_EXT;

            OGRE_CHECK_GL_ERROR(pBuffer = glMapBufferRangeEXT(mTarget, offset, length, access));
        }

        if (!pBuffer)
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer: Out of memory",
                        "GLES2HardwareBuffer::lock");
        }

        // pBuffer is already offsetted in glMapBufferRange
        return static_cast<uint8*>(pBuffer);
    }

    void GLES2HardwareBuffer::unlockImpl()
    {
        mRenderSystem->_getStateCacheManager()->bindGLBuffer(mTarget, mBufferId);

        if(mRenderSystem->getCapabilities()->hasCapability(RSC_MAPBUFFER)) {
            GLboolean mapped;
            OGRE_CHECK_GL_ERROR(mapped = glUnmapBufferOES(mTarget));
            if(!mapped)
            {
                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer data corrupted, please reload",
                            "GLES2HardwareBuffer::unlock");
            }
        }
    }

    void GLES2HardwareBuffer::readData(size_t offset, size_t length, void* pDest)
    {
        if (mShadowBuffer)
        {
            mShadowBuffer->readData(offset, length, pDest);
            return;
        }

        if(!OGRE_NO_GLES3_SUPPORT || mRenderSystem->checkExtension("GL_EXT_map_buffer_range"))
        {
            // Map the buffer range then copy out of it into our destination buffer
            void* srcData;
            OGRE_CHECK_GL_ERROR(srcData = glMapBufferRangeEXT(mTarget, offset, length, GL_MAP_READ_BIT_EXT));
            memcpy(pDest, srcData, length);

            // Unmap the buffer since we are done.
            GLboolean mapped;
            OGRE_CHECK_GL_ERROR(mapped = glUnmapBufferOES(mTarget));
            if(!mapped)
            {
                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer data corrupted, please reload",
                            "GLES2HardwareBuffer::readData");
            }
        }
        else
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Read hardware buffer is not supported",
                        "GLES2HardwareBuffer::readData");
        }
    }

    void GLES2HardwareBuffer::writeData(size_t offset, size_t length, const void* pSource,
                                        bool discardWholeBuffer)
    {
        if (mShadowBuffer)
        {
            mShadowBuffer->writeData(offset, length, pSource, discardWholeBuffer);
        }

        writeDataImpl(offset, length, pSource, discardWholeBuffer);
    }

    void GLES2HardwareBuffer::writeDataImpl(size_t offset, size_t length, const void* pSource,
                                        bool discardWholeBuffer)
    {
        mRenderSystem->_getStateCacheManager()->bindGLBuffer(mTarget, mBufferId);

        if (offset == 0 && length == mSizeInBytes)
        {
            OGRE_CHECK_GL_ERROR(glBufferData(mTarget, mSizeInBytes, pSource, getGLUsage(mUsage)));
        }
        else
        {
            if(discardWholeBuffer)
            {
                OGRE_CHECK_GL_ERROR(glBufferData(mTarget, mSizeInBytes, NULL, getGLUsage(mUsage)));
            }

            OGRE_CHECK_GL_ERROR(glBufferSubData(mTarget, offset, length, pSource));
        }
    }

    void GLES2HardwareBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset, size_t dstOffset,
                                       size_t length, bool discardWholeBuffer)
    {
        if(!mRenderSystem->hasMinGLVersion(3, 0))
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "GLES3 needed");

        if (mShadowBuffer)
        {
            mShadowBuffer->copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer);
        }
        // Zero out this(destination) buffer
        OGRE_CHECK_GL_ERROR(glBindBuffer(mTarget, mBufferId));
        OGRE_CHECK_GL_ERROR(glBufferData(mTarget, length, 0, getGLUsage(mUsage)));
        OGRE_CHECK_GL_ERROR(glBindBuffer(mTarget, 0));

        // Do it the fast way.
        OGRE_CHECK_GL_ERROR(glBindBuffer(GL_COPY_READ_BUFFER,
                                         static_cast<GLES2HardwareBuffer&>(srcBuffer).getGLBufferId()));
        OGRE_CHECK_GL_ERROR(glBindBuffer(GL_COPY_WRITE_BUFFER, mBufferId));

        OGRE_CHECK_GL_ERROR(glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, dstOffset, length));

        OGRE_CHECK_GL_ERROR(glBindBuffer(GL_COPY_READ_BUFFER, 0));
        OGRE_CHECK_GL_ERROR(glBindBuffer(GL_COPY_WRITE_BUFFER, 0));
    }

    GLenum GLES2HardwareBuffer::getGLUsage(unsigned int usage)
    {
        return (usage == HBU_GPU_TO_CPU) ? GL_STATIC_READ
                                         : (usage == HBU_GPU_ONLY) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW;
    }

    void GLES2HardwareBuffer::_updateFromShadow(void)
    {
        if (mShadowBuffer && mShadowUpdated && !mSuppressHardwareUpdate)
        {
            HardwareBufferLockGuard shadowLock(mShadowBuffer.get(), mLockStart, mLockSize, HBL_READ_ONLY);
            writeDataImpl(mLockStart, mLockSize, shadowLock.pData, false);

            mShadowUpdated = false;
        }
    }

    void GLES2HardwareBuffer::setGLBufferBinding(GLint binding)
    {
        mBindingPoint = binding;

        // Attach the buffer to the UBO binding
        OGRE_CHECK_GL_ERROR(glBindBufferBase(mTarget, mBindingPoint, mBufferId));
    }

#if HANDLE_CONTEXT_LOSS
    void GLES2HardwareBuffer::notifyOnContextLost()
    {
        destroyBuffer();
    }

    void GLES2HardwareBuffer::notifyOnContextReset()
    {
        createBuffer();
        mShadowUpdated = true;
        _updateFromShadow();
    }
#endif
}
<commit_msg>GLES2: fix HardwareBuffer::readData<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreGLES2HardwareBuffer.h"
#include "OgreRoot.h"
#include "OgreGLES2RenderSystem.h"
#include "OgreGLES2StateCacheManager.h"
#include "OgreDefaultHardwareBufferManager.h"

namespace Ogre {
    GLES2HardwareBuffer::GLES2HardwareBuffer(GLenum target, size_t sizeInBytes, uint32 usage, bool useShadowBuffer)
        : HardwareBuffer(usage, false, useShadowBuffer || HANDLE_CONTEXT_LOSS), mTarget(target)
    {
        mSizeInBytes = sizeInBytes;
        mRenderSystem = static_cast<GLES2RenderSystem*>(Root::getSingleton().getRenderSystem());
        createBuffer();

        if (useShadowBuffer || HANDLE_CONTEXT_LOSS)
        {
            mShadowBuffer.reset(new DefaultHardwareBuffer(mSizeInBytes));
        }
    }

    GLES2HardwareBuffer::~GLES2HardwareBuffer()
    {
        destroyBuffer();
    }

    void GLES2HardwareBuffer::createBuffer()
    {
        OGRE_CHECK_GL_ERROR(glGenBuffers(1, &mBufferId));

        if (!mBufferId)
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                        "Cannot create GL ES buffer",
                        "GLES2HardwareBuffer::createBuffer");
        }

        mRenderSystem->_getStateCacheManager()->bindGLBuffer(mTarget, mBufferId);
        OGRE_CHECK_GL_ERROR(glBufferData(mTarget, mSizeInBytes, NULL, getGLUsage(mUsage)));
    }

    void GLES2HardwareBuffer::destroyBuffer()
    {
        // Delete the cached value
        if(GLES2StateCacheManager* stateCacheManager = mRenderSystem->_getStateCacheManager())
            stateCacheManager->deleteGLBuffer(mTarget, mBufferId);
    }

    void* GLES2HardwareBuffer::lockImpl(size_t offset, size_t length,
                                        HardwareBuffer::LockOptions options)
    {
        GLenum access = 0;

        // Use glMapBuffer
        mRenderSystem->_getStateCacheManager()->bindGLBuffer(mTarget, mBufferId);

        bool writeOnly =
            options == HardwareBuffer::HBL_WRITE_ONLY ||
            ((mUsage & HBU_DETAIL_WRITE_ONLY) &&
             options != HardwareBuffer::HBL_READ_ONLY && options != HardwareBuffer::HBL_NORMAL);

        void* pBuffer = NULL;
        if(mRenderSystem->getCapabilities()->hasCapability(RSC_MAPBUFFER))
        {
            if (writeOnly)
            {
                access = GL_MAP_WRITE_BIT_EXT;
                if (options == HardwareBuffer::HBL_DISCARD ||
                    options == HardwareBuffer::HBL_NO_OVERWRITE)
                {
                    // Discard the buffer
                    access |= GL_MAP_INVALIDATE_RANGE_BIT_EXT;
                }
            }
            else if (options == HardwareBuffer::HBL_READ_ONLY)
                access = GL_MAP_READ_BIT_EXT;
            else
                access = GL_MAP_READ_BIT_EXT | GL_MAP_WRITE_BIT_EXT;

            OGRE_CHECK_GL_ERROR(pBuffer = glMapBufferRangeEXT(mTarget, offset, length, access));
        }

        if (!pBuffer)
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer: Out of memory",
                        "GLES2HardwareBuffer::lock");
        }

        // pBuffer is already offsetted in glMapBufferRange
        return static_cast<uint8*>(pBuffer);
    }

    void GLES2HardwareBuffer::unlockImpl()
    {
        mRenderSystem->_getStateCacheManager()->bindGLBuffer(mTarget, mBufferId);

        if(mRenderSystem->getCapabilities()->hasCapability(RSC_MAPBUFFER)) {
            GLboolean mapped;
            OGRE_CHECK_GL_ERROR(mapped = glUnmapBufferOES(mTarget));
            if(!mapped)
            {
                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer data corrupted, please reload",
                            "GLES2HardwareBuffer::unlock");
            }
        }
    }

    void GLES2HardwareBuffer::readData(size_t offset, size_t length, void* pDest)
    {
        if (mShadowBuffer)
        {
            mShadowBuffer->readData(offset, length, pDest);
            return;
        }

        OgreAssert(mRenderSystem->getCapabilities()->hasCapability(RSC_MAPBUFFER),
                   "Read hardware buffer is not supported");

        mRenderSystem->_getStateCacheManager()->bindGLBuffer(mTarget, mBufferId);
        // Map the buffer range then copy out of it into our destination buffer
        void* srcData;
        OGRE_CHECK_GL_ERROR(srcData = glMapBufferRangeEXT(mTarget, offset, length, GL_MAP_READ_BIT_EXT));
        memcpy(pDest, srcData, length);

        // Unmap the buffer since we are done.
        GLboolean mapped;
        OGRE_CHECK_GL_ERROR(mapped = glUnmapBufferOES(mTarget));
        if(!mapped)
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer data corrupted, please reload",
                        "GLES2HardwareBuffer::readData");
        }
    }

    void GLES2HardwareBuffer::writeData(size_t offset, size_t length, const void* pSource,
                                        bool discardWholeBuffer)
    {
        if (mShadowBuffer)
        {
            mShadowBuffer->writeData(offset, length, pSource, discardWholeBuffer);
        }

        writeDataImpl(offset, length, pSource, discardWholeBuffer);
    }

    void GLES2HardwareBuffer::writeDataImpl(size_t offset, size_t length, const void* pSource,
                                        bool discardWholeBuffer)
    {
        mRenderSystem->_getStateCacheManager()->bindGLBuffer(mTarget, mBufferId);

        if (offset == 0 && length == mSizeInBytes)
        {
            OGRE_CHECK_GL_ERROR(glBufferData(mTarget, mSizeInBytes, pSource, getGLUsage(mUsage)));
        }
        else
        {
            if(discardWholeBuffer)
            {
                OGRE_CHECK_GL_ERROR(glBufferData(mTarget, mSizeInBytes, NULL, getGLUsage(mUsage)));
            }

            OGRE_CHECK_GL_ERROR(glBufferSubData(mTarget, offset, length, pSource));
        }
    }

    void GLES2HardwareBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset, size_t dstOffset,
                                       size_t length, bool discardWholeBuffer)
    {
        if(!mRenderSystem->hasMinGLVersion(3, 0))
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "GLES3 needed");

        if (mShadowBuffer)
        {
            mShadowBuffer->copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer);
        }
        // Zero out this(destination) buffer
        OGRE_CHECK_GL_ERROR(glBindBuffer(mTarget, mBufferId));
        OGRE_CHECK_GL_ERROR(glBufferData(mTarget, length, 0, getGLUsage(mUsage)));
        OGRE_CHECK_GL_ERROR(glBindBuffer(mTarget, 0));

        // Do it the fast way.
        OGRE_CHECK_GL_ERROR(glBindBuffer(GL_COPY_READ_BUFFER,
                                         static_cast<GLES2HardwareBuffer&>(srcBuffer).getGLBufferId()));
        OGRE_CHECK_GL_ERROR(glBindBuffer(GL_COPY_WRITE_BUFFER, mBufferId));

        OGRE_CHECK_GL_ERROR(glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, dstOffset, length));

        OGRE_CHECK_GL_ERROR(glBindBuffer(GL_COPY_READ_BUFFER, 0));
        OGRE_CHECK_GL_ERROR(glBindBuffer(GL_COPY_WRITE_BUFFER, 0));
    }

    GLenum GLES2HardwareBuffer::getGLUsage(unsigned int usage)
    {
        return (usage == HBU_GPU_TO_CPU) ? GL_STATIC_READ
                                         : (usage == HBU_GPU_ONLY) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW;
    }

    void GLES2HardwareBuffer::_updateFromShadow(void)
    {
        if (mShadowBuffer && mShadowUpdated && !mSuppressHardwareUpdate)
        {
            HardwareBufferLockGuard shadowLock(mShadowBuffer.get(), mLockStart, mLockSize, HBL_READ_ONLY);
            writeDataImpl(mLockStart, mLockSize, shadowLock.pData, false);

            mShadowUpdated = false;
        }
    }

    void GLES2HardwareBuffer::setGLBufferBinding(GLint binding)
    {
        mBindingPoint = binding;

        // Attach the buffer to the UBO binding
        OGRE_CHECK_GL_ERROR(glBindBufferBase(mTarget, mBindingPoint, mBufferId));
    }

#if HANDLE_CONTEXT_LOSS
    void GLES2HardwareBuffer::notifyOnContextLost()
    {
        destroyBuffer();
    }

    void GLES2HardwareBuffer::notifyOnContextReset()
    {
        createBuffer();
        mShadowUpdated = true;
        _updateFromShadow();
    }
#endif
}
<|endoftext|>


<commit_before>/*=============================================================================

  Library: CTK

  Copyright (c) 2010 German Cancer Research Center,
    Division of Medical and Biological Informatics

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

=============================================================================*/

#include <QCoreApplication>
#include <QDirIterator>
#include <QTest>
#include <QThread>

#include <ctkPluginContext.h>
#include <ctkPluginConstants.h>
#include <ctkPluginFrameworkFactory.h>
#include <ctkPluginFramework.h>
#include <ctkPluginException.h>
#include <ctkServiceReference.h>

#include "ctkTestSuiteInterface.h"

class TestRunner : public QThread
{
public:

  TestRunner(ctkPluginContext* context, long testPluginId, int argc, char** argv)
    : context(context), testPluginId(testPluginId), argc(argc), argv(argv)
  {

  }

  void run()
  {
    // start the main test plugin which registers the test suites (QObject classes)
    QSharedPointer<ctkPlugin> fwTest = context->getPlugin(testPluginId);
    fwTest->start();

    QList<ctkServiceReference> refs = context->getServiceReferences<ctkTestSuiteInterface>();

    int result = 0;
    foreach(ctkServiceReference ref, refs)
    {
      result = QTest::qExec(context->getService(ref), argc, argv);
    }

    QCoreApplication::exit(result);
  }

private:

  ctkPluginContext* context;
  long testPluginId;
  int argc;
  char** argv;
};

int main(int argc, char** argv)
{
  QCoreApplication app(argc, argv);

  app.setOrganizationName("CTK");
  app.setOrganizationDomain("commontk.org");
  app.setApplicationName("ctkPluginFrameworkCppTests");

  QString pluginDir;
#ifdef CMAKE_INTDIR
  pluginDir = qApp->applicationDirPath() + "/../test_plugins/" CMAKE_INTDIR "/";
#else
  pluginDir = qApp->applicationDirPath() + "/test_plugins/";
#endif

  QApplication::addLibraryPath(pluginDir);

  ctkProperties fwProps;
  fwProps.insert(ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN, ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
  fwProps.insert("pluginfw.testDir", pluginDir);
  ctkPluginFrameworkFactory fwFactory(fwProps);
  QSharedPointer<ctkPluginFramework> framework = fwFactory.getFramework();
  framework->start();

  ctkPluginContext* context = framework->getPluginContext();

  long fwTestPluginId = -1;
  QStringList libFilter;
  libFilter << "*.dll" << "*.so" << "*.dylib";
  QDirIterator dirIter(pluginDir, libFilter, QDir::Files);
  while(dirIter.hasNext())
  {
    dirIter.next();
    if (dirIter.fileName().contains("org_commontk_pluginfwtest"))
    {
      try
      {
        fwTestPluginId = context->installPlugin(QUrl::fromLocalFile(dirIter.filePath()).toString())->getPluginId();
        break;
      }
      catch (const ctkPluginException& e)
      {
        qCritical() << e.what();
      }
    }
  }

  if (fwTestPluginId < 0)
  {
    qCritical() << "Could not find the plugin framework test plugin: org.commontk.pluginfwtest";
  }

//  QList<ctkServiceReference> refs = context->getServiceReferences("ctkTestSuiteInterface");

//  int result = 0;
//  foreach(ctkServiceReference ref, refs)
//  {
//    result = QTest::qExec(context->getService(ref), argc, argv);
//  }

//  return result;

  TestRunner runner(context, fwTestPluginId, argc, argv);
  runner.start();

  return app.exec();
}
<commit_msg>Stop executing plugin framework tests on error.<commit_after>/*=============================================================================

  Library: CTK

  Copyright (c) 2010 German Cancer Research Center,
    Division of Medical and Biological Informatics

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

=============================================================================*/

#include <QCoreApplication>
#include <QDirIterator>
#include <QTest>
#include <QThread>

#include <ctkPluginContext.h>
#include <ctkPluginConstants.h>
#include <ctkPluginFrameworkFactory.h>
#include <ctkPluginFramework.h>
#include <ctkPluginException.h>
#include <ctkServiceReference.h>

#include "ctkTestSuiteInterface.h"

class TestRunner : public QThread
{
public:

  TestRunner(ctkPluginContext* context, long testPluginId, int argc, char** argv)
    : context(context), testPluginId(testPluginId), argc(argc), argv(argv)
  {

  }

  void run()
  {
    // start the main test plugin which registers the test suites (QObject classes)
    QSharedPointer<ctkPlugin> fwTest = context->getPlugin(testPluginId);
    fwTest->start();

    QList<ctkServiceReference> refs = context->getServiceReferences<ctkTestSuiteInterface>();

    int result = 0;
    foreach(ctkServiceReference ref, refs)
    {
      result += QTest::qExec(context->getService(ref), argc, argv);
      if (result > 0) break;
    }

    QCoreApplication::exit(result);
  }

private:

  ctkPluginContext* context;
  long testPluginId;
  int argc;
  char** argv;
};

int main(int argc, char** argv)
{
  QCoreApplication app(argc, argv);

  app.setOrganizationName("CTK");
  app.setOrganizationDomain("commontk.org");
  app.setApplicationName("ctkPluginFrameworkCppTests");

  QString pluginDir;
#ifdef CMAKE_INTDIR
  pluginDir = qApp->applicationDirPath() + "/../test_plugins/" CMAKE_INTDIR "/";
#else
  pluginDir = qApp->applicationDirPath() + "/test_plugins/";
#endif

  QApplication::addLibraryPath(pluginDir);

  ctkProperties fwProps;
  fwProps.insert(ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN, ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
  fwProps.insert("pluginfw.testDir", pluginDir);
  ctkPluginFrameworkFactory fwFactory(fwProps);
  QSharedPointer<ctkPluginFramework> framework = fwFactory.getFramework();
  framework->start();

  ctkPluginContext* context = framework->getPluginContext();

  long fwTestPluginId = -1;
  QStringList libFilter;
  libFilter << "*.dll" << "*.so" << "*.dylib";
  QDirIterator dirIter(pluginDir, libFilter, QDir::Files);
  while(dirIter.hasNext())
  {
    dirIter.next();
    if (dirIter.fileName().contains("org_commontk_pluginfwtest"))
    {
      try
      {
        fwTestPluginId = context->installPlugin(QUrl::fromLocalFile(dirIter.filePath()).toString())->getPluginId();
        break;
      }
      catch (const ctkPluginException& e)
      {
        qCritical() << e.what();
      }
    }
  }

  if (fwTestPluginId < 0)
  {
    qCritical() << "Could not find the plugin framework test plugin: org.commontk.pluginfwtest";
  }

//  QList<ctkServiceReference> refs = context->getServiceReferences("ctkTestSuiteInterface");

//  int result = 0;
//  foreach(ctkServiceReference ref, refs)
//  {
//    result = QTest::qExec(context->getService(ref), argc, argv);
//  }

//  return result;

  TestRunner runner(context, fwTestPluginId, argc, argv);
  runner.start();

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


<commit_before>/*************************************************************************
 *
 *  $RCSfile: newppdlg.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-15 17:21:55 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>
#include <unistd.h>

#ifndef _PSPRINT_PPDPARSER_HXX_
#include <psprint/ppdparser.hxx>
#endif
#ifndef _PSPRINT_HELPER_HXX_
#include <psprint/helper.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef __SGI_STL_LIST
#include <list>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif

#ifndef _PAD_HELPER_HXX_
#include <helper.hxx>
#endif
#ifndef _PAD_PADIALOG_HRC_
#include <padialog.hrc>
#endif
#ifndef _PAD_NEWPPDLG_HXX_
#include <newppdlg.hxx>
#endif
#ifndef _PAD_PADIALOG_HXX_
#include <padialog.hxx>
#endif
#ifndef _PAD_PROGRESS_HXX_
#include <progress.hxx>
#endif

#define PPDIMPORT_GROUP "PPDImport"

using namespace padmin;
using namespace psp;
using namespace osl;
using namespace rtl;

PPDImportDialog::PPDImportDialog( Window* pParent ) :
        ModalDialog( pParent, PaResId( RID_PPDIMPORT_DLG ) ),
        m_aOKBtn( this, PaResId( RID_PPDIMP_BTN_OK ) ),
        m_aCancelBtn( this, PaResId( RID_PPDIMP_BTN_CANCEL ) ),
        m_aSearchBtn( this, PaResId( RID_PPDIMP_BTN_SEARCH ) ),
        m_aPathBox( this, PaResId( RID_PPDIMP_LB_PATH ) ),
        m_aDriverTxt( this, PaResId( RID_PPDIMP_TXT_DRIVER ) ),
        m_aDriverLB( this, PaResId( RID_PPDIMP_LB_DRIVER ) ),
        m_aPathGroup( this, PaResId( RID_PPDIMP_GROUP_PATH ) ),
        m_aDriverGroup( this, PaResId( RID_PPDIMP_GROUP_DRIVER ) ),
        m_aPathTxt( this, PaResId( RID_PPDIMP_TXT_PATH ) ),
        m_aLoadingPPD( PaResId( RID_PPDIMP_STR_LOADINGPPD ) )
{
    FreeResource();

    String aText( m_aDriverTxt.GetText() );
    aText.SearchAndReplaceAscii( "%s", Button::GetStandardText( BUTTON_OK ) );
    aText.EraseAllChars( '~' );
    m_aDriverTxt.SetText( aText );

    Config& rConfig = getPadminRC();
    rConfig.SetGroup( PPDIMPORT_GROUP );
    m_aPathBox.SetText( String( rConfig.ReadKey( "LastDir" ), RTL_TEXTENCODING_UTF8 ) );
    for( int i = 0; i < 11; i++ )
    {
        ByteString aEntry( rConfig.ReadKey( ByteString::CreateFromInt32( i ) ) );
        if( aEntry.Len() )
            m_aPathBox.InsertEntry( String( aEntry, RTL_TEXTENCODING_UTF8 ) );
    }

    m_aOKBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aCancelBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aSearchBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aPathBox.SetSelectHdl( LINK( this, PPDImportDialog, SelectHdl ) );
    m_aPathBox.SetModifyHdl( LINK( this, PPDImportDialog, ModifyHdl ) );

    if( m_aPathBox.GetText().Len() )
        Import();
}

PPDImportDialog::~PPDImportDialog()
{
    while( m_aDriverLB.GetEntryCount() )
    {
        delete (String*)m_aDriverLB.GetEntryData( 0 );
        m_aDriverLB.RemoveEntry( 0 );
    }
}

void PPDImportDialog::Import()
{
    String aImportPath( m_aPathBox.GetText() );

    Config& rConfig = getPadminRC();
    rConfig.SetGroup( PPDIMPORT_GROUP );
    rConfig.WriteKey( "LastDir", ByteString( aImportPath, RTL_TEXTENCODING_UTF8 ) );

    int nEntries = m_aPathBox.GetEntryCount();
    while( nEntries-- )
        if( aImportPath == m_aPathBox.GetEntry( nEntries ) )
            break;
    if( nEntries < 0 )
    {
        int nNextEntry = rConfig.ReadKey( "NextEntry" ).ToInt32();
        rConfig.WriteKey( ByteString::CreateFromInt32( nNextEntry ), ByteString( aImportPath, RTL_TEXTENCODING_UTF8 ) );
        nNextEntry = nNextEntry < 10 ? nNextEntry+1 : 0;
        rConfig.WriteKey( "NextEntry", ByteString::CreateFromInt32( nNextEntry ) );
        m_aPathBox.InsertEntry( aImportPath );
    }
    while( m_aDriverLB.GetEntryCount() )
    {
        delete (String*)m_aDriverLB.GetEntryData( 0 );
        m_aDriverLB.RemoveEntry( 0 );
    }

    ProgressDialog aProgress( Application::GetFocusWindow() );
    aProgress.startOperation( m_aLoadingPPD );

    ::std::list< String > aFiles;
    FindFiles( aImportPath, aFiles, String::CreateFromAscii( "PS;PPD" ) );

    int i = 0;
    aProgress.setRange( 0, aFiles.size() );
    while( aFiles.size() )
    {
        aProgress.setValue( ++i );
        aProgress.setFilename( aFiles.front() );
        INetURLObject aPath( aImportPath, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
        aPath.Append( aFiles.front() );
        String aPrinterName = PPDParser::getPPDPrinterName( aPath.PathToFileName() );
        aFiles.pop_front();

        if( ! aPrinterName.Len() )
        {
#if OSL_DEBUG_LEVEL > 1
            fprintf( stderr, "Warning: File %s has empty printer name.\n",
                     ByteString( ByteString( aPath.PathToFileName(), osl_getThreadTextEncoding() ).GetBuffer() ) );
#endif
            continue;
        }

        USHORT nPos = m_aDriverLB.InsertEntry( aPrinterName );
        m_aDriverLB.SetEntryData( nPos, new String( aPath.PathToFileName() ) );
    }
}

IMPL_LINK( PPDImportDialog, ClickBtnHdl, PushButton*, pButton )
{
    rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();

    if( pButton == &m_aCancelBtn )
    {
        EndDialog( 0 );
    }
    else if( pButton == &m_aOKBtn )
    {
        // copy the files
        ::std::list< String > aToDirs;
        String aPathList( ::psp::getPrinterPath() );
        int nTokens = aPathList.GetTokenCount( ':' );
        for( int n = 0; n < nTokens; n++ )
        {
            String aPath = aPathList.GetToken( n, ':' );
            aPath.AppendAscii( "/"PSPRINT_PPDDIR );
            aToDirs.push_back( aPath );
        }
        ::std::list< String >::iterator writeDir = aToDirs.begin();

        for( int i = 0; i < m_aDriverLB.GetSelectEntryCount(); i++ )
        {
            INetURLObject aFile( *(String*)m_aDriverLB.GetEntryData(
                m_aDriverLB.GetSelectEntryPos( i )
                ), INET_PROT_FILE, INetURLObject::ENCODE_ALL );
            OUString aFromUni( aFile.GetMainURL(INetURLObject::DECODE_TO_IURI) );

            do
            {
                INetURLObject aToFile( *writeDir, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
                aToFile.Append( aFile.GetName() );
                aToFile.setExtension( String::CreateFromAscii( "PPD" ) );
                OUString aToUni( aToFile.GetMainURL(INetURLObject::DECODE_TO_IURI) );
                if( ! File::copy( aFromUni, aToUni ) )
                    break;
                ++writeDir;
            } while( writeDir != aToDirs.end() );
        }
        EndDialog( 1 );
    }
    else if( pButton == &m_aSearchBtn )
    {
        String aPath( m_aPathBox.GetText() );
        if( chooseDirectory( this, aPath ) )
        {
            m_aPathBox.SetText( aPath );
            Import();
        }
    }
    return 0;
}

IMPL_LINK( PPDImportDialog, SelectHdl, ComboBox*, pListBox )
{
    if( pListBox == &m_aPathBox )
    {
        Import();
    }
    return 0;
}

IMPL_LINK( PPDImportDialog, ModifyHdl, ComboBox*, pListBox )
{
    if( pListBox == &m_aPathBox )
    {
        ByteString aDir( m_aPathBox.GetText(), osl_getThreadTextEncoding() );
        if( ! access( aDir.GetBuffer(), F_OK ) )
            Import();
    }
    return 0;
}
<commit_msg>INTEGRATION: CWS vcl09 (1.7.4); FILE MERGED 2003/04/29 15:29:36 pl 1.7.4.1: #108994# read locale from configuration<commit_after>/*************************************************************************
 *
 *  $RCSfile: newppdlg.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: vg $ $Date: 2003-05-28 12:36:18 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>
#include <unistd.h>

#ifndef _PSPRINT_PPDPARSER_HXX_
#include <psprint/ppdparser.hxx>
#endif
#ifndef _PSPRINT_HELPER_HXX_
#include <psprint/helper.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef __SGI_STL_LIST
#include <list>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif

#ifndef _PAD_HELPER_HXX_
#include <helper.hxx>
#endif
#ifndef _PAD_PADIALOG_HRC_
#include <padialog.hrc>
#endif
#ifndef _PAD_NEWPPDLG_HXX_
#include <newppdlg.hxx>
#endif
#ifndef _PAD_PADIALOG_HXX_
#include <padialog.hxx>
#endif
#ifndef _PAD_PROGRESS_HXX_
#include <progress.hxx>
#endif

#define PPDIMPORT_GROUP "PPDImport"

using namespace padmin;
using namespace psp;
using namespace osl;
using namespace rtl;

PPDImportDialog::PPDImportDialog( Window* pParent ) :
        ModalDialog( pParent, PaResId( RID_PPDIMPORT_DLG ) ),
        m_aOKBtn( this, PaResId( RID_PPDIMP_BTN_OK ) ),
        m_aCancelBtn( this, PaResId( RID_PPDIMP_BTN_CANCEL ) ),
        m_aSearchBtn( this, PaResId( RID_PPDIMP_BTN_SEARCH ) ),
        m_aPathBox( this, PaResId( RID_PPDIMP_LB_PATH ) ),
        m_aDriverTxt( this, PaResId( RID_PPDIMP_TXT_DRIVER ) ),
        m_aDriverLB( this, PaResId( RID_PPDIMP_LB_DRIVER ) ),
        m_aPathGroup( this, PaResId( RID_PPDIMP_GROUP_PATH ) ),
        m_aDriverGroup( this, PaResId( RID_PPDIMP_GROUP_DRIVER ) ),
        m_aPathTxt( this, PaResId( RID_PPDIMP_TXT_PATH ) ),
        m_aLoadingPPD( PaResId( RID_PPDIMP_STR_LOADINGPPD ) )
{
    FreeResource();

    String aText( m_aDriverTxt.GetText() );
    aText.SearchAndReplaceAscii( "%s", Button::GetStandardText( BUTTON_OK ) );
    aText.EraseAllChars( '~' );
    m_aDriverTxt.SetText( aText );

    Config& rConfig = getPadminRC();
    rConfig.SetGroup( PPDIMPORT_GROUP );
    m_aPathBox.SetText( String( rConfig.ReadKey( "LastDir" ), RTL_TEXTENCODING_UTF8 ) );
    for( int i = 0; i < 11; i++ )
    {
        ByteString aEntry( rConfig.ReadKey( ByteString::CreateFromInt32( i ) ) );
        if( aEntry.Len() )
            m_aPathBox.InsertEntry( String( aEntry, RTL_TEXTENCODING_UTF8 ) );
    }

    m_aOKBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aCancelBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aSearchBtn.SetClickHdl( LINK( this, PPDImportDialog, ClickBtnHdl ) );
    m_aPathBox.SetSelectHdl( LINK( this, PPDImportDialog, SelectHdl ) );
    m_aPathBox.SetModifyHdl( LINK( this, PPDImportDialog, ModifyHdl ) );

    if( m_aPathBox.GetText().Len() )
        Import();
}

PPDImportDialog::~PPDImportDialog()
{
    while( m_aDriverLB.GetEntryCount() )
    {
        delete (String*)m_aDriverLB.GetEntryData( 0 );
        m_aDriverLB.RemoveEntry( 0 );
    }
}

void PPDImportDialog::Import()
{
    String aImportPath( m_aPathBox.GetText() );

    Config& rConfig = getPadminRC();
    rConfig.SetGroup( PPDIMPORT_GROUP );
    rConfig.WriteKey( "LastDir", ByteString( aImportPath, RTL_TEXTENCODING_UTF8 ) );

    int nEntries = m_aPathBox.GetEntryCount();
    while( nEntries-- )
        if( aImportPath == m_aPathBox.GetEntry( nEntries ) )
            break;
    if( nEntries < 0 )
    {
        int nNextEntry = rConfig.ReadKey( "NextEntry" ).ToInt32();
        rConfig.WriteKey( ByteString::CreateFromInt32( nNextEntry ), ByteString( aImportPath, RTL_TEXTENCODING_UTF8 ) );
        nNextEntry = nNextEntry < 10 ? nNextEntry+1 : 0;
        rConfig.WriteKey( "NextEntry", ByteString::CreateFromInt32( nNextEntry ) );
        m_aPathBox.InsertEntry( aImportPath );
    }
    while( m_aDriverLB.GetEntryCount() )
    {
        delete (String*)m_aDriverLB.GetEntryData( 0 );
        m_aDriverLB.RemoveEntry( 0 );
    }

    ProgressDialog aProgress( Application::GetFocusWindow() );
    aProgress.startOperation( m_aLoadingPPD );

    ::std::list< String > aFiles;
    FindFiles( aImportPath, aFiles, String::CreateFromAscii( "PS;PPD" ) );

    int i = 0;
    aProgress.setRange( 0, aFiles.size() );
    while( aFiles.size() )
    {
        aProgress.setValue( ++i );
        aProgress.setFilename( aFiles.front() );
        INetURLObject aPath( aImportPath, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
        aPath.Append( aFiles.front() );
        String aPrinterName = PPDParser::getPPDPrinterName( aPath.PathToFileName() );
        aFiles.pop_front();

        if( ! aPrinterName.Len() )
        {
#if OSL_DEBUG_LEVEL > 1
            fprintf( stderr, "Warning: File %s has empty printer name.\n",
                     ByteString( aPath.PathToFileName(), osl_getThreadTextEncoding() ).GetBuffer() );
#endif
            continue;
        }

        USHORT nPos = m_aDriverLB.InsertEntry( aPrinterName );
        m_aDriverLB.SetEntryData( nPos, new String( aPath.PathToFileName() ) );
    }
}

IMPL_LINK( PPDImportDialog, ClickBtnHdl, PushButton*, pButton )
{
    rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();

    if( pButton == &m_aCancelBtn )
    {
        EndDialog( 0 );
    }
    else if( pButton == &m_aOKBtn )
    {
        // copy the files
        ::std::list< String > aToDirs;
        String aPathList( ::psp::getPrinterPath() );
        int nTokens = aPathList.GetTokenCount( ':' );
        for( int n = 0; n < nTokens; n++ )
        {
            String aPath = aPathList.GetToken( n, ':' );
            aPath.AppendAscii( "/"PSPRINT_PPDDIR );
            aToDirs.push_back( aPath );
        }
        ::std::list< String >::iterator writeDir = aToDirs.begin();

        for( int i = 0; i < m_aDriverLB.GetSelectEntryCount(); i++ )
        {
            INetURLObject aFile( *(String*)m_aDriverLB.GetEntryData(
                m_aDriverLB.GetSelectEntryPos( i )
                ), INET_PROT_FILE, INetURLObject::ENCODE_ALL );
            OUString aFromUni( aFile.GetMainURL(INetURLObject::DECODE_TO_IURI) );

            do
            {
                INetURLObject aToFile( *writeDir, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
                aToFile.Append( aFile.GetName() );
                aToFile.setExtension( String::CreateFromAscii( "PPD" ) );
                OUString aToUni( aToFile.GetMainURL(INetURLObject::DECODE_TO_IURI) );
                if( ! File::copy( aFromUni, aToUni ) )
                    break;
                ++writeDir;
            } while( writeDir != aToDirs.end() );
        }
        EndDialog( 1 );
    }
    else if( pButton == &m_aSearchBtn )
    {
        String aPath( m_aPathBox.GetText() );
        if( chooseDirectory( this, aPath ) )
        {
            m_aPathBox.SetText( aPath );
            Import();
        }
    }
    return 0;
}

IMPL_LINK( PPDImportDialog, SelectHdl, ComboBox*, pListBox )
{
    if( pListBox == &m_aPathBox )
    {
        Import();
    }
    return 0;
}

IMPL_LINK( PPDImportDialog, ModifyHdl, ComboBox*, pListBox )
{
    if( pListBox == &m_aPathBox )
    {
        ByteString aDir( m_aPathBox.GetText(), osl_getThreadTextEncoding() );
        if( ! access( aDir.GetBuffer(), F_OK ) )
            Import();
    }
    return 0;
}
<|endoftext|>


<commit_before>/*
 * MapLocationEntry.cpp
 *
 *  Created on: 24/06/2010
 *      Author: victor
 *  Updated on: Sun Oct 16 16:30:54 PDT 2011 by lordkator - resolve displayName on add in setObject() with cleaner names for maps
 *
 */

#include "MapLocationEntry.h"
#include "MapLocationType.h"
#include "server/zone/managers/planet/PlanetManager.h"
#include "server/zone/objects/scene/SceneObject.h"
#include "server/zone/objects/area/ActiveArea.h"
#include "server/zone/objects/region/CityRegion.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/tangible/terminal/mission/MissionTerminal.h"

uint64 MapLocationEntry::getObjectID() const {
	return object->getObjectID();
}

int MapLocationEntry::compareTo(const MapLocationEntry& entry) const {
	if (getObjectID() < entry.getObjectID())
		return 1;
	else if (getObjectID() > entry.getObjectID())
		return -1;
	else
		return 0;
}

MapLocationEntry& MapLocationEntry::operator=(const MapLocationEntry& entry) {
	if (this == &entry)
		return *this;

	object = entry.object;
	active = entry.active;

	return *this;
}

void MapLocationEntry::setObject(SceneObject *obj) {
	displayName = "";
	object = obj;

	if(object == NULL)
		return;

	PlanetMapCategory* category = object->getPlanetMapCategory();

	if (category == NULL)
		return;

	ManagedReference<Zone*> zone = object->getZone();

	if(zone == NULL)
		return;

	// Default is the result of getDisplayedName()
	String newName = object->getDisplayedName();

	if(object->isCreatureObject()) { // Try FirstName + FastName if it's a creature
		if(!object->isVendor()) {

			CreatureObject* creature = cast<CreatureObject*>(object.get());

			String fName = creature->getFirstName();
			String lName = creature->getLastName();

			if(fName.length() > 0) {
				newName = fName;

				if(lName.length() > 0)
					newName += " " + lName;
			}
		}
	} else if(category->getIndex() == MapLocationType::SHUTTLEPORT) { // Shuttleports take on the name of nearest travel point
		ManagedReference<PlanetManager*> planetManager = zone->getPlanetManager();
		PlanetTravelPoint* ptp = planetManager->getNearestPlanetTravelPoint(object, 64.f);

		if(ptp != NULL) {
			newName = ptp->getPointName();
		}
	} else if(category->getIndex() == MapLocationType::TERMINAL && (object->getPlanetMapSubCategory() != NULL)) {
		newName = object->getPlanetMapSubCategory()->getName();

		if (newName == "terminal_bank") {
			newName = "@map_loc_cat_n:terminal_bank";
		} else if (newName == "terminal_bazaar") {
			newName = "@map_loc_cat_n:terminal_bazaar";
		} else if (newName == "terminal_mission") {
			if (object->isMissionTerminal()) {
				ManagedReference<MissionTerminal*> terminal = dynamic_cast<MissionTerminal*>(object.get());

				if (terminal != NULL)
					newName = terminal->getTerminalName();
			}
		} else {
			newName = "@map_loc_cat_n:terminal";
		}

	} else { // Everything else is just named by the city it's in
		ManagedReference<PlanetManager*> planetManager = zone->getPlanetManager();

		ManagedReference<CityRegion *> region = planetManager->getRegionAt(object->getWorldPositionX(), object->getWorldPositionY());

		if(region != NULL) {
			newName = region->getRegionName();
		}
	}

	displayName = newName;
}

bool MapLocationEntry::insertToMessage(BaseMessage* message, unsigned int faction) const {
	if (object == NULL)
		return false;

	PlanetMapCategory* category = object->getPlanetMapCategory();

	if (category == NULL)
		return false;

	if (category->isFactionVisibleOnly()) {
		unsigned int entryFaction = category->getFaction().hashCode();

		if (entryFaction != faction)
			return false;
	}

	message->insertLong(object->getObjectID());

	message->insertUnicode(displayName);

	message->insertFloat(object->getWorldPositionX());
	message->insertFloat(object->getWorldPositionY());

	message->insertByte(category->getIndex());
	message->insertByte((object->getPlanetMapSubCategory() != NULL) ? object->getPlanetMapSubCategory()->getIndex() : 0);
	message->insertByte(active);

	return true;
}
<commit_msg>[Fixed] Vendor names on overhead and planetary map no longer include the "Vendor: " prefix - mantis 5091 [Fixed] droid/terminal vendors in a player city now display their own name on overhead/planetary maps rather than the name of the city<commit_after>/*
 * MapLocationEntry.cpp
 *
 *  Created on: 24/06/2010
 *      Author: victor
 *  Updated on: Sun Oct 16 16:30:54 PDT 2011 by lordkator - resolve displayName on add in setObject() with cleaner names for maps
 *
 */

#include "MapLocationEntry.h"
#include "MapLocationType.h"
#include "server/zone/managers/planet/PlanetManager.h"
#include "server/zone/objects/scene/SceneObject.h"
#include "server/zone/objects/area/ActiveArea.h"
#include "server/zone/objects/region/CityRegion.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/tangible/terminal/mission/MissionTerminal.h"

uint64 MapLocationEntry::getObjectID() const {
	return object->getObjectID();
}

int MapLocationEntry::compareTo(const MapLocationEntry& entry) const {
	if (getObjectID() < entry.getObjectID())
		return 1;
	else if (getObjectID() > entry.getObjectID())
		return -1;
	else
		return 0;
}

MapLocationEntry& MapLocationEntry::operator=(const MapLocationEntry& entry) {
	if (this == &entry)
		return *this;

	object = entry.object;
	active = entry.active;

	return *this;
}

void MapLocationEntry::setObject(SceneObject *obj) {
	displayName = "";
	object = obj;

	if(object == NULL)
		return;

	PlanetMapCategory* category = object->getPlanetMapCategory();

	if (category == NULL)
		return;

	ManagedReference<Zone*> zone = object->getZone();

	if(zone == NULL)
		return;

	// Default is the result of getDisplayedName()
	String newName = object->getDisplayedName();

	if (object->isVendor()) {
		newName = newName.subString(8); // Removes the "Vendor: " prefix
	} else if (object->isCreatureObject()) { // Try FirstName + LastName if it's a creature
		CreatureObject* creature = cast<CreatureObject*>(object.get());

		String fName = creature->getFirstName();
		String lName = creature->getLastName();

		if(fName.length() > 0) {
			newName = fName;

			if(lName.length() > 0)
				newName += " " + lName;
		}
	} else if(category->getIndex() == MapLocationType::SHUTTLEPORT) { // Shuttleports take on the name of nearest travel point
		ManagedReference<PlanetManager*> planetManager = zone->getPlanetManager();
		PlanetTravelPoint* ptp = planetManager->getNearestPlanetTravelPoint(object, 64.f);

		if(ptp != NULL) {
			newName = ptp->getPointName();
		}
	} else if(category->getIndex() == MapLocationType::TERMINAL && (object->getPlanetMapSubCategory() != NULL)) {
		newName = object->getPlanetMapSubCategory()->getName();

		if (newName == "terminal_bank") {
			newName = "@map_loc_cat_n:terminal_bank";
		} else if (newName == "terminal_bazaar") {
			newName = "@map_loc_cat_n:terminal_bazaar";
		} else if (newName == "terminal_mission") {
			if (object->isMissionTerminal()) {
				ManagedReference<MissionTerminal*> terminal = dynamic_cast<MissionTerminal*>(object.get());

				if (terminal != NULL)
					newName = terminal->getTerminalName();
			}
		} else {
			newName = "@map_loc_cat_n:terminal";
		}

	} else { // Everything else is just named by the city it's in
		ManagedReference<PlanetManager*> planetManager = zone->getPlanetManager();

		ManagedReference<CityRegion *> region = planetManager->getRegionAt(object->getWorldPositionX(), object->getWorldPositionY());

		if(region != NULL) {
			newName = region->getRegionName();
		}
	}

	displayName = newName;
}

bool MapLocationEntry::insertToMessage(BaseMessage* message, unsigned int faction) const {
	if (object == NULL)
		return false;

	PlanetMapCategory* category = object->getPlanetMapCategory();

	if (category == NULL)
		return false;

	if (category->isFactionVisibleOnly()) {
		unsigned int entryFaction = category->getFaction().hashCode();

		if (entryFaction != faction)
			return false;
	}

	message->insertLong(object->getObjectID());

	message->insertUnicode(displayName);

	message->insertFloat(object->getWorldPositionX());
	message->insertFloat(object->getWorldPositionY());

	message->insertByte(category->getIndex());
	message->insertByte((object->getPlanetMapSubCategory() != NULL) ? object->getPlanetMapSubCategory()->getIndex() : 0);
	message->insertByte(active);

	return true;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: padialog.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2005-08-05 12:55:32 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _PAD_PADIALOG_HXX_
#define _PAD_PADIALOG_HXX_
#ifndef __SGI_STL_LIST
#include <list>
#endif
#ifndef _RTL_USTRING
#include <rtl/ustring>
#endif
#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
#ifndef _CONFIG_HXX
#include <tools/config.hxx>
#endif
#ifndef _SV_LSTBOX_HXX
#include <vcl/lstbox.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_GROUP_HXX
#include <vcl/group.hxx>
#endif
#ifndef _SV_EDIT_HXX
#include <vcl/edit.hxx>
#endif
#ifndef _PAD_HELPER_HXX_
#include <helper.hxx>
#endif

// forward declaration
namespace psp { class PrinterInfoManager; }
class Printer;

namespace padmin {

    class PADialog : public ModalDialog
    {
    private:
        DelListBox                          m_aDevicesLB;
        PushButton                          m_aConfPB;
        PushButton                          m_aRenamePB;
        PushButton                          m_aStdPB;
        PushButton                          m_aRemPB;
        PushButton                          m_aTestPagePB;
        FixedLine                           m_aPrintersFL;
        FixedText                           m_aDriverTxt;
        FixedText                           m_aDriver;
        FixedText                           m_aLocationTxt;
        FixedText                           m_aLocation;
        FixedText                           m_aCommandTxt;
        FixedText                           m_aCommand;
        FixedText                           m_aCommentTxt;
        FixedText                           m_aComment;

        FixedLine                           m_aSepButtonFL;
        PushButton                          m_aAddPB;
        PushButton                          m_aFontsPB;
        CancelButton                        m_aCancelButton;

        String                              m_aDefPrt;
        String                              m_aRenameStr;

        Printer*                            m_pPrinter;
        ::psp::PrinterInfoManager&          m_rPIManager;
        ::std::list< ::rtl::OUString >      m_aPrinters;

        Image                               m_aPrinterImg;
        Image                               m_aFaxImg;
        Image                               m_aPdfImg;

        DECL_LINK( ClickBtnHdl, PushButton* );
        DECL_LINK( DoubleClickHdl, ListBox* );
        DECL_LINK( SelectHdl, ListBox* );
        DECL_LINK( EndPrintHdl, void* );
        DECL_LINK( DelPressedHdl, ListBox* );

        PADialog( Window*,  BOOL );
        void Init();

        void UpdateDefPrt();
        void UpdateText();
        void UpdateDevice();
        void AddDevice();
        void RemDevice();
        void ConfigureDevice();
        void RenameDevice();
        void PrintTestPage();

        virtual long Notify( NotifyEvent& rEv );

        String getSelectedDevice();
    public:
        ~PADialog();

        static PADialog* Create( Window*,  BOOL );
    };

} // namespace

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.7.6); FILE MERGED 2005/09/05 13:16:12 rt 1.7.6.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: padialog.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 16:26:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/

#ifndef _PAD_PADIALOG_HXX_
#define _PAD_PADIALOG_HXX_
#ifndef __SGI_STL_LIST
#include <list>
#endif
#ifndef _RTL_USTRING
#include <rtl/ustring>
#endif
#ifndef _SV_DIALOG_HXX
#include <vcl/dialog.hxx>
#endif
#ifndef _CONFIG_HXX
#include <tools/config.hxx>
#endif
#ifndef _SV_LSTBOX_HXX
#include <vcl/lstbox.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_GROUP_HXX
#include <vcl/group.hxx>
#endif
#ifndef _SV_EDIT_HXX
#include <vcl/edit.hxx>
#endif
#ifndef _PAD_HELPER_HXX_
#include <helper.hxx>
#endif

// forward declaration
namespace psp { class PrinterInfoManager; }
class Printer;

namespace padmin {

    class PADialog : public ModalDialog
    {
    private:
        DelListBox                          m_aDevicesLB;
        PushButton                          m_aConfPB;
        PushButton                          m_aRenamePB;
        PushButton                          m_aStdPB;
        PushButton                          m_aRemPB;
        PushButton                          m_aTestPagePB;
        FixedLine                           m_aPrintersFL;
        FixedText                           m_aDriverTxt;
        FixedText                           m_aDriver;
        FixedText                           m_aLocationTxt;
        FixedText                           m_aLocation;
        FixedText                           m_aCommandTxt;
        FixedText                           m_aCommand;
        FixedText                           m_aCommentTxt;
        FixedText                           m_aComment;

        FixedLine                           m_aSepButtonFL;
        PushButton                          m_aAddPB;
        PushButton                          m_aFontsPB;
        CancelButton                        m_aCancelButton;

        String                              m_aDefPrt;
        String                              m_aRenameStr;

        Printer*                            m_pPrinter;
        ::psp::PrinterInfoManager&          m_rPIManager;
        ::std::list< ::rtl::OUString >      m_aPrinters;

        Image                               m_aPrinterImg;
        Image                               m_aFaxImg;
        Image                               m_aPdfImg;

        DECL_LINK( ClickBtnHdl, PushButton* );
        DECL_LINK( DoubleClickHdl, ListBox* );
        DECL_LINK( SelectHdl, ListBox* );
        DECL_LINK( EndPrintHdl, void* );
        DECL_LINK( DelPressedHdl, ListBox* );

        PADialog( Window*,  BOOL );
        void Init();

        void UpdateDefPrt();
        void UpdateText();
        void UpdateDevice();
        void AddDevice();
        void RemDevice();
        void ConfigureDevice();
        void RenameDevice();
        void PrintTestPage();

        virtual long Notify( NotifyEvent& rEv );

        String getSelectedDevice();
    public:
        ~PADialog();

        static PADialog* Create( Window*,  BOOL );
    };

} // namespace

#endif
<|endoftext|>


<commit_before>#include "repo_log.h"

#if BOOST_VERSION > 105700
#include <boost/core/null_deleter.hpp>
#else
#include <boost/utility/empty_deleter.hpp>
#endif

#include <boost/iostreams/stream.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/utility/setup.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <ctime>

using namespace repo::lib;
using text_sink = boost::log::sinks::synchronous_sink < boost::log::sinks::text_ostream_backend >;

BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime)
BOOST_LOG_ATTRIBUTE_KEYWORD(threadid, "ThreadID", boost::log::attributes::current_thread_id::value_type)

auto logFormatting = boost::log::expressions::stream
<< "[" << boost::log::expressions::format_date_time(timestamp, "%Y-%m-%d %H:%M:%S") << "]"
<< "(" << threadid << ") <" << boost::log::trivial::severity
<< ">"
<< ": " << boost::log::expressions::smessage;

RepoLog::RepoLog()
{
	auto sink = boost::log::add_console_log(std::cout);
	sink->set_formatter
	(
		logFormatting
	);
	sink->imbue(sink->getloc());
}
RepoLog::~RepoLog()
{
}

void RepoLog::log(
	const RepoLogLevel &severity,
	const std::string  &msg)
{
	switch (severity)
	{
	case RepoLogLevel::TRACE:
		repoTrace << msg;
		break;
	case RepoLogLevel::DEBUG:
		repoDebug << msg;
		break;
	case RepoLogLevel::INFO:
		repoInfo << msg;
		break;
	case RepoLogLevel::WARNING:
		repoWarning << msg;
		break;
	case RepoLogLevel::ERR:
		repoError << msg;
		break;
	case RepoLogLevel::FATAL:
		repoFatal << msg;
	}
}

static std::string getTimeAsString()
{
	time_t rawtime;
	struct tm * timeinfo;
	char buffer[80];

	time(&rawtime);
	timeinfo = localtime(&rawtime);

	strftime(buffer, 80, "%d-%m-%Y_%Hh%Mm%S", timeinfo);
	return std::string(buffer);
}

void RepoLog::logToFile(const std::string &filePath)
{
	boost::filesystem::path logPath(filePath);
	std::string fileName;
	// a directory is given
	std::string name = getTimeAsString() + "_%N.log";
	fileName = (logPath / name).string();

	boost::log::add_file_log
	(
		boost::log::keywords::file_name = fileName,
		boost::log::keywords::rotation_size = 10 * 1024 * 1024,
		boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0),
		boost::log::keywords::auto_flush = true,
		boost::log::keywords::format = (
			logFormatting)
	);
	boost::log::add_common_attributes();

	repoInfo << "Log file registered: " << filePath;
}

void RepoLog::setLoggingLevel(const RepoLogLevel &level)
{
	boost::log::trivial::severity_level loggingLevel;
	switch (level)
	{
	case repo::lib::RepoLog::RepoLogLevel::TRACE:
		loggingLevel = boost::log::trivial::trace;
		break;
	case repo::lib::RepoLog::RepoLogLevel::DEBUG:
		loggingLevel = boost::log::trivial::debug;
		break;
	case repo::lib::RepoLog::RepoLogLevel::INFO:
		loggingLevel = boost::log::trivial::info;
		break;
	case repo::lib::RepoLog::RepoLogLevel::WARNING:
		loggingLevel = boost::log::trivial::warning;
		break;
	case repo::lib::RepoLog::RepoLogLevel::ERR:
		loggingLevel = boost::log::trivial::error;
		break;
	case repo::lib::RepoLog::RepoLogLevel::FATAL:
		loggingLevel = boost::log::trivial::fatal;
		break;
	default:
		repoError << "Unknown log level: " << (int)level;
		return;
	}

	boost::log::core::get()->set_filter(
		boost::log::trivial::severity >= loggingLevel);
}

void RepoLog::subscribeBroadcaster(RepoBroadcaster *broadcaster) {
	boost::iostreams::stream<RepoBroadcaster> *streamptr =
		new boost::iostreams::stream<RepoBroadcaster>(*broadcaster);

#if BOOST_VERSION > 105700
	boost::shared_ptr< std::ostream > stream(
		streamptr, boost::null_deleter());
#else
	boost::shared_ptr< std::ostream > stream(
		streamptr, boost::empty_deleter());
#endif

	boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();

	sink->set_filter(boost::log::trivial::severity >= boost::log::trivial::trace);
	//FIXME: better format!
	sink->set_formatter
	(
		boost::log::expressions::stream
		<< "%" << boost::log::trivial::severity << "%"
		<< boost::log::expressions::smessage);

	sink->locked_backend()->add_stream(stream);
	sink->locked_backend()->auto_flush(true);

	// Register the sink in the logging core
	boost::log::core::get()->add_sink(sink);
}

void RepoLog::subscribeListeners(
	const std::vector<RepoAbstractListener*> &listeners)
{
	/*
		FIXME: ideally, we should have a single broadcaster for the application
		and you should only need to add the listeners when you subscribe
		But the whole hackery of making a broadcaster to be a ostream
		to tap into the boost logger made this really difficult
		so for now, instantiate a new broadcaster everytime.
		And I will review this on a braver day...
		*/
	RepoBroadcaster *broadcaster = new RepoBroadcaster();

	for (auto listener : listeners)
		broadcaster->subscribe(listener);

	subscribeBroadcaster(broadcaster);
}<commit_msg>ISSUE #366 attempt to remove default sink<commit_after>#include "repo_log.h"

#if BOOST_VERSION > 105700
#include <boost/core/null_deleter.hpp>
#else
#include <boost/utility/empty_deleter.hpp>
#endif

#include <boost/iostreams/stream.hpp>
#include <boost/log/core/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/utility/setup.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <ctime>

using namespace repo::lib;
using text_sink = boost::log::sinks::synchronous_sink < boost::log::sinks::text_ostream_backend >;

BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime)
BOOST_LOG_ATTRIBUTE_KEYWORD(threadid, "ThreadID", boost::log::attributes::current_thread_id::value_type)

auto logFormatting = boost::log::expressions::stream
<< "[" << boost::log::expressions::format_date_time(timestamp, "%Y-%m-%d %H:%M:%S") << "]"
<< "(" << threadid << ") <" << boost::log::trivial::severity
<< ">"
<< ": " << boost::log::expressions::smessage;

RepoLog::RepoLog()
{
	boost::log::core::get()->remove_all_sinks();
	auto sink = boost::log::add_console_log(std::cout);
	sink->set_formatter
	(
		logFormatting
	);
	sink->imbue(sink->getloc());
}
RepoLog::~RepoLog()
{
}

void RepoLog::log(
	const RepoLogLevel &severity,
	const std::string  &msg)
{
	switch (severity)
	{
	case RepoLogLevel::TRACE:
		repoTrace << msg;
		break;
	case RepoLogLevel::DEBUG:
		repoDebug << msg;
		break;
	case RepoLogLevel::INFO:
		repoInfo << msg;
		break;
	case RepoLogLevel::WARNING:
		repoWarning << msg;
		break;
	case RepoLogLevel::ERR:
		repoError << msg;
		break;
	case RepoLogLevel::FATAL:
		repoFatal << msg;
	}
}

static std::string getTimeAsString()
{
	time_t rawtime;
	struct tm * timeinfo;
	char buffer[80];

	time(&rawtime);
	timeinfo = localtime(&rawtime);

	strftime(buffer, 80, "%d-%m-%Y_%Hh%Mm%S", timeinfo);
	return std::string(buffer);
}

void RepoLog::logToFile(const std::string &filePath)
{
	boost::filesystem::path logPath(filePath);
	std::string fileName;
	// a directory is given
	std::string name = getTimeAsString() + "_%N.log";
	fileName = (logPath / name).string();

	boost::log::add_file_log
	(
		boost::log::keywords::file_name = fileName,
		boost::log::keywords::rotation_size = 10 * 1024 * 1024,
		boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0),
		boost::log::keywords::auto_flush = true,
		boost::log::keywords::format = (
			logFormatting)
	);
	boost::log::add_common_attributes();

	repoInfo << "Log file registered: " << filePath;
}

void RepoLog::setLoggingLevel(const RepoLogLevel &level)
{
	boost::log::trivial::severity_level loggingLevel;
	switch (level)
	{
	case repo::lib::RepoLog::RepoLogLevel::TRACE:
		loggingLevel = boost::log::trivial::trace;
		break;
	case repo::lib::RepoLog::RepoLogLevel::DEBUG:
		loggingLevel = boost::log::trivial::debug;
		break;
	case repo::lib::RepoLog::RepoLogLevel::INFO:
		loggingLevel = boost::log::trivial::info;
		break;
	case repo::lib::RepoLog::RepoLogLevel::WARNING:
		loggingLevel = boost::log::trivial::warning;
		break;
	case repo::lib::RepoLog::RepoLogLevel::ERR:
		loggingLevel = boost::log::trivial::error;
		break;
	case repo::lib::RepoLog::RepoLogLevel::FATAL:
		loggingLevel = boost::log::trivial::fatal;
		break;
	default:
		repoError << "Unknown log level: " << (int)level;
		return;
	}

	boost::log::core::get()->set_filter(
		boost::log::trivial::severity >= loggingLevel);
}

void RepoLog::subscribeBroadcaster(RepoBroadcaster *broadcaster) {
	boost::iostreams::stream<RepoBroadcaster> *streamptr =
		new boost::iostreams::stream<RepoBroadcaster>(*broadcaster);

#if BOOST_VERSION > 105700
	boost::shared_ptr< std::ostream > stream(
		streamptr, boost::null_deleter());
#else
	boost::shared_ptr< std::ostream > stream(
		streamptr, boost::empty_deleter());
#endif

	boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();

	sink->set_filter(boost::log::trivial::severity >= boost::log::trivial::trace);
	//FIXME: better format!
	sink->set_formatter
	(
		boost::log::expressions::stream
		<< "%" << boost::log::trivial::severity << "%"
		<< boost::log::expressions::smessage);

	sink->locked_backend()->add_stream(stream);
	sink->locked_backend()->auto_flush(true);

	// Register the sink in the logging core
	boost::log::core::get()->add_sink(sink);
}

void RepoLog::subscribeListeners(
	const std::vector<RepoAbstractListener*> &listeners)
{
	/*
		FIXME: ideally, we should have a single broadcaster for the application
		and you should only need to add the listeners when you subscribe
		But the whole hackery of making a broadcaster to be a ostream
		to tap into the boost logger made this really difficult
		so for now, instantiate a new broadcaster everytime.
		And I will review this on a braver day...
		*/
	RepoBroadcaster *broadcaster = new RepoBroadcaster();

	for (auto listener : listeners)
		broadcaster->subscribe(listener);

	subscribeBroadcaster(broadcaster);
}<|endoftext|>


<commit_before>#include <include/cef_app.h>

#include "../cef_handler.h"
#include "../window/about_window.h"
#include "../window/accounts_window.h"

namespace {

    const char *const icon_names_[] = {
       "offline",
       "offline",
       "online",
       "flash",
       "flash-important"
    };

    const char *const icon_files_[] = {
       "offline.svg",
       "offline.svg",
       "online.svg",
       "flash.svg",
       "flash-important.svg"
    };
}

StatusIcon::StatusIcon(std::string icons_dir)
   : icons_folder_ (icons_dir),
     icon_handler_(NULL)
{
  Init();
}

StatusIcon::~StatusIcon() {
}

std::string
StatusIcon::GetIconPath(Icon icon) {
  return icons_folder_ + icon_files_[icon];
}

std::string
StatusIcon::GetIconName(Icon icon) {
  return icon_names_[icon];
}

unsigned char
StatusIcon::GetIcon() {
  return current_icon_;
}

void
StatusIcon::SetBadge(int badge, bool is_important) {
    if (
        (is_important || GetIcon() != StatusIcon::Icon::FLASH_IMPORTANT)
        && badge > 0
       ) {
        // Regular flash (e.g. notification) can't replace important flash status (e.g. messages)
        if (is_important) {
            SetIcon(StatusIcon::Icon::FLASH_IMPORTANT);
        } else {
            SetIcon(StatusIcon::Icon::FLASH);
        }
#ifdef unity
        // Parts of simple Unity integration - let's set badge in launcher!
        unity_launcher_entry_set_count(launcher_handler_, badge);
#endif
    } else {
        // if you don't know what to do just set "online" status
        SetIcon(StatusIcon::Icon::ONLINE);
#ifdef unity
        unity_launcher_entry_set_count(launcher_handler_, 0);
#endif
    }
}

bool
StatusIcon::OnClick() {
  CefRefPtr<ClientHandler> client_handler = ClientHandler::GetInstance();
  if (!client_handler)
    return false;

  CefRefPtr<BrowserWindow> window = client_handler->GetMainWindowHandle();
  if (!window)
    return false;

  if (window->GetHided()) {
    window->Show();
  } else {
    window->Hide();
  }

  return true;
}

bool
StatusIcon::OnMenuQuit() {
  CefQuitMessageLoop();
  return true;
}

bool
StatusIcon::OnMenuPortalOpen() {
  return true;
}

bool
StatusIcon::OnMenuAbout() {
  AboutWindow::Instance()->Show();
  return true;
}

bool
StatusIcon::OnMenuManageAccount() {
  AccountsWindow::Instance()->Show();
  return true;
}

bool
StatusIcon::OnMenuChangeAccount(int id) {
  CefRefPtr<ClientHandler> client_handler = ClientHandler::GetInstance();
  CefRefPtr<AccountManager> account_manager = client_handler->GetAccountManager();
  if (account_manager->GetCurrentAccount()->GetId() == id)
    return true; // Selected current account

  SetIcon(Icon::OFFLINE);
  client_handler->SwitchAccount(id);

  return true;
}<commit_msg>Отдаем логику скрытия/показа внутрь окна браузера. Теперь иконке в трее пофик на эту логику.<commit_after>#include <include/cef_app.h>

#include "../cef_handler.h"
#include "../window/about_window.h"
#include "../window/accounts_window.h"

namespace {

    const char *const icon_names_[] = {
       "offline",
       "offline",
       "online",
       "flash",
       "flash-important"
    };

    const char *const icon_files_[] = {
       "offline.svg",
       "offline.svg",
       "online.svg",
       "flash.svg",
       "flash-important.svg"
    };
}

StatusIcon::StatusIcon(std::string icons_dir)
   : icons_folder_ (icons_dir),
     icon_handler_(NULL)
{
  Init();
}

StatusIcon::~StatusIcon() {
}

std::string
StatusIcon::GetIconPath(Icon icon) {
  return icons_folder_ + icon_files_[icon];
}

std::string
StatusIcon::GetIconName(Icon icon) {
  return icon_names_[icon];
}

unsigned char
StatusIcon::GetIcon() {
  return current_icon_;
}

void
StatusIcon::SetBadge(int badge, bool is_important) {
    if (
        (is_important || GetIcon() != StatusIcon::Icon::FLASH_IMPORTANT)
        && badge > 0
       ) {
        // Regular flash (e.g. notification) can't replace important flash status (e.g. messages)
        if (is_important) {
            SetIcon(StatusIcon::Icon::FLASH_IMPORTANT);
        } else {
            SetIcon(StatusIcon::Icon::FLASH);
        }
#ifdef unity
        // Parts of simple Unity integration - let's set badge in launcher!
        unity_launcher_entry_set_count(launcher_handler_, badge);
#endif
    } else {
        // if you don't know what to do just set "online" status
        SetIcon(StatusIcon::Icon::ONLINE);
#ifdef unity
        unity_launcher_entry_set_count(launcher_handler_, 0);
#endif
    }
}

bool
StatusIcon::OnClick() {
  CefRefPtr<ClientHandler> client_handler = ClientHandler::GetInstance();
  if (!client_handler)
    return false;

  CefRefPtr<BrowserWindow> window = client_handler->GetMainWindowHandle();
  if (!window)
    return false;

  window->ToggleVisibility();

  return true;
}

bool
StatusIcon::OnMenuQuit() {
  CefQuitMessageLoop();
  return true;
}

bool
StatusIcon::OnMenuPortalOpen() {
  return true;
}

bool
StatusIcon::OnMenuAbout() {
  AboutWindow::Instance()->Show();
  return true;
}

bool
StatusIcon::OnMenuManageAccount() {
  AccountsWindow::Instance()->Show();
  return true;
}

bool
StatusIcon::OnMenuChangeAccount(int id) {
  CefRefPtr<ClientHandler> client_handler = ClientHandler::GetInstance();
  CefRefPtr<AccountManager> account_manager = client_handler->GetAccountManager();
  if (account_manager->GetCurrentAccount()->GetId() == id)
    return true; // Selected current account

  SetIcon(Icon::OFFLINE);
  client_handler->SwitchAccount(id);

  return true;
}<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libmspub 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/.
 */

#include "MSPUBParser97.h"

#include <memory>
#include <utility>

#include "MSPUBCollector.h"
#include "libmspub_utils.h"
#include "MSPUBTypes.h"

namespace libmspub
{

MSPUBParser97::MSPUBParser97(librevenge::RVNGInputStream *input, MSPUBCollector *collector)
  : MSPUBParser2k(input, collector), m_isBanner(false)
{
  m_collector->useEncodingHeuristic();
}

unsigned short MSPUBParser97::getTextMarker() const
{
  return 0x0000;
}

unsigned MSPUBParser97::getTextIdOffset() const
{
  return 0x46;
}

bool MSPUBParser97::parse()
{
  std::unique_ptr<librevenge::RVNGInputStream> contents(m_input->getSubStreamByName("Contents"));
  if (!contents)
  {
    MSPUB_DEBUG_MSG(("Couldn't get contents stream.\n"));
    return false;
  }
  if (!parseContents(contents.get()))
  {
    MSPUB_DEBUG_MSG(("Couldn't parse contents stream.\n"));
    return false;
  }
  return m_collector->go();
}

bool MSPUBParser97::parseDocument(librevenge::RVNGInputStream *input)
{
  if (bool(m_documentChunkIndex))
  {
    input->seek(m_contentChunks[m_documentChunkIndex.get()].offset + 0x12, librevenge::RVNG_SEEK_SET);
    unsigned short coordinateSystemMark = readU16(input);
    m_isBanner = coordinateSystemMark == 0x0007;
    unsigned width = readU32(input);
    unsigned height = readU32(input);
    m_collector->setWidthInEmu(width);
    m_collector->setHeightInEmu(height);
    return true;
  }
  return false;
}

void MSPUBParser97::parseContentsTextIfNecessary(librevenge::RVNGInputStream *input)
{
  input->seek(0x12, librevenge::RVNG_SEEK_SET);
  input->seek(readU32(input), librevenge::RVNG_SEEK_SET);
  input->seek(14, librevenge::RVNG_SEEK_CUR);
  unsigned textStart = readU32(input);
  unsigned textEnd = readU32(input);
  unsigned prop1Index = readU16(input);
  unsigned prop2Index = readU16(input);
  unsigned prop3Index = readU16(input);
  unsigned prop3End = readU16(input);
  std::vector<SpanInfo97> spanInfos = getSpansInfo(input, prop1Index,
                                                   prop2Index, prop3Index, prop3End);
  input->seek(textStart, librevenge::RVNG_SEEK_SET);
  TextInfo97 textInfo = getTextInfo(input, textEnd - textStart);
  unsigned iParaEnd = 0, iSpanEnd = 0;
  unsigned currentParaIndex = 0;
  unsigned currentSpanIndex = 0;
  for (unsigned iShapeEnd = 0; iShapeEnd < textInfo.m_shapeEnds.size(); ++iShapeEnd)
  {
    unsigned shapeEnd = std::min<unsigned>(textInfo.m_shapeEnds[iShapeEnd], textInfo.m_chars.size());
    std::vector<TextParagraph> shapeParas;
    while (currentParaIndex < shapeEnd)
    {
      unsigned paraEnd = iParaEnd < textInfo.m_paragraphEnds.size() ?
                         textInfo.m_paragraphEnds[iParaEnd++] : shapeEnd;
      if (paraEnd > shapeEnd)
      {
        --iParaEnd;
        paraEnd = shapeEnd;
      }
      std::vector<TextSpan> paraSpans;
      while (currentSpanIndex < paraEnd)
      {
        const SpanInfo97 &spanInfo = iSpanEnd < spanInfos.size() ?
                                     spanInfos[iSpanEnd++] :
                                     SpanInfo97(paraEnd, CharacterStyle());
        unsigned spanEnd = spanInfo.m_spanEnd;
        if (spanEnd > paraEnd)
        {
          --iSpanEnd;
          spanEnd = paraEnd;
        }
        const CharacterStyle &spanStyle = spanInfo.m_style;
        std::vector<unsigned char> spanChars;
        spanChars.reserve(std::min(spanEnd - currentSpanIndex, m_length));
        for (unsigned i = currentSpanIndex; i < spanEnd; ++i)
        {
          unsigned char ch = textInfo.m_chars[i];
          if (ch == 0xB) // Pub97 interprets vertical tab as nonbreaking space.
          {
            spanChars.push_back('\n');
          }
          else if (ch == 0x0D)
          {
            if (i + 1 < spanEnd && textInfo.m_chars[i + 1] == 0x0A)
            {
              ++i; // ignore the 0x0D and advance past the 0x0A
            }
          }
          else if (ch == 0x0C)
          {
            // ignore the 0x0C
          }
          else
          {
            spanChars.push_back(ch);
          }
        }
        paraSpans.push_back(TextSpan(spanChars, spanStyle));
        currentSpanIndex = spanEnd;
      }
      shapeParas.push_back(TextParagraph(paraSpans, ParagraphStyle()));
      currentParaIndex = paraEnd;
    }
    m_collector->addTextString(shapeParas, iShapeEnd);
  }
}

std::vector<MSPUBParser97::SpanInfo97> MSPUBParser97::getSpansInfo(
  librevenge::RVNGInputStream *input,
  unsigned prop1Index, unsigned prop2Index, unsigned /* prop3Index */,
  unsigned /* prop3End */)
{
  std::vector<unsigned> spanEnds;
  std::vector<SpanInfo97> ret;
  for (unsigned i = prop1Index; i < prop2Index; ++i)
  {
    unsigned offset = i * 0x200;
    input->seek(offset + 0x1FF, librevenge::RVNG_SEEK_SET);
    unsigned numEntries = readU8(input);
    input->seek(offset, librevenge::RVNG_SEEK_SET);
    // Skip the first thing; it is not an end
    unsigned start = readU32(input);
    for (unsigned j = 0; j < numEntries; ++j)
    {
      spanEnds.push_back(readU32(input) - start);
    }
    std::vector<unsigned char> spanStyleIndices;
    for (unsigned j = 0; j < spanEnds.size(); ++j)
    {
      spanStyleIndices.push_back(readU8(input));
    }
    while (stillReading(input, offset + 0x200) && readU8(input) == 0)
    {
      ;
    }
    input->seek(-1, librevenge::RVNG_SEEK_CUR);
    std::map<unsigned char, CharacterStyle> stylesByIndex;
    while (stillReading(input, offset + 0x1FF))
    {
      unsigned length = readU8(input);
      unsigned nextOffset = input->tell() + length;
      unsigned char index = static_cast<unsigned char>(
                              (input->tell() - 1 - offset) / 2);
      stylesByIndex[index] = readCharacterStyle(input, length);
      input->seek(nextOffset, librevenge::RVNG_SEEK_SET);
    }
    for (unsigned j = 0; j < spanEnds.size(); ++j)
    {
      ret.push_back(SpanInfo97(spanEnds[j], j < spanStyleIndices.size() ?
                               stylesByIndex[spanStyleIndices[j]] : CharacterStyle()));
    }
  }
  return ret;
}

CharacterStyle MSPUBParser97::readCharacterStyle(
  librevenge::RVNGInputStream *input, unsigned length)
{
  unsigned begin = input->tell();
  bool underline = false, italic = false, bold = false;
  int colorIndex = -1;
  unsigned fontIndex = 0;
  int textSizeVariationFromDefault = 0;

  if (length >= 1)
  {
    unsigned char biFlags = readU8(input);
    bold = biFlags & 0x1;
    italic = biFlags & 0x2;
  }
  if (length >= 3)
  {
    input->seek(begin + 0x2, librevenge::RVNG_SEEK_SET);
    fontIndex = readU8(input);
  }
  if (length >= 9)
  {
    input->seek(begin + 0x8, librevenge::RVNG_SEEK_SET);
    underline = readU8(input) & 0x1;
  }
  if (length >= 5)
  {
    input->seek(begin + 0x4, librevenge::RVNG_SEEK_SET);
    textSizeVariationFromDefault =
      length >= 6 ? readS16(input) : readS8(input);
  }
  if (length >= 16)
  {
    input->seek(begin + 0xC, librevenge::RVNG_SEEK_SET);
    colorIndex = getColorIndexByQuillEntry(readU32(input));
  }
  double textSizeInPt = 10 +
                        static_cast<double>(textSizeVariationFromDefault) / 2;
  return CharacterStyle(underline, italic, bold, textSizeInPt, colorIndex,
                        fontIndex);
}

MSPUBParser97::TextInfo97 MSPUBParser97::getTextInfo(librevenge::RVNGInputStream *input, unsigned length)
{
  length = std::min(length, m_length); // sanity check
  std::vector<unsigned char> chars;
  chars.reserve(length);
  std::vector<unsigned> paragraphEnds;
  std::vector<unsigned> shapeEnds;
  unsigned start = input->tell();
  unsigned char last = '\0';
  while (stillReading(input, start + length))
  {
    chars.push_back(readU8(input));
    if (last == 0xD && chars.back() == 0xA)
    {
      paragraphEnds.push_back(chars.size());
    }
    else if (chars.back() == 0xC)
    {
      shapeEnds.push_back(chars.size());
    }
    last = chars.back();
  }
  return TextInfo97(chars, paragraphEnds, shapeEnds);
}

int MSPUBParser97::translateCoordinateIfNecessary(int coordinate) const
{
  if (m_isBanner)
  {
    return coordinate - 120 * EMUS_IN_INCH;
  }
  else
  {
    return coordinate - 25 * EMUS_IN_INCH;
  }
}

unsigned MSPUBParser97::getFirstLineOffset() const
{
  return 0x22;
}

unsigned MSPUBParser97::getSecondLineOffset() const
{
  return 0x2D;
}

unsigned MSPUBParser97::getShapeFillTypeOffset() const
{
  return 0x20;
}

unsigned MSPUBParser97::getShapeFillColorOffset() const
{
  return 0x18;
}

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<commit_msg>ofz#1288 fix signed integer overflow<commit_after>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libmspub 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/.
 */

#include "MSPUBParser97.h"

#include <limits>
#include <memory>
#include <utility>

#include "MSPUBCollector.h"
#include "libmspub_utils.h"
#include "MSPUBTypes.h"

namespace libmspub
{

MSPUBParser97::MSPUBParser97(librevenge::RVNGInputStream *input, MSPUBCollector *collector)
  : MSPUBParser2k(input, collector), m_isBanner(false)
{
  m_collector->useEncodingHeuristic();
}

unsigned short MSPUBParser97::getTextMarker() const
{
  return 0x0000;
}

unsigned MSPUBParser97::getTextIdOffset() const
{
  return 0x46;
}

bool MSPUBParser97::parse()
{
  std::unique_ptr<librevenge::RVNGInputStream> contents(m_input->getSubStreamByName("Contents"));
  if (!contents)
  {
    MSPUB_DEBUG_MSG(("Couldn't get contents stream.\n"));
    return false;
  }
  if (!parseContents(contents.get()))
  {
    MSPUB_DEBUG_MSG(("Couldn't parse contents stream.\n"));
    return false;
  }
  return m_collector->go();
}

bool MSPUBParser97::parseDocument(librevenge::RVNGInputStream *input)
{
  if (bool(m_documentChunkIndex))
  {
    input->seek(m_contentChunks[m_documentChunkIndex.get()].offset + 0x12, librevenge::RVNG_SEEK_SET);
    unsigned short coordinateSystemMark = readU16(input);
    m_isBanner = coordinateSystemMark == 0x0007;
    unsigned width = readU32(input);
    unsigned height = readU32(input);
    m_collector->setWidthInEmu(width);
    m_collector->setHeightInEmu(height);
    return true;
  }
  return false;
}

void MSPUBParser97::parseContentsTextIfNecessary(librevenge::RVNGInputStream *input)
{
  input->seek(0x12, librevenge::RVNG_SEEK_SET);
  input->seek(readU32(input), librevenge::RVNG_SEEK_SET);
  input->seek(14, librevenge::RVNG_SEEK_CUR);
  unsigned textStart = readU32(input);
  unsigned textEnd = readU32(input);
  unsigned prop1Index = readU16(input);
  unsigned prop2Index = readU16(input);
  unsigned prop3Index = readU16(input);
  unsigned prop3End = readU16(input);
  std::vector<SpanInfo97> spanInfos = getSpansInfo(input, prop1Index,
                                                   prop2Index, prop3Index, prop3End);
  input->seek(textStart, librevenge::RVNG_SEEK_SET);
  TextInfo97 textInfo = getTextInfo(input, textEnd - textStart);
  unsigned iParaEnd = 0, iSpanEnd = 0;
  unsigned currentParaIndex = 0;
  unsigned currentSpanIndex = 0;
  for (unsigned iShapeEnd = 0; iShapeEnd < textInfo.m_shapeEnds.size(); ++iShapeEnd)
  {
    unsigned shapeEnd = std::min<unsigned>(textInfo.m_shapeEnds[iShapeEnd], textInfo.m_chars.size());
    std::vector<TextParagraph> shapeParas;
    while (currentParaIndex < shapeEnd)
    {
      unsigned paraEnd = iParaEnd < textInfo.m_paragraphEnds.size() ?
                         textInfo.m_paragraphEnds[iParaEnd++] : shapeEnd;
      if (paraEnd > shapeEnd)
      {
        --iParaEnd;
        paraEnd = shapeEnd;
      }
      std::vector<TextSpan> paraSpans;
      while (currentSpanIndex < paraEnd)
      {
        const SpanInfo97 &spanInfo = iSpanEnd < spanInfos.size() ?
                                     spanInfos[iSpanEnd++] :
                                     SpanInfo97(paraEnd, CharacterStyle());
        unsigned spanEnd = spanInfo.m_spanEnd;
        if (spanEnd > paraEnd)
        {
          --iSpanEnd;
          spanEnd = paraEnd;
        }
        const CharacterStyle &spanStyle = spanInfo.m_style;
        std::vector<unsigned char> spanChars;
        spanChars.reserve(std::min(spanEnd - currentSpanIndex, m_length));
        for (unsigned i = currentSpanIndex; i < spanEnd; ++i)
        {
          unsigned char ch = textInfo.m_chars[i];
          if (ch == 0xB) // Pub97 interprets vertical tab as nonbreaking space.
          {
            spanChars.push_back('\n');
          }
          else if (ch == 0x0D)
          {
            if (i + 1 < spanEnd && textInfo.m_chars[i + 1] == 0x0A)
            {
              ++i; // ignore the 0x0D and advance past the 0x0A
            }
          }
          else if (ch == 0x0C)
          {
            // ignore the 0x0C
          }
          else
          {
            spanChars.push_back(ch);
          }
        }
        paraSpans.push_back(TextSpan(spanChars, spanStyle));
        currentSpanIndex = spanEnd;
      }
      shapeParas.push_back(TextParagraph(paraSpans, ParagraphStyle()));
      currentParaIndex = paraEnd;
    }
    m_collector->addTextString(shapeParas, iShapeEnd);
  }
}

std::vector<MSPUBParser97::SpanInfo97> MSPUBParser97::getSpansInfo(
  librevenge::RVNGInputStream *input,
  unsigned prop1Index, unsigned prop2Index, unsigned /* prop3Index */,
  unsigned /* prop3End */)
{
  std::vector<unsigned> spanEnds;
  std::vector<SpanInfo97> ret;
  for (unsigned i = prop1Index; i < prop2Index; ++i)
  {
    unsigned offset = i * 0x200;
    input->seek(offset + 0x1FF, librevenge::RVNG_SEEK_SET);
    unsigned numEntries = readU8(input);
    input->seek(offset, librevenge::RVNG_SEEK_SET);
    // Skip the first thing; it is not an end
    unsigned start = readU32(input);
    for (unsigned j = 0; j < numEntries; ++j)
    {
      spanEnds.push_back(readU32(input) - start);
    }
    std::vector<unsigned char> spanStyleIndices;
    for (unsigned j = 0; j < spanEnds.size(); ++j)
    {
      spanStyleIndices.push_back(readU8(input));
    }
    while (stillReading(input, offset + 0x200) && readU8(input) == 0)
    {
      ;
    }
    input->seek(-1, librevenge::RVNG_SEEK_CUR);
    std::map<unsigned char, CharacterStyle> stylesByIndex;
    while (stillReading(input, offset + 0x1FF))
    {
      unsigned length = readU8(input);
      unsigned nextOffset = input->tell() + length;
      unsigned char index = static_cast<unsigned char>(
                              (input->tell() - 1 - offset) / 2);
      stylesByIndex[index] = readCharacterStyle(input, length);
      input->seek(nextOffset, librevenge::RVNG_SEEK_SET);
    }
    for (unsigned j = 0; j < spanEnds.size(); ++j)
    {
      ret.push_back(SpanInfo97(spanEnds[j], j < spanStyleIndices.size() ?
                               stylesByIndex[spanStyleIndices[j]] : CharacterStyle()));
    }
  }
  return ret;
}

CharacterStyle MSPUBParser97::readCharacterStyle(
  librevenge::RVNGInputStream *input, unsigned length)
{
  unsigned begin = input->tell();
  bool underline = false, italic = false, bold = false;
  int colorIndex = -1;
  unsigned fontIndex = 0;
  int textSizeVariationFromDefault = 0;

  if (length >= 1)
  {
    unsigned char biFlags = readU8(input);
    bold = biFlags & 0x1;
    italic = biFlags & 0x2;
  }
  if (length >= 3)
  {
    input->seek(begin + 0x2, librevenge::RVNG_SEEK_SET);
    fontIndex = readU8(input);
  }
  if (length >= 9)
  {
    input->seek(begin + 0x8, librevenge::RVNG_SEEK_SET);
    underline = readU8(input) & 0x1;
  }
  if (length >= 5)
  {
    input->seek(begin + 0x4, librevenge::RVNG_SEEK_SET);
    textSizeVariationFromDefault =
      length >= 6 ? readS16(input) : readS8(input);
  }
  if (length >= 16)
  {
    input->seek(begin + 0xC, librevenge::RVNG_SEEK_SET);
    colorIndex = getColorIndexByQuillEntry(readU32(input));
  }
  double textSizeInPt = 10 +
                        static_cast<double>(textSizeVariationFromDefault) / 2;
  return CharacterStyle(underline, italic, bold, textSizeInPt, colorIndex,
                        fontIndex);
}

MSPUBParser97::TextInfo97 MSPUBParser97::getTextInfo(librevenge::RVNGInputStream *input, unsigned length)
{
  length = std::min(length, m_length); // sanity check
  std::vector<unsigned char> chars;
  chars.reserve(length);
  std::vector<unsigned> paragraphEnds;
  std::vector<unsigned> shapeEnds;
  unsigned start = input->tell();
  unsigned char last = '\0';
  while (stillReading(input, start + length))
  {
    chars.push_back(readU8(input));
    if (last == 0xD && chars.back() == 0xA)
    {
      paragraphEnds.push_back(chars.size());
    }
    else if (chars.back() == 0xC)
    {
      shapeEnds.push_back(chars.size());
    }
    last = chars.back();
  }
  return TextInfo97(chars, paragraphEnds, shapeEnds);
}

int MSPUBParser97::translateCoordinateIfNecessary(int coordinate) const
{
  const int offset = (m_isBanner ? 120 : 25) * EMUS_IN_INCH;
  if (std::numeric_limits<int>::min() + offset > coordinate)
    return std::numeric_limits<int>::min();
  else
    return coordinate - offset;
}

unsigned MSPUBParser97::getFirstLineOffset() const
{
  return 0x22;
}

unsigned MSPUBParser97::getSecondLineOffset() const
{
  return 0x2D;
}

unsigned MSPUBParser97::getShapeFillTypeOffset() const
{
  return 0x20;
}

unsigned MSPUBParser97::getShapeFillColorOffset() const
{
  return 0x18;
}

}

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


<commit_before><commit_msg>imgui_scene_widget : missing include<commit_after><|endoftext|>