<commit_before>/*
 * Copyright (c) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#if !OS(WIN) && !OS(ANDROID)
#include "SkFontConfigInterface.h"
#endif
#include "SkFontMgr.h"
#include "SkStream.h"
#include "SkTypeface.h"
#include "platform/NotImplemented.h"
#include "platform/fonts/AlternateFontFamily.h"
#include "platform/fonts/FontCache.h"
#include "platform/fonts/FontDescription.h"
#include "platform/fonts/FontFaceCreationParams.h"
#include "platform/fonts/SimpleFontData.h"
#include "public/platform/Platform.h"
#include "public/platform/linux/WebSandboxSupport.h"
#include "wtf/Assertions.h"
#include "wtf/text/AtomicString.h"
#include "wtf/text/CString.h"
#include <unicode/locid.h>

#if !OS(WIN) && !OS(ANDROID)
static SkStream* streamForFontconfigInterfaceId(int fontconfigInterfaceId)
{
    SkAutoTUnref<SkFontConfigInterface> fci(SkFontConfigInterface::RefGlobal());
    SkFontConfigInterface::FontIdentity fontIdentity;
    fontIdentity.fID = fontconfigInterfaceId;
    return fci->openStream(fontIdentity);
}
#endif

namespace blink {

void FontCache::platformInit()
{
}

PassRefPtr<SimpleFontData> FontCache::fallbackOnStandardFontStyle(
    const FontDescription& fontDescription, UChar32 character)
{
    FontDescription substituteDescription(fontDescription);
    substituteDescription.setStyle(FontStyleNormal);
    substituteDescription.setWeight(FontWeightNormal);

    FontFaceCreationParams creationParams(substituteDescription.family().family());
    FontPlatformData* substitutePlatformData = getFontPlatformData(substituteDescription, creationParams);
    if (substitutePlatformData && substitutePlatformData->fontContainsCharacter(character)) {
        FontPlatformData platformData = FontPlatformData(*substitutePlatformData);
        platformData.setSyntheticBold(fontDescription.weight() >= FontWeight600);
        platformData.setSyntheticItalic(fontDescription.style() == FontStyleItalic);
        return fontDataFromFontPlatformData(&platformData, DoNotRetain);
    }

    return nullptr;
}

#if !OS(WIN) && !OS(ANDROID)
PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(const FontDescription& fontDescription, UChar32 c, const SimpleFontData*)
{
    // First try the specified font with standard style & weight.
    if (fontDescription.style() == FontStyleItalic
        || fontDescription.weight() >= FontWeight600) {
        RefPtr<SimpleFontData> fontData = fallbackOnStandardFontStyle(
            fontDescription, c);
        if (fontData)
            return fontData;
    }

    FontCache::PlatformFallbackFont fallbackFont;
    FontCache::getFontForCharacter(c, "", &fallbackFont);
    if (fallbackFont.name.isEmpty())
        return nullptr;

    FontFaceCreationParams creationParams;
    creationParams = FontFaceCreationParams(fallbackFont.filename, fallbackFont.fontconfigInterfaceId, fallbackFont.ttcIndex);

    // Changes weight and/or italic of given FontDescription depends on
    // the result of fontconfig so that keeping the correct font mapping
    // of the given character. See http://crbug.com/32109 for details.
    bool shouldSetSyntheticBold = false;
    bool shouldSetSyntheticItalic = false;
    FontDescription description(fontDescription);
    if (fallbackFont.isBold && description.weight() < FontWeightBold)
        description.setWeight(FontWeightBold);
    if (!fallbackFont.isBold && description.weight() >= FontWeightBold) {
        shouldSetSyntheticBold = true;
        description.setWeight(FontWeightNormal);
    }
    if (fallbackFont.isItalic && description.style() == FontStyleNormal)
        description.setStyle(FontStyleItalic);
    if (!fallbackFont.isItalic && description.style() == FontStyleItalic) {
        shouldSetSyntheticItalic = true;
        description.setStyle(FontStyleNormal);
    }

    FontPlatformData* substitutePlatformData = getFontPlatformData(description, creationParams);
    if (!substitutePlatformData)
        return nullptr;
    FontPlatformData platformData = FontPlatformData(*substitutePlatformData);
    platformData.setSyntheticBold(shouldSetSyntheticBold);
    platformData.setSyntheticItalic(shouldSetSyntheticItalic);
    return fontDataFromFontPlatformData(&platformData, DoNotRetain);
}

#endif // !OS(WIN) && !OS(ANDROID)

PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain)
{
    const FontFaceCreationParams fallbackCreationParams(getFallbackFontFamily(description));
    const FontPlatformData* fontPlatformData = getFontPlatformData(description, fallbackCreationParams);

    // We should at least have Sans or Arial which is the last resort fallback of SkFontHost ports.
    if (!fontPlatformData) {
        DEFINE_STATIC_LOCAL(const FontFaceCreationParams, sansCreationParams, (AtomicString("Sans", AtomicString::ConstructFromLiteral)));
        fontPlatformData = getFontPlatformData(description, sansCreationParams);
    }
    if (!fontPlatformData) {
        DEFINE_STATIC_LOCAL(const FontFaceCreationParams, arialCreationParams, (AtomicString("Arial", AtomicString::ConstructFromLiteral)));
        fontPlatformData = getFontPlatformData(description, arialCreationParams);
    }
#if OS(WIN)
    // Try some more Windows-specific fallbacks.
    if (!fontPlatformData) {
        DEFINE_STATIC_LOCAL(const FontFaceCreationParams, msuigothicCreationParams, (AtomicString("MS UI Gothic", AtomicString::ConstructFromLiteral)));
        fontPlatformData = getFontPlatformData(description, msuigothicCreationParams);
    }
    if (!fontPlatformData) {
        DEFINE_STATIC_LOCAL(const FontFaceCreationParams, mssansserifCreationParams, (AtomicString("Microsoft Sans Serif", AtomicString::ConstructFromLiteral)));
        fontPlatformData = getFontPlatformData(description, mssansserifCreationParams);
    }
#endif

    ASSERT(fontPlatformData);
    return fontDataFromFontPlatformData(fontPlatformData, shouldRetain);
}

#if OS(WIN)
static inline SkFontStyle fontStyle(const FontDescription& fontDescription)
{
    int width = static_cast<int>(fontDescription.stretch());
    int weight = (fontDescription.weight() - FontWeight100 + 1) * 100;
    SkFontStyle::Slant slant = fontDescription.style() == FontStyleItalic
        ? SkFontStyle::kItalic_Slant
        : SkFontStyle::kUpright_Slant;
    return SkFontStyle(weight, width, slant);
}

COMPILE_ASSERT(FontStretchUltraCondensed == SkFontStyle::kUltraCondensed_Width,
    FontStretchUltraCondensedMapsTokUltraCondensed_Width);
COMPILE_ASSERT(FontStretchNormal == SkFontStyle::kNormal_Width,
    FontStretchNormalMapsTokNormal_Width);
COMPILE_ASSERT(FontStretchUltraExpanded == SkFontStyle::kUltaExpanded_Width,
    FontStretchUltraExpandedMapsTokUltaExpanded_Width);
#endif

PassRefPtr<SkTypeface> FontCache::createTypeface(const FontDescription& fontDescription, const FontFaceCreationParams& creationParams, CString& name)
{
#if !OS(WIN) && !OS(ANDROID)
    if (creationParams.creationType() == CreateFontByFciIdAndTtcIndex) {
        // TODO(dro): crbug.com/381620 Use creationParams.ttcIndex() after
        // https://code.google.com/p/skia/issues/detail?id=1186 gets fixed.
        SkTypeface* typeface = nullptr;
        if (Platform::current()->sandboxSupport())
            typeface = SkTypeface::CreateFromStream(streamForFontconfigInterfaceId(creationParams.fontconfigInterfaceId()));
        else
            typeface = SkTypeface::CreateFromFile(creationParams.filename().data());

        if (typeface)
            return adoptRef(typeface);
        else
            return nullptr;
    }
#endif

    AtomicString family = creationParams.family();
    // If we're creating a fallback font (e.g. "-webkit-monospace"), convert the name into
    // the fallback name (like "monospace") that fontconfig understands.
    if (!family.length() || family.startsWith("-webkit-")) {
        name = getFallbackFontFamily(fontDescription).string().utf8();
    } else {
        // convert the name to utf8
        name = family.utf8();
    }

    int style = SkTypeface::kNormal;
    if (fontDescription.weight() >= FontWeight600)
        style |= SkTypeface::kBold;
    if (fontDescription.style())
        style |= SkTypeface::kItalic;

#if OS(WIN)
    if (s_sideloadedFonts) {
        HashMap<String, SkTypeface*>::iterator sideloadedFont =
            s_sideloadedFonts->find(name.data());
        if (sideloadedFont != s_sideloadedFonts->end())
            return adoptRef(sideloadedFont->value);
    }

    if (m_fontManager) {
        return adoptRef(useDirectWrite()
            ? m_fontManager->matchFamilyStyle(name.data(), fontStyle(fontDescription))
            : m_fontManager->legacyCreateTypeface(name.data(), style)
            );
    }
#endif

    // FIXME: Use m_fontManager, SkFontStyle and matchFamilyStyle instead of
    // CreateFromName on all platforms.
    return adoptRef(SkTypeface::CreateFromName(name.data(), static_cast<SkTypeface::Style>(style)));
}

#if !OS(WIN)
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const FontFaceCreationParams& creationParams, float fontSize)
{
    CString name;
    RefPtr<SkTypeface> tf(createTypeface(fontDescription, creationParams, name));
    if (!tf)
        return 0;

    FontPlatformData* result = new FontPlatformData(tf,
        name.data(),
        fontSize,
        (fontDescription.weight() >= FontWeight600 && !tf->isBold()) || fontDescription.isSyntheticBold(),
        (fontDescription.style() && !tf->isItalic()) || fontDescription.isSyntheticItalic(),
        fontDescription.orientation(),
        fontDescription.useSubpixelPositioning());
    return result;
}
#endif // !OS(WIN)

} // namespace blink
<commit_msg>Fix a few clang warnings.<commit_after>/*
 * Copyright (c) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#if !OS(WIN) && !OS(ANDROID)
#include "SkFontConfigInterface.h"
#endif
#include "SkFontMgr.h"
#include "SkStream.h"
#include "SkTypeface.h"
#include "platform/NotImplemented.h"
#include "platform/fonts/AlternateFontFamily.h"
#include "platform/fonts/FontCache.h"
#include "platform/fonts/FontDescription.h"
#include "platform/fonts/FontFaceCreationParams.h"
#include "platform/fonts/SimpleFontData.h"
#include "public/platform/Platform.h"
#include "public/platform/linux/WebSandboxSupport.h"
#include "wtf/Assertions.h"
#include "wtf/text/AtomicString.h"
#include "wtf/text/CString.h"
#include <unicode/locid.h>

#if !OS(WIN) && !OS(ANDROID)
static SkStream* streamForFontconfigInterfaceId(int fontconfigInterfaceId)
{
    SkAutoTUnref<SkFontConfigInterface> fci(SkFontConfigInterface::RefGlobal());
    SkFontConfigInterface::FontIdentity fontIdentity;
    fontIdentity.fID = fontconfigInterfaceId;
    return fci->openStream(fontIdentity);
}
#endif

namespace blink {

void FontCache::platformInit()
{
}

PassRefPtr<SimpleFontData> FontCache::fallbackOnStandardFontStyle(
    const FontDescription& fontDescription, UChar32 character)
{
    FontDescription substituteDescription(fontDescription);
    substituteDescription.setStyle(FontStyleNormal);
    substituteDescription.setWeight(FontWeightNormal);

    FontFaceCreationParams creationParams(substituteDescription.family().family());
    FontPlatformData* substitutePlatformData = getFontPlatformData(substituteDescription, creationParams);
    if (substitutePlatformData && substitutePlatformData->fontContainsCharacter(character)) {
        FontPlatformData platformData = FontPlatformData(*substitutePlatformData);
        platformData.setSyntheticBold(fontDescription.weight() >= FontWeight600);
        platformData.setSyntheticItalic(fontDescription.style() == FontStyleItalic);
        return fontDataFromFontPlatformData(&platformData, DoNotRetain);
    }

    return nullptr;
}

#if !OS(WIN) && !OS(ANDROID)
PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(const FontDescription& fontDescription, UChar32 c, const SimpleFontData*)
{
    // First try the specified font with standard style & weight.
    if (fontDescription.style() == FontStyleItalic
        || fontDescription.weight() >= FontWeight600) {
        RefPtr<SimpleFontData> fontData = fallbackOnStandardFontStyle(
            fontDescription, c);
        if (fontData)
            return fontData;
    }

    FontCache::PlatformFallbackFont fallbackFont;
    FontCache::getFontForCharacter(c, "", &fallbackFont);
    if (fallbackFont.name.isEmpty())
        return nullptr;

    FontFaceCreationParams creationParams;
    creationParams = FontFaceCreationParams(fallbackFont.filename, fallbackFont.fontconfigInterfaceId, fallbackFont.ttcIndex);

    // Changes weight and/or italic of given FontDescription depends on
    // the result of fontconfig so that keeping the correct font mapping
    // of the given character. See http://crbug.com/32109 for details.
    bool shouldSetSyntheticBold = false;
    bool shouldSetSyntheticItalic = false;
    FontDescription description(fontDescription);
    if (fallbackFont.isBold && description.weight() < FontWeightBold)
        description.setWeight(FontWeightBold);
    if (!fallbackFont.isBold && description.weight() >= FontWeightBold) {
        shouldSetSyntheticBold = true;
        description.setWeight(FontWeightNormal);
    }
    if (fallbackFont.isItalic && description.style() == FontStyleNormal)
        description.setStyle(FontStyleItalic);
    if (!fallbackFont.isItalic && description.style() == FontStyleItalic) {
        shouldSetSyntheticItalic = true;
        description.setStyle(FontStyleNormal);
    }

    FontPlatformData* substitutePlatformData = getFontPlatformData(description, creationParams);
    if (!substitutePlatformData)
        return nullptr;
    FontPlatformData platformData = FontPlatformData(*substitutePlatformData);
    platformData.setSyntheticBold(shouldSetSyntheticBold);
    platformData.setSyntheticItalic(shouldSetSyntheticItalic);
    return fontDataFromFontPlatformData(&platformData, DoNotRetain);
}

#endif // !OS(WIN) && !OS(ANDROID)

PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain)
{
    const FontFaceCreationParams fallbackCreationParams(getFallbackFontFamily(description));
    const FontPlatformData* fontPlatformData = getFontPlatformData(description, fallbackCreationParams);

    // We should at least have Sans or Arial which is the last resort fallback of SkFontHost ports.
    if (!fontPlatformData) {
        DEFINE_STATIC_LOCAL(const FontFaceCreationParams, sansCreationParams, (AtomicString("Sans", AtomicString::ConstructFromLiteral)));
        fontPlatformData = getFontPlatformData(description, sansCreationParams);
    }
    if (!fontPlatformData) {
        DEFINE_STATIC_LOCAL(const FontFaceCreationParams, arialCreationParams, (AtomicString("Arial", AtomicString::ConstructFromLiteral)));
        fontPlatformData = getFontPlatformData(description, arialCreationParams);
    }
#if OS(WIN)
    // Try some more Windows-specific fallbacks.
    if (!fontPlatformData) {
        DEFINE_STATIC_LOCAL(const FontFaceCreationParams, msuigothicCreationParams, (AtomicString("MS UI Gothic", AtomicString::ConstructFromLiteral)));
        fontPlatformData = getFontPlatformData(description, msuigothicCreationParams);
    }
    if (!fontPlatformData) {
        DEFINE_STATIC_LOCAL(const FontFaceCreationParams, mssansserifCreationParams, (AtomicString("Microsoft Sans Serif", AtomicString::ConstructFromLiteral)));
        fontPlatformData = getFontPlatformData(description, mssansserifCreationParams);
    }
#endif

    ASSERT(fontPlatformData);
    return fontDataFromFontPlatformData(fontPlatformData, shouldRetain);
}

#if OS(WIN)
static inline SkFontStyle fontStyle(const FontDescription& fontDescription)
{
    int width = static_cast<int>(fontDescription.stretch());
    int weight = (fontDescription.weight() - FontWeight100 + 1) * 100;
    SkFontStyle::Slant slant = fontDescription.style() == FontStyleItalic
        ? SkFontStyle::kItalic_Slant
        : SkFontStyle::kUpright_Slant;
    return SkFontStyle(weight, width, slant);
}

COMPILE_ASSERT(static_cast<int>(FontStretchUltraCondensed) == static_cast<int>(SkFontStyle::kUltraCondensed_Width),
    FontStretchUltraCondensedMapsTokUltraCondensed_Width);
COMPILE_ASSERT(static_cast<int>(FontStretchNormal) == static_cast<int>(SkFontStyle::kNormal_Width),
    FontStretchNormalMapsTokNormal_Width);
COMPILE_ASSERT(static_cast<int>(FontStretchUltraExpanded) == static_cast<int>(SkFontStyle::kUltaExpanded_Width),
    FontStretchUltraExpandedMapsTokUltaExpanded_Width);
#endif

PassRefPtr<SkTypeface> FontCache::createTypeface(const FontDescription& fontDescription, const FontFaceCreationParams& creationParams, CString& name)
{
#if !OS(WIN) && !OS(ANDROID)
    if (creationParams.creationType() == CreateFontByFciIdAndTtcIndex) {
        // TODO(dro): crbug.com/381620 Use creationParams.ttcIndex() after
        // https://code.google.com/p/skia/issues/detail?id=1186 gets fixed.
        SkTypeface* typeface = nullptr;
        if (Platform::current()->sandboxSupport())
            typeface = SkTypeface::CreateFromStream(streamForFontconfigInterfaceId(creationParams.fontconfigInterfaceId()));
        else
            typeface = SkTypeface::CreateFromFile(creationParams.filename().data());

        if (typeface)
            return adoptRef(typeface);
        else
            return nullptr;
    }
#endif

    AtomicString family = creationParams.family();
    // If we're creating a fallback font (e.g. "-webkit-monospace"), convert the name into
    // the fallback name (like "monospace") that fontconfig understands.
    if (!family.length() || family.startsWith("-webkit-")) {
        name = getFallbackFontFamily(fontDescription).string().utf8();
    } else {
        // convert the name to utf8
        name = family.utf8();
    }

    int style = SkTypeface::kNormal;
    if (fontDescription.weight() >= FontWeight600)
        style |= SkTypeface::kBold;
    if (fontDescription.style())
        style |= SkTypeface::kItalic;

#if OS(WIN)
    if (s_sideloadedFonts) {
        HashMap<String, SkTypeface*>::iterator sideloadedFont =
            s_sideloadedFonts->find(name.data());
        if (sideloadedFont != s_sideloadedFonts->end())
            return adoptRef(sideloadedFont->value);
    }

    if (m_fontManager) {
        return adoptRef(useDirectWrite()
            ? m_fontManager->matchFamilyStyle(name.data(), fontStyle(fontDescription))
            : m_fontManager->legacyCreateTypeface(name.data(), style)
            );
    }
#endif

    // FIXME: Use m_fontManager, SkFontStyle and matchFamilyStyle instead of
    // CreateFromName on all platforms.
    return adoptRef(SkTypeface::CreateFromName(name.data(), static_cast<SkTypeface::Style>(style)));
}

#if !OS(WIN)
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const FontFaceCreationParams& creationParams, float fontSize)
{
    CString name;
    RefPtr<SkTypeface> tf(createTypeface(fontDescription, creationParams, name));
    if (!tf)
        return 0;

    FontPlatformData* result = new FontPlatformData(tf,
        name.data(),
        fontSize,
        (fontDescription.weight() >= FontWeight600 && !tf->isBold()) || fontDescription.isSyntheticBold(),
        (fontDescription.style() && !tf->isItalic()) || fontDescription.isSyntheticItalic(),
        fontDescription.orientation(),
        fontDescription.useSubpixelPositioning());
    return result;
}
#endif // !OS(WIN)

} // namespace blink
<|endoftext|>


<commit_before>#include <stdio.h>
#include <Halide.h>
#include <algorithm>

using namespace Halide;

static Func Build() {
    ImageParam input1(UInt(8), 3, "input1");
    ImageParam input2(UInt(8), 2, "input2");
    Param<int32_t> height("height");
    Param<int32_t> width("width");
    Param<uint8_t> thresh("thresh");
    Param<float> frac("frac");
    // Named so that it will come last, to simplify test.
    Param<float> z_ignored("z_ignored");

    Var x("x"), y("y"), c("c");

    Func f("f");
    f(x, y, c) = frac * (input1(clamp(x, 0, height), clamp(y, 0, width), c) +
                    min(thresh, input2(x, y))) + (0 * z_ignored);
    return f;
}

int main(int argc, char **argv) {

#define EXPECT(expect, actual) \
    if (expect != actual) { printf("Failure, expected %s\n", #expect); return -1; }

    for (int i = 0; i < 2; ++i) {
        Func f = Build();

        bool use_lowered = (i != 0);
        std::vector<Argument> args = f.infer_arguments(use_lowered);
        if (use_lowered) {
            EXPECT(6, args.size());
        } else {
            EXPECT(7, args.size());
        }

        EXPECT("input1", args[0].name);
        EXPECT("input2", args[1].name);
        EXPECT("frac", args[2].name);
        EXPECT("height", args[3].name);
        EXPECT("thresh", args[4].name);
        EXPECT("width", args[5].name);

        EXPECT(true, args[0].is_buffer);
        EXPECT(true, args[1].is_buffer);
        EXPECT(false, args[2].is_buffer);
        EXPECT(false, args[3].is_buffer);
        EXPECT(false, args[4].is_buffer);
        EXPECT(false, args[5].is_buffer);

        EXPECT(Type::Float, args[2].type.code);
        EXPECT(Type::Int, args[3].type.code);
        EXPECT(Type::UInt, args[4].type.code);
        EXPECT(Type::Int, args[5].type.code);

        EXPECT(32, args[2].type.bits);
        EXPECT(32, args[3].type.bits);
        EXPECT(8, args[4].type.bits);
        EXPECT(32, args[5].type.bits);

        if (!use_lowered) {
            EXPECT("z_ignored", args[6].name);
            EXPECT(false, args[6].is_buffer);
            EXPECT(Type::Float, args[6].type.code);
            EXPECT(32, args[6].type.bits);
        }
    }

    printf("Success!\n");
    return 0;

}
<commit_msg>fix cap/static<commit_after>#include <stdio.h>
#include <Halide.h>
#include <algorithm>

using namespace Halide;

Func build() {
    ImageParam input1(UInt(8), 3, "input1");
    ImageParam input2(UInt(8), 2, "input2");
    Param<int32_t> height("height");
    Param<int32_t> width("width");
    Param<uint8_t> thresh("thresh");
    Param<float> frac("frac");
    // Named so that it will come last, to simplify test.
    Param<float> z_ignored("z_ignored");

    Var x("x"), y("y"), c("c");

    Func f("f");
    f(x, y, c) = frac * (input1(clamp(x, 0, height), clamp(y, 0, width), c) +
                    min(thresh, input2(x, y))) + (0 * z_ignored);
    return f;
}

int main(int argc, char **argv) {

#define EXPECT(expect, actual) \
    if (expect != actual) { printf("Failure, expected %s\n", #expect); return -1; }

    for (int i = 0; i < 2; ++i) {
        Func f = Build();

        bool use_lowered = (i != 0);
        std::vector<Argument> args = f.infer_arguments(use_lowered);
        if (use_lowered) {
            EXPECT(6, args.size());
        } else {
            EXPECT(7, args.size());
        }

        EXPECT("input1", args[0].name);
        EXPECT("input2", args[1].name);
        EXPECT("frac", args[2].name);
        EXPECT("height", args[3].name);
        EXPECT("thresh", args[4].name);
        EXPECT("width", args[5].name);

        EXPECT(true, args[0].is_buffer);
        EXPECT(true, args[1].is_buffer);
        EXPECT(false, args[2].is_buffer);
        EXPECT(false, args[3].is_buffer);
        EXPECT(false, args[4].is_buffer);
        EXPECT(false, args[5].is_buffer);

        EXPECT(Type::Float, args[2].type.code);
        EXPECT(Type::Int, args[3].type.code);
        EXPECT(Type::UInt, args[4].type.code);
        EXPECT(Type::Int, args[5].type.code);

        EXPECT(32, args[2].type.bits);
        EXPECT(32, args[3].type.bits);
        EXPECT(8, args[4].type.bits);
        EXPECT(32, args[5].type.bits);

        if (!use_lowered) {
            EXPECT("z_ignored", args[6].name);
            EXPECT(false, args[6].is_buffer);
            EXPECT(Type::Float, args[6].type.code);
            EXPECT(32, args[6].type.bits);
        }
    }

    printf("Success!\n");
    return 0;

}
<|endoftext|>


<commit_before>#include <iostream>
#include <opencv2/opencv.hpp>

#include "DB.hpp"
#include "Image.hpp"

int main()
{
	// Setup directory and folder paths, no recursive solution yet

	// ----> Directory for: KRISTOFER <-----
	//string mainDirectory = "C:/Users/StoffesBok/Bilddatabaser_TNM025/dataset/";
	//cv::Mat image_temp = imread("C:/Users/StoffesBok/Bilddatabaser_TNM025/dataset/zlatan/zlatan_blue_background_1920x1080.jpg", 1);

	// ----> Directory for: GABRIEL <-----
	cv::Mat image_temp = imread("C:/Users/Gabriel/Desktop/Bildatabaser/Bilddatabaser_TNM025/dataset/zlatan/zlatan_blue_background_1920x1080.jpg", 1);
	string mainDirectory = "C:/Users/Gabriel/Desktop/Bildatabaser/Bilddatabaser_TNM025/dataset/";
	char a;
	if (!image_temp.data){
		cout << "Zlatan is too big!" << endl; return -1;
	}

	vector<string> inputFolders = { "animal2", "beach2", "cat2", "colorful2",
								    "doll2", "elegant2", "flower2", "food2", "formal2", "garden2" };
	vector<string> animalFolder = { "animal2" };

	// Initilize the database
	DB database = DB();
	database.loadImages(mainDirectory, inputFolders);

	DB zlatan_DB = DB(image_temp, 32);
	zlatan_DB.reconstructImageFromDB(database);

	// A test for color histogram
	/*Mat src = imread("test.png", 1)
	cout << "Total: " << src.total() << endl;

	int r_bins = 2;
	int g_bins = 2;
	int b_bins = 2;
	const int hist_size[] = { r_bins, g_bins, b_bins };

	float r_range[] = { 0, 255 };
	float g_range[] = { 0, 255 };
	float b_range[] = { 0, 255 };
	const float *hist_range[] = { r_range, g_range, b_range };

	cv::Mat histos;

	bool uniform = true;
	bool accumulate = false;
	int channels[] = { 0, 1, 2 };
	// Check if channels and dims is correct
	calcHist(&src, 1, channels, Mat(), histos, 3, hist_size, hist_range, uniform, accumulate);

	//cout << "size" << histos.size[0] << endl;
	//cout << " x " << histos.size[1] << endl;
	//cout << " x " << histos.size[2] << endl;

	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 2; j++)
		{
			for (int k = 0; k < 2; k++)
			{
				cout << "B: " << i << endl;
				cout << "G: " << j << endl;
				cout << "R: " << k << endl;
				cout << histos.at<Vec3b>(i, j, k) << " " << endl;
			}
		}

	}
	*/

	system("pause");
	return 0;
}<commit_msg>Fixed a minor typo where Zlatan was not loaded correctly.<commit_after>#include <iostream>
#include <opencv2/opencv.hpp>

#include "DB.hpp"
#include "Image.hpp"

int main()
{
	// Setup directory and folder paths, no recursive solution yet
	string image_name = "zlatan_blue_background_1920x1080.jpg";

	// ----> Directory for: KRISTOFER <-----
	string mainDirectory = "C:/Users/StoffesBok/Bilddatabaser_TNM025/dataset/";
	cv::Mat image_temp = imread("C:/Users/StoffesBok/Bilddatabaser_TNM025/dataset/zlatan/" + image_name, 1);

	// ----> Directory for: GABRIEL <-----
	//string mainDirectory = "C:/Users/Gabriel/Desktop/Bildatabaser/Bilddatabaser_TNM025/dataset/";
	//cv::Mat image_temp = imread("C:/Users/Gabriel/Desktop/Bildatabaser/Bilddatabaser_TNM025/dataset/zlatan/" + image_name, 1);

	if (!image_temp.data){
		cout << "Zlatan is too big!" << endl; return -1;
	}

	vector<string> inputFolders = { "animal2", "beach2", "cat2", "colorful2",
								    "doll2", "elegant2", "flower2", "food2", "formal2", "garden2" };
	vector<string> animalFolder = { "animal2" };

	// Initilize the database
	DB database = DB();
	database.loadImages(mainDirectory, inputFolders);

	DB zlatan_DB = DB(image_temp, 32);
	zlatan_DB.reconstructImageFromDB(database, image_name);

	// A test for color histogram
	/*Mat src = imread("test.png", 1)
	cout << "Total: " << src.total() << endl;

	int r_bins = 2;
	int g_bins = 2;
	int b_bins = 2;
	const int hist_size[] = { r_bins, g_bins, b_bins };

	float r_range[] = { 0, 255 };
	float g_range[] = { 0, 255 };
	float b_range[] = { 0, 255 };
	const float *hist_range[] = { r_range, g_range, b_range };

	cv::Mat histos;

	bool uniform = true;
	bool accumulate = false;
	int channels[] = { 0, 1, 2 };
	// Check if channels and dims is correct
	calcHist(&src, 1, channels, Mat(), histos, 3, hist_size, hist_range, uniform, accumulate);

	//cout << "size" << histos.size[0] << endl;
	//cout << " x " << histos.size[1] << endl;
	//cout << " x " << histos.size[2] << endl;

	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 2; j++)
		{
			for (int k = 0; k < 2; k++)
			{
				cout << "B: " << i << endl;
				cout << "G: " << j << endl;
				cout << "R: " << k << endl;
				cout << histos.at<Vec3b>(i, j, k) << " " << endl;
			}
		}

	}
	*/

	system("pause");
	return 0;
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: StyleSheetTable.hxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-05 16:53:53 $
 *
 *  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 INCLUDED_STYLESHEETTABLE_HXX
#define INCLUDED_STYLESHEETTABLE_HXX

#include <WriterFilterDllApi.hxx>
#include <dmapper/DomainMapper.hxx>
#include <com/sun/star/lang/XComponent.hpp>
#include <PropertyMap.hxx>
#include <FontTable.hxx>
#include <resourcemodel/WW8ResourceModel.hxx>

namespace com{ namespace sun { namespace star { namespace text{
    class XTextDocument;
}}}}

namespace writerfilter {
namespace dmapper
{

enum StyleType
{
    STYLE_TYPE_UNKNOWN,
    STYLE_TYPE_PARA,
    STYLE_TYPE_CHAR,
    STYLE_TYPE_TABLE,
    STYLE_LIST
};

struct StyleSheetTable_Impl;
struct StyleSheetEntry
{
    ::rtl::OUString sStyleIdentifierI;
    ::rtl::OUString sStyleIdentifierD;
    bool            bIsDefaultStyle;
    bool            bInvalidHeight;
    bool            bHasUPE; //universal property expansion
    StyleType       nStyleTypeCode; //sgc
    ::rtl::OUString sBaseStyleIdentifier;
    ::rtl::OUString sNextStyleIdentifier;
    ::rtl::OUString sStyleName;
    ::rtl::OUString sStyleName1;
    PropertyMapPtr  pProperties;
    ::rtl::OUString sConvertedStyleName;
    StyleSheetEntry();
};
class DomainMapper;
class WRITERFILTER_DLLPRIVATE StyleSheetTable :
        public Properties,
        public Table
{
    StyleSheetTable_Impl   *m_pImpl;

public:
    StyleSheetTable( DomainMapper& rDMapper,
                        ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextDocument> xTextDocument );
    virtual ~StyleSheetTable();

    // Properties
    virtual void attribute(Id Name, Value & val);
    virtual void sprm(Sprm & sprm);

    // Table
    virtual void entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref);

    void ApplyStyleSheets( FontTablePtr rFontTable );
    const StyleSheetEntry* FindStyleSheetByISTD(const ::rtl::OUString& sIndex);
    const StyleSheetEntry* FindStyleSheetByStyleName(const ::rtl::OUString& rIndex);
    const StyleSheetEntry* FindStyleSheetByConvertedStyleName(const ::rtl::OUString& rIndex);
    // returns the parent of the one with the given name - if empty the parent of the current style sheet is returned
    const StyleSheetEntry* FindParentStyleSheet(::rtl::OUString sBaseStyle);

    ::rtl::OUString ConvertStyleName( const ::rtl::OUString& rWWName, bool bExtendedSearch = false );
    ::rtl::OUString GetStyleIdFromIndex(const sal_uInt32 sti);

    ::rtl::OUString getOrCreateCharStyle( PropertyValueVector_t& rCharProperties );

private:
    void resolveAttributeProperties(Value & val);
    void resolveSprmProps(Sprm & sprm_);
    void applyDefaults(bool bParaProperties);
};
typedef boost::shared_ptr< StyleSheetTable >    StyleSheetTablePtr;

}}

#endif //
<commit_msg>INTEGRATION: CWS changefileheader (1.15.4); FILE MERGED 2008/03/28 15:53:00 rt 1.15.4.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: StyleSheetTable.hxx,v $
 * $Revision: 1.16 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef INCLUDED_STYLESHEETTABLE_HXX
#define INCLUDED_STYLESHEETTABLE_HXX

#include <WriterFilterDllApi.hxx>
#include <dmapper/DomainMapper.hxx>
#include <com/sun/star/lang/XComponent.hpp>
#include <PropertyMap.hxx>
#include <FontTable.hxx>
#include <resourcemodel/WW8ResourceModel.hxx>

namespace com{ namespace sun { namespace star { namespace text{
    class XTextDocument;
}}}}

namespace writerfilter {
namespace dmapper
{

enum StyleType
{
    STYLE_TYPE_UNKNOWN,
    STYLE_TYPE_PARA,
    STYLE_TYPE_CHAR,
    STYLE_TYPE_TABLE,
    STYLE_LIST
};

struct StyleSheetTable_Impl;
struct StyleSheetEntry
{
    ::rtl::OUString sStyleIdentifierI;
    ::rtl::OUString sStyleIdentifierD;
    bool            bIsDefaultStyle;
    bool            bInvalidHeight;
    bool            bHasUPE; //universal property expansion
    StyleType       nStyleTypeCode; //sgc
    ::rtl::OUString sBaseStyleIdentifier;
    ::rtl::OUString sNextStyleIdentifier;
    ::rtl::OUString sStyleName;
    ::rtl::OUString sStyleName1;
    PropertyMapPtr  pProperties;
    ::rtl::OUString sConvertedStyleName;
    StyleSheetEntry();
};
class DomainMapper;
class WRITERFILTER_DLLPRIVATE StyleSheetTable :
        public Properties,
        public Table
{
    StyleSheetTable_Impl   *m_pImpl;

public:
    StyleSheetTable( DomainMapper& rDMapper,
                        ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextDocument> xTextDocument );
    virtual ~StyleSheetTable();

    // Properties
    virtual void attribute(Id Name, Value & val);
    virtual void sprm(Sprm & sprm);

    // Table
    virtual void entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref);

    void ApplyStyleSheets( FontTablePtr rFontTable );
    const StyleSheetEntry* FindStyleSheetByISTD(const ::rtl::OUString& sIndex);
    const StyleSheetEntry* FindStyleSheetByStyleName(const ::rtl::OUString& rIndex);
    const StyleSheetEntry* FindStyleSheetByConvertedStyleName(const ::rtl::OUString& rIndex);
    // returns the parent of the one with the given name - if empty the parent of the current style sheet is returned
    const StyleSheetEntry* FindParentStyleSheet(::rtl::OUString sBaseStyle);

    ::rtl::OUString ConvertStyleName( const ::rtl::OUString& rWWName, bool bExtendedSearch = false );
    ::rtl::OUString GetStyleIdFromIndex(const sal_uInt32 sti);

    ::rtl::OUString getOrCreateCharStyle( PropertyValueVector_t& rCharProperties );

private:
    void resolveAttributeProperties(Value & val);
    void resolveSprmProps(Sprm & sprm_);
    void applyDefaults(bool bParaProperties);
};
typedef boost::shared_ptr< StyleSheetTable >    StyleSheetTablePtr;

}}

#endif //
<|endoftext|>


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

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

    Kleopatra is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Kleopatra is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

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

#include "refreshkeyscommand.h"
#include "command_p.h"
#include <models/keycache.h>

#include <gpgme++/key.h>
#include <gpgme++/keylistresult.h>

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

#include <QStringList>

#include <cassert>

using namespace Kleo;

class RefreshKeysCommand::Private : public Command::Private {
    friend class ::Kleo::RefreshKeysCommand;
public:
    Private( RefreshKeysCommand * qq, Mode mode, KeyListController* controller );
    ~Private();
    enum KeyType {
        PublicKeys,
        SecretKeys
    };
    void startKeyListing( const char* backend, KeyType type );
    void publicKeyListingDone( const GpgME::KeyListResult& result );
    void secretKeyListingDone( const GpgME::KeyListResult& result );

    void addKey( const GpgME::Key& key );

private:
    const Mode mode;
    uint m_pubKeysJobs;
    uint m_secKeysJobs;
};

RefreshKeysCommand::Private * RefreshKeysCommand::d_func() { return static_cast<Private*>( d.get() ); }
const RefreshKeysCommand::Private * RefreshKeysCommand::d_func() const { return static_cast<const Private*>( d.get() ); }

RefreshKeysCommand::RefreshKeysCommand( Mode mode, KeyListController * p )
    : Command( p, new Private( this, mode, p ) )
{

}

RefreshKeysCommand::RefreshKeysCommand( Mode mode, QAbstractItemView * v, KeyListController * p )
    : Command( v, p, new Private( this, mode, p ) )
{

}

RefreshKeysCommand::~RefreshKeysCommand() {}

RefreshKeysCommand::Private::Private( RefreshKeysCommand * qq, Mode m, KeyListController * controller )
    : Command::Private( qq, controller ),
      mode( m ),
      m_pubKeysJobs( 0 ),
      m_secKeysJobs( 0 )
{

}

RefreshKeysCommand::Private::~Private() {}

void RefreshKeysCommand::Private::startKeyListing( const char* backend, KeyType type )
{
    const Kleo::CryptoBackend::Protocol * const protocol = Kleo::CryptoBackendFactory::instance()->protocol( backend );
    if ( !protocol )
        return;
    Kleo::KeyListJob * const job = protocol->keyListJob( /*remote*/false, /*includeSigs*/false, mode == Validate );
    if ( !job )
        return;
    if ( type == PublicKeys ) {
        connect( job, SIGNAL(result(GpgME::KeyListResult)),
                 q, SLOT(publicKeyListingDone(GpgME::KeyListResult)) );
    } else {
        connect( job, SIGNAL(result(GpgME::KeyListResult)),
                 q, SLOT(secretKeyListingDone(GpgME::KeyListResult)) );
    }
    connect( job, SIGNAL(progress(QString,int,int)),
             q, SIGNAL(progress(QString,int,int)) );
    connect( job, SIGNAL(nextKey(GpgME::Key)),
             q, SLOT(addKey(GpgME::Key)) );
    job->start( QStringList(), type == SecretKeys );
    ++( type == PublicKeys ? m_pubKeysJobs : m_secKeysJobs );
}

void RefreshKeysCommand::Private::publicKeyListingDone( const GpgME::KeyListResult & )
{
    assert( m_pubKeysJobs > 0 );
    --m_pubKeysJobs;
    if ( m_pubKeysJobs == 0 )
    {
        startKeyListing( "openpgp", Private::SecretKeys );
        startKeyListing( "smime", Private::SecretKeys );
    }
}

void RefreshKeysCommand::Private::secretKeyListingDone( const GpgME::KeyListResult & )
{
    assert( m_secKeysJobs > 0 );
    --m_secKeysJobs;
    if ( m_secKeysJobs == 0 )
    {
    }
}

void RefreshKeysCommand::Private::addKey( const GpgME::Key& key )
{
    if ( key.hasSecret() ) // ### hope this is ok. It is, after all, why we need the split in the first place...
        SecretKeyCache::mutableInstance()->insert( key );
    else
        PublicKeyCache::mutableInstance()->insert( key );
}

#define d d_func()

void RefreshKeysCommand::doStart() {
    /* NOTE: first fetch public keys. when done, fetch secret keys. hasSecret() works only
       correctly when the key was retrieved with --list-secret-keys (secretOnly flag
       in gpgme keylist operations) so we overwrite the key from --list-keys (secret
       not set) with the one from --list-secret-keys (with secret set).
    */
    d->startKeyListing( "openpgp", Private::PublicKeys );
    d->startKeyListing( "smime", Private::PublicKeys );
}

void RefreshKeysCommand::doCancel() {
}

#undef d

#include "moc_refreshkeyscommand.cpp"
<commit_msg>Don't forget to emit finished (using Command::Private::finished() hook.<commit_after>/* -*- mode: c++; c-basic-offset:4 -*-
    refreshkeyscommand.cpp

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

    Kleopatra is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Kleopatra is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

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

#include "refreshkeyscommand.h"
#include "command_p.h"
#include <models/keycache.h>

#include <gpgme++/key.h>
#include <gpgme++/keylistresult.h>

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

#include <QStringList>

#include <cassert>

using namespace Kleo;

class RefreshKeysCommand::Private : public Command::Private {
    friend class ::Kleo::RefreshKeysCommand;
public:
    Private( RefreshKeysCommand * qq, Mode mode, KeyListController* controller );
    ~Private();
    enum KeyType {
        PublicKeys,
        SecretKeys
    };
    void startKeyListing( const char* backend, KeyType type );
    void publicKeyListingDone( const GpgME::KeyListResult& result );
    void secretKeyListingDone( const GpgME::KeyListResult& result );

    void addKey( const GpgME::Key& key );

private:
    const Mode mode;
    uint m_pubKeysJobs;
    uint m_secKeysJobs;
};

RefreshKeysCommand::Private * RefreshKeysCommand::d_func() { return static_cast<Private*>( d.get() ); }
const RefreshKeysCommand::Private * RefreshKeysCommand::d_func() const { return static_cast<const Private*>( d.get() ); }

RefreshKeysCommand::RefreshKeysCommand( Mode mode, KeyListController * p )
    : Command( p, new Private( this, mode, p ) )
{

}

RefreshKeysCommand::RefreshKeysCommand( Mode mode, QAbstractItemView * v, KeyListController * p )
    : Command( v, p, new Private( this, mode, p ) )
{

}

RefreshKeysCommand::~RefreshKeysCommand() {}

RefreshKeysCommand::Private::Private( RefreshKeysCommand * qq, Mode m, KeyListController * controller )
    : Command::Private( qq, controller ),
      mode( m ),
      m_pubKeysJobs( 0 ),
      m_secKeysJobs( 0 )
{

}

RefreshKeysCommand::Private::~Private() {}

void RefreshKeysCommand::Private::startKeyListing( const char* backend, KeyType type )
{
    const Kleo::CryptoBackend::Protocol * const protocol = Kleo::CryptoBackendFactory::instance()->protocol( backend );
    if ( !protocol )
        return;
    Kleo::KeyListJob * const job = protocol->keyListJob( /*remote*/false, /*includeSigs*/false, mode == Validate );
    if ( !job )
        return;
    if ( type == PublicKeys ) {
        connect( job, SIGNAL(result(GpgME::KeyListResult)),
                 q, SLOT(publicKeyListingDone(GpgME::KeyListResult)) );
    } else {
        connect( job, SIGNAL(result(GpgME::KeyListResult)),
                 q, SLOT(secretKeyListingDone(GpgME::KeyListResult)) );
    }
    connect( job, SIGNAL(progress(QString,int,int)),
             q, SIGNAL(progress(QString,int,int)) );
    connect( job, SIGNAL(nextKey(GpgME::Key)),
             q, SLOT(addKey(GpgME::Key)) );
    job->start( QStringList(), type == SecretKeys );
    ++( type == PublicKeys ? m_pubKeysJobs : m_secKeysJobs );
}

void RefreshKeysCommand::Private::publicKeyListingDone( const GpgME::KeyListResult & )
{
    assert( m_pubKeysJobs > 0 );
    --m_pubKeysJobs;
    if ( m_pubKeysJobs == 0 ) {
        startKeyListing( "openpgp", Private::SecretKeys );
        startKeyListing( "smime", Private::SecretKeys );
    }
}

void RefreshKeysCommand::Private::secretKeyListingDone( const GpgME::KeyListResult & )
{
    assert( m_secKeysJobs > 0 );
    --m_secKeysJobs;
    if ( m_secKeysJobs == 0 )
        finished();
}

void RefreshKeysCommand::Private::addKey( const GpgME::Key& key )
{
    if ( key.hasSecret() ) // ### hope this is ok. It is, after all, why we need the split in the first place...
        SecretKeyCache::mutableInstance()->insert( key );
    else
        PublicKeyCache::mutableInstance()->insert( key );
}

#define d d_func()

void RefreshKeysCommand::doStart() {
    /* NOTE: first fetch public keys. when done, fetch secret keys. hasSecret() works only
       correctly when the key was retrieved with --list-secret-keys (secretOnly flag
       in gpgme keylist operations) so we overwrite the key from --list-keys (secret
       not set) with the one from --list-secret-keys (with secret set).
    */
    d->startKeyListing( "openpgp", Private::PublicKeys );
    d->startKeyListing( "smime", Private::PublicKeys );
}

void RefreshKeysCommand::doCancel() {
}

#undef d

#include "moc_refreshkeyscommand.cpp"
<|endoftext|>


<commit_before>/*
Copyright 2015 University of Auckland

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.Some license of other
*/

#include "gtest/gtest.h"

#include <libcellml>

TEST(Variable, serialise) {
    const std::string e = "<variable/>";
    libcellml::Variable v;
    std::string a = v.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, setValidVariableName) {
    const std::string in = "valid_name";
    const std::string e = "<variable name=\"" + in + "\"/>";
    libcellml::Variable v;
    v.setName(in);
    std::string a = v.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, setInvalidVariableName) {
    const std::string in = "invalid name";
    const std::string e = "<variable name=\"" + in + "\"/>";
    libcellml::Variable v;
    v.setName(in);
    std::string a = v.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, getValidVariableName) {
    const std::string in = "valid_name";
    const std::string e = in;
    libcellml::Variable v;
    v.setName(in);
    std::string a = v.getName();
    EXPECT_EQ(e, a);
}

TEST(Variable, getInvalidVariableName) {
    const std::string in = "invalid name";
    const std::string e = in;
    libcellml::Variable v;
    v.setName(in);
    std::string a = v.getName();
    EXPECT_EQ(e, a);
}

TEST(Variable, setUnits) {
    const std::string in = "dimensionless";
    const std::string e = "<variable units=\"" + in + "\"/>";
    libcellml::Variable v;

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName(in);
    v.setUnits(u);

    std::string a = v.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, setUnitsAndName) {
    const std::string in = "valid_name";
    const std::string e = "<variable name=\"" + in + "\" units=\"dimensionless\"/>";
    libcellml::Variable v;
    v.setName(in);

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("dimensionless");
    v.setUnits(u);

    std::string a = v.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, addVariable) {
    const std::string in = "valid_name";
    const std::string e =
            "<component name=\"" + in + "\">"
                "<variable name=\"" + in + "\" units=\"dimensionless\"/>"
              "</component>";

    libcellml::Component c;
    c.setName(in);

    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();
    v->setName(in);
    c.addVariable(v);

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("dimensionless");
    v->setUnits(u);

    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, addVariableToUnnamedComponent) {
    const std::string in = "valid_name";
    const std::string e =
            "<component>"
                "<variable name=\"" + in + "\"/>"
             "</component>";

    libcellml::Component c;

    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();
    v->setName(in);
    c.addVariable(v);

    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, addTwoVariables) {
    const std::string in = "valid_name";
    const std::string e =
            "<component name=\"" + in + "\">"
                "<variable name=\"variable1\"/>"
                "<variable name=\"variable2\"/>"
            "</component>";

    libcellml::Component c;
    c.setName(in);

    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    v1->setName("variable1");
    c.addVariable(v1);

    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    v2->setName("variable2");
    c.addVariable(v2);

    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, addVariables) {
	const std::string e =
		"<component>"
            "<variable name=\"var1\" units=\"dimensionless\"/>"
            "<variable name=\"var2\"/>"
            "<variable name=\"var3\"/>"
		"</component>";

	libcellml::Component c;

	libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
	v1->setName("var1");
	libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
	v2->setName("var2");
	libcellml::VariablePtr v3 = std::make_shared<libcellml::Variable>();
	v3->setName("var3");
	c.addVariable(v1);
	c.addVariable(v2);
	c.addVariable(v3);

	libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
	u->setName("dimensionless");
	v1->setUnits(u);

	std::string a = c.serialise(libcellml::FORMAT_XML);
	EXPECT_EQ(e, a);
}

TEST(Variable, removeVariable) {
    const std::string in = "valid_name";
    const std::string e =
            "<component name=\"" + in + "\">"
                "<variable name=\"variable2\"/>"
            "</component>";

    libcellml::Component c;
    c.setName(in);

    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    v1->setName("variable1");
    c.addVariable(v1);

    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    v2->setName("variable2");
    c.addVariable(v2);

    c.removeVariable("variable1");
    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);

    EXPECT_THROW(c.removeVariable("BAD_NAME"), std::out_of_range);
}

TEST(Variable, getVariableMethods) {
    const std::string in = "valid_name";
    libcellml::Component c;
    c.setName(in);

    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    v1->setName("variable1");
    c.addVariable(v1);
    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    v2->setName("variable2");
    c.addVariable(v2);
    libcellml::VariablePtr v3 = std::make_shared<libcellml::Variable>();
    v3->setName("variable3");
    c.addVariable(v3);
    libcellml::VariablePtr v4 = std::make_shared<libcellml::Variable>();
    v4->setName("variable4");
    c.addVariable(v4);

    // Get by string
    libcellml::VariablePtr vMethod1 = c.getVariable("variable1");
    std::string a1 = vMethod1->getName();
    EXPECT_EQ("variable1", a1);

    // Get by index
    libcellml::VariablePtr vMethod2 = c.getVariable(1);
    std::string a2 = vMethod2->getName();
    EXPECT_EQ("variable2", a2);

    // Get const by string
    const libcellml::VariablePtr vMethod3 = static_cast<const libcellml::Component>(c).getVariable("variable3");
    std::string a3 = vMethod3->getName();
    EXPECT_EQ("variable3", a3);

    // Get const by index
    const libcellml::VariablePtr vMethod4 = static_cast<const libcellml::Component>(c).getVariable(3);
    std::string a4 = vMethod4->getName();
    EXPECT_EQ("variable4", a4);
}

TEST(Variable, modelValidVariableName) {
    const std::string in = "valid_name";
    const std::string e =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
              "<component name=\"" + in + "\">"
                "<variable name=\"" + in + "\" units=\"dimensionless\"/>"
              "</component>"
            "</model>";

    libcellml::Model m;

    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    c->setName(in);
    m.addComponent(c);

    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();
    v->setName(in);
    c->addVariable(v);

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("dimensionless");
    v->setUnits(u);

    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
    EXPECT_EQ("valid_name", v->getName());
}

TEST(Variable, modelInvalidVariableName) {
    const std::string in = "invalid name";
    const std::string e =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
              "<component name=\"" + in + "\">"
                "<variable name=\"" + in + "\" units=\"dimensionless\"/>"
              "</component>"
            "</model>";

    libcellml::Model m;

    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    c->setName(in);
    m.addComponent(c);

    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();
    v->setName(in);
    c->addVariable(v);

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("dimensionless");
    v->setUnits(u);

    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
    EXPECT_EQ("invalid name", v->getName());
}

TEST(Variable, modelInvalidUnitsName) {
    const std::string in = "valid_name";
    const std::string e =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
              "<component name=\"" + in + "\">"
                "<variable name=\"" + in + "\" units=\"invalid name\"/>"
              "</component>"
            "</model>";

    libcellml::Model m;

    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    c->setName(in);
    m.addComponent(c);

    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();
    v->setName(in);
    c->addVariable(v);

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("invalid name");
    v->setUnits(u);

    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
    EXPECT_EQ("invalid name", u->getName());
}

<commit_msg>add testing permutations to addVariables from variable serialisation bugfix<commit_after>/*
Copyright 2015 University of Auckland

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.Some license of other
*/

#include "gtest/gtest.h"

#include <libcellml>

TEST(Variable, serialise) {
    const std::string e = "<variable/>";
    libcellml::Variable v;
    std::string a = v.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, setValidVariableName) {
    const std::string in = "valid_name";
    const std::string e = "<variable name=\"" + in + "\"/>";
    libcellml::Variable v;
    v.setName(in);
    std::string a = v.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, setInvalidVariableName) {
    const std::string in = "invalid name";
    const std::string e = "<variable name=\"" + in + "\"/>";
    libcellml::Variable v;
    v.setName(in);
    std::string a = v.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, getValidVariableName) {
    const std::string in = "valid_name";
    const std::string e = in;
    libcellml::Variable v;
    v.setName(in);
    std::string a = v.getName();
    EXPECT_EQ(e, a);
}

TEST(Variable, getInvalidVariableName) {
    const std::string in = "invalid name";
    const std::string e = in;
    libcellml::Variable v;
    v.setName(in);
    std::string a = v.getName();
    EXPECT_EQ(e, a);
}

TEST(Variable, setUnits) {
    const std::string in = "dimensionless";
    const std::string e = "<variable units=\"" + in + "\"/>";
    libcellml::Variable v;

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName(in);
    v.setUnits(u);

    std::string a = v.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, setUnitsAndName) {
    const std::string in = "valid_name";
    const std::string e = "<variable name=\"" + in + "\" units=\"dimensionless\"/>";
    libcellml::Variable v;
    v.setName(in);

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("dimensionless");
    v.setUnits(u);

    std::string a = v.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, addVariable) {
    const std::string in = "valid_name";
    const std::string e =
            "<component name=\"" + in + "\">"
                "<variable name=\"" + in + "\" units=\"dimensionless\"/>"
              "</component>";

    libcellml::Component c;
    c.setName(in);

    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();
    v->setName(in);
    c.addVariable(v);

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("dimensionless");
    v->setUnits(u);

    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, addVariableToUnnamedComponent) {
    const std::string in = "valid_name";
    const std::string e =
            "<component>"
                "<variable name=\"" + in + "\"/>"
             "</component>";

    libcellml::Component c;

    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();
    v->setName(in);
    c.addVariable(v);

    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, addTwoVariables) {
    const std::string in = "valid_name";
    const std::string e =
            "<component name=\"" + in + "\">"
                "<variable name=\"variable1\"/>"
                "<variable name=\"variable2\"/>"
            "</component>";

    libcellml::Component c;
    c.setName(in);

    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    v1->setName("variable1");
    c.addVariable(v1);

    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    v2->setName("variable2");
    c.addVariable(v2);

    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
}

TEST(Variable, addVariables) {
	const std::string e =
		"<component>"
            "<variable name=\"var1\" units=\"dimensionless\"/>"
            "<variable name=\"var2\"/>"
            "<variable units=\"dimensionless\"/>"
            "<variable/>"
		"</component>";

	libcellml::Component c;

	libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
	v1->setName("var1");
	libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
	v2->setName("var2");
	libcellml::VariablePtr v3 = std::make_shared<libcellml::Variable>();
    libcellml::VariablePtr v4 = std::make_shared<libcellml::Variable>();
	c.addVariable(v1);
	c.addVariable(v2);
	c.addVariable(v3);
    c.addVariable(v4);

	libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
	u->setName("dimensionless");
	v1->setUnits(u);
    v3->setUnits(u);

	std::string a = c.serialise(libcellml::FORMAT_XML);
	EXPECT_EQ(e, a);
}

TEST(Variable, removeVariable) {
    const std::string in = "valid_name";
    const std::string e =
            "<component name=\"" + in + "\">"
                "<variable name=\"variable2\"/>"
            "</component>";

    libcellml::Component c;
    c.setName(in);

    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    v1->setName("variable1");
    c.addVariable(v1);

    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    v2->setName("variable2");
    c.addVariable(v2);

    c.removeVariable("variable1");
    std::string a = c.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);

    EXPECT_THROW(c.removeVariable("BAD_NAME"), std::out_of_range);
}

TEST(Variable, getVariableMethods) {
    const std::string in = "valid_name";
    libcellml::Component c;
    c.setName(in);

    libcellml::VariablePtr v1 = std::make_shared<libcellml::Variable>();
    v1->setName("variable1");
    c.addVariable(v1);
    libcellml::VariablePtr v2 = std::make_shared<libcellml::Variable>();
    v2->setName("variable2");
    c.addVariable(v2);
    libcellml::VariablePtr v3 = std::make_shared<libcellml::Variable>();
    v3->setName("variable3");
    c.addVariable(v3);
    libcellml::VariablePtr v4 = std::make_shared<libcellml::Variable>();
    v4->setName("variable4");
    c.addVariable(v4);

    // Get by string
    libcellml::VariablePtr vMethod1 = c.getVariable("variable1");
    std::string a1 = vMethod1->getName();
    EXPECT_EQ("variable1", a1);

    // Get by index
    libcellml::VariablePtr vMethod2 = c.getVariable(1);
    std::string a2 = vMethod2->getName();
    EXPECT_EQ("variable2", a2);

    // Get const by string
    const libcellml::VariablePtr vMethod3 = static_cast<const libcellml::Component>(c).getVariable("variable3");
    std::string a3 = vMethod3->getName();
    EXPECT_EQ("variable3", a3);

    // Get const by index
    const libcellml::VariablePtr vMethod4 = static_cast<const libcellml::Component>(c).getVariable(3);
    std::string a4 = vMethod4->getName();
    EXPECT_EQ("variable4", a4);
}

TEST(Variable, modelValidVariableName) {
    const std::string in = "valid_name";
    const std::string e =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
              "<component name=\"" + in + "\">"
                "<variable name=\"" + in + "\" units=\"dimensionless\"/>"
              "</component>"
            "</model>";

    libcellml::Model m;

    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    c->setName(in);
    m.addComponent(c);

    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();
    v->setName(in);
    c->addVariable(v);

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("dimensionless");
    v->setUnits(u);

    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
    EXPECT_EQ("valid_name", v->getName());
}

TEST(Variable, modelInvalidVariableName) {
    const std::string in = "invalid name";
    const std::string e =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
              "<component name=\"" + in + "\">"
                "<variable name=\"" + in + "\" units=\"dimensionless\"/>"
              "</component>"
            "</model>";

    libcellml::Model m;

    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    c->setName(in);
    m.addComponent(c);

    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();
    v->setName(in);
    c->addVariable(v);

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("dimensionless");
    v->setUnits(u);

    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
    EXPECT_EQ("invalid name", v->getName());
}

TEST(Variable, modelInvalidUnitsName) {
    const std::string in = "valid_name";
    const std::string e =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            "<model xmlns=\"http://www.cellml.org/cellml/1.2#\">"
              "<component name=\"" + in + "\">"
                "<variable name=\"" + in + "\" units=\"invalid name\"/>"
              "</component>"
            "</model>";

    libcellml::Model m;

    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    c->setName(in);
    m.addComponent(c);

    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();
    v->setName(in);
    c->addVariable(v);

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("invalid name");
    v->setUnits(u);

    std::string a = m.serialise(libcellml::FORMAT_XML);
    EXPECT_EQ(e, a);
    EXPECT_EQ("invalid name", u->getName());
}

<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2018 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/qtwidgets/properties/listpropertywidgetqt.h>
#include <modules/qtwidgets/inviwoqtutils.h>
#include <modules/qtwidgets/inviwowidgetsqt.h>

#include <inviwo/core/properties/compositeproperty.h>
#include <inviwo/core/properties/listproperty.h>
#include <inviwo/core/util/zip.h>

#include <warn/push>
#include <warn/ignore/all>
#include <QMenu>
#include <QAction>
#include <QToolButton>
#include <QHBoxLayout>
#include <warn/pop>

namespace inviwo {

ListPropertyWidgetQt::ListPropertyWidgetQt(ListProperty* property)
    : CompositePropertyWidgetQt(property), listProperty_(property) {

    setShowIfEmpty(true);

    // inject "add" button in the header of the composite property for adding list elements
    if (auto headerlayout = dynamic_cast<QHBoxLayout*>(layout()->itemAt(0)->layout())) {
        addItemButton_ = new QToolButton(this);
        QIcon icon;
        icon.addFile(":/stylesheets/images/addlistitem.png", QSize(), QIcon::Normal, QIcon::Off);
        icon.addFile(":/stylesheets/images/addlistitem_disabled.png", QSize(), QIcon::Disabled,
                     QIcon::Off);
        addItemButton_->setIcon(icon);
        addItemButton_->setObjectName("addListItemButton");
        addItemButton_->setToolTip("Add list element");

        connect(addItemButton_, &QToolButton::clicked, this, [&]() {
            if (listProperty_ && listProperty_->getPrefabCount() > 0) {
                if (listProperty_->getPrefabCount() == 1) {
                    listProperty_->addProperty(static_cast<size_t>(0));
                } else {
                    // show context menu since there exist more than one prefab in the list property
                    QMenu m;
                    for (auto&& item : util::enumerate(listProperty_->getPrefabs())) {
                        auto&& ind = get<0>(item);
                        auto&& elem = get<1>(item);

                        auto addAction = m.addAction(utilqt::toQString(elem->getDisplayName()));
                        addAction->setData(ind);
                    }

                    if (auto selectedAction = m.exec(QCursor::pos())) {
                        listProperty_->setInitiatingWidget(this);
                        listProperty_->addProperty(selectedAction->data().toUInt());
                        listProperty_->clearInitiatingWidget();
                    }
                }
            }
        });

        if (listProperty_) {
            addItemButton_->setVisible((listProperty_->getUIFlags() & ListPropertyUIFlag::Add) ==
                                       ListPropertyUIFlag::Add);

            // listProperty_->PropertyOwnerObservable::addObserver(this);
        }

        headerlayout->insertWidget(headerlayout->count() - 2, addItemButton_);
    }
}

void ListPropertyWidgetQt::updateFromProperty() {
    CompositePropertyWidgetQt::updateFromProperty();

    if (listProperty_) {
        addItemButton_->setEnabled(canAddElements());
    }
}

bool ListPropertyWidgetQt::isChildRemovable() const {
    return ((listProperty_->getUIFlags() & ListPropertyUIFlag::Remove) ==
            ListPropertyUIFlag::Remove);
}

std::unique_ptr<QMenu> ListPropertyWidgetQt::getContextMenu() {
    auto menu = PropertyWidgetQt::getContextMenu();

    if (listProperty_) {
        menu->addSeparator();

        if ((listProperty_->getUIFlags() & ListPropertyUIFlag::Add) == ListPropertyUIFlag::Add) {
            if (listProperty_->getPrefabCount() == 1) {
                auto addAction = menu->addAction(utilqt::toQString(
                    "Add " + listProperty_->getPrefabs().front()->getDisplayName()));
                connect(addAction, &QAction::triggered, this, [&]() {
                    listProperty_->setInitiatingWidget(this);
                    listProperty_->addProperty(static_cast<size_t>(0));
                    listProperty_->clearInitiatingWidget();
                });
            } else {
                auto addItemMenu = menu->addMenu("&Add Item");
                if (listProperty_->getPrefabCount() > 0) {
                    for (auto&& item : util::enumerate(listProperty_->getPrefabs())) {
                        auto&& ind = get<0>(item);
                        auto&& elem = get<1>(item);

                        auto addAction =
                            addItemMenu->addAction(utilqt::toQString(elem->getDisplayName()));
                        connect(addAction, &QAction::triggered, this, [&, index = ind ]() {
                            listProperty_->setInitiatingWidget(this);
                            listProperty_->addProperty(index);
                            listProperty_->clearInitiatingWidget();
                        });
                    }
                } else {  // no prefab objects available
                    auto action = addItemMenu->addAction("No templates available");
                    action->setEnabled(false);
                }

                // disable add item menu if list property is already fully filled
                const bool enable =
                    (listProperty_->getMaxNumberOfElements() == 0) ||
                    (listProperty_->size() < listProperty_->getMaxNumberOfElements());
                addItemMenu->setEnabled(enable);
            }
        }

        if ((listProperty_->getUIFlags() & ListPropertyUIFlag::Remove) ==
            ListPropertyUIFlag::Remove) {
            auto clearAction = menu->addAction(tr("&Clear Items"));
            connect(clearAction, &QAction::triggered, this, [&]() {
                listProperty_->setInitiatingWidget(this);
                listProperty_->clear();
                listProperty_->clearInitiatingWidget();
            });
        }

        menu->addSeparator();
    }

    return menu;
}
/*
void ListPropertyWidgetQt::onDidAddProperty(Property* property, size_t index) {
    addItemButton_->setEnabled(canAddElements());

    CompositePropertyWidgetQt::onDidAddProperty(property, index);
}

void ListPropertyWidgetQt::onDidRemoveProperty(Property* property, size_t index) {
    addItemButton_->setEnabled(canAddElements());

    CompositePropertyWidgetQt::onDidRemoveProperty(property, index);
}
*/
bool ListPropertyWidgetQt::canAddElements() const {
    return (listProperty_->getMaxNumberOfElements() == 0) ||
           (listProperty_->size() < listProperty_->getMaxNumberOfElements());
}

}  // namespace inviwo
<commit_msg>QtWidgets: gcc fix<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2018 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <modules/qtwidgets/properties/listpropertywidgetqt.h>
#include <modules/qtwidgets/inviwoqtutils.h>
#include <modules/qtwidgets/inviwowidgetsqt.h>

#include <inviwo/core/properties/compositeproperty.h>
#include <inviwo/core/properties/listproperty.h>
#include <inviwo/core/util/zip.h>

#include <warn/push>
#include <warn/ignore/all>
#include <QMenu>
#include <QAction>
#include <QToolButton>
#include <QHBoxLayout>
#include <warn/pop>

namespace inviwo {

ListPropertyWidgetQt::ListPropertyWidgetQt(ListProperty* property)
    : CompositePropertyWidgetQt(property), listProperty_(property) {

    setShowIfEmpty(true);

    // inject "add" button in the header of the composite property for adding list elements
    if (auto headerlayout = dynamic_cast<QHBoxLayout*>(layout()->itemAt(0)->layout())) {
        addItemButton_ = new QToolButton(this);
        QIcon icon;
        icon.addFile(":/stylesheets/images/addlistitem.png", QSize(), QIcon::Normal, QIcon::Off);
        icon.addFile(":/stylesheets/images/addlistitem_disabled.png", QSize(), QIcon::Disabled,
                     QIcon::Off);
        addItemButton_->setIcon(icon);
        addItemButton_->setObjectName("addListItemButton");
        addItemButton_->setToolTip("Add list element");

        connect(addItemButton_, &QToolButton::clicked, this, [&]() {
            if (listProperty_ && listProperty_->getPrefabCount() > 0) {
                if (listProperty_->getPrefabCount() == 1) {
                    listProperty_->addProperty(static_cast<size_t>(0));
                } else {
                    // show context menu since there exist more than one prefab in the list property
                    QMenu m;
                    for (auto&& item : util::enumerate(listProperty_->getPrefabs())) {
                        auto&& ind = get<0>(item);
                        auto&& elem = get<1>(item);

                        auto addAction = m.addAction(utilqt::toQString(elem->getDisplayName()));
                        addAction->setData(static_cast<uint>(ind));
                    }

                    if (auto selectedAction = m.exec(QCursor::pos())) {
                        listProperty_->setInitiatingWidget(this);
                        listProperty_->addProperty(selectedAction->data().toUInt());
                        listProperty_->clearInitiatingWidget();
                    }
                }
            }
        });

        if (listProperty_) {
            addItemButton_->setVisible((listProperty_->getUIFlags() & ListPropertyUIFlag::Add) ==
                                       ListPropertyUIFlag::Add);

            // listProperty_->PropertyOwnerObservable::addObserver(this);
        }

        headerlayout->insertWidget(headerlayout->count() - 2, addItemButton_);
    }
}

void ListPropertyWidgetQt::updateFromProperty() {
    CompositePropertyWidgetQt::updateFromProperty();

    if (listProperty_) {
        addItemButton_->setEnabled(canAddElements());
    }
}

bool ListPropertyWidgetQt::isChildRemovable() const {
    return ((listProperty_->getUIFlags() & ListPropertyUIFlag::Remove) ==
            ListPropertyUIFlag::Remove);
}

std::unique_ptr<QMenu> ListPropertyWidgetQt::getContextMenu() {
    auto menu = PropertyWidgetQt::getContextMenu();

    if (listProperty_) {
        menu->addSeparator();

        if ((listProperty_->getUIFlags() & ListPropertyUIFlag::Add) == ListPropertyUIFlag::Add) {
            if (listProperty_->getPrefabCount() == 1) {
                auto addAction = menu->addAction(utilqt::toQString(
                    "Add " + listProperty_->getPrefabs().front()->getDisplayName()));
                connect(addAction, &QAction::triggered, this, [&]() {
                    listProperty_->setInitiatingWidget(this);
                    listProperty_->addProperty(static_cast<size_t>(0));
                    listProperty_->clearInitiatingWidget();
                });
            } else {
                auto addItemMenu = menu->addMenu("&Add Item");
                if (listProperty_->getPrefabCount() > 0) {
                    for (auto&& item : util::enumerate(listProperty_->getPrefabs())) {
                        auto&& ind = get<0>(item);
                        auto&& elem = get<1>(item);

                        auto addAction =
                            addItemMenu->addAction(utilqt::toQString(elem->getDisplayName()));
                        connect(addAction, &QAction::triggered, this, [&, index = ind ]() {
                            listProperty_->setInitiatingWidget(this);
                            listProperty_->addProperty(index);
                            listProperty_->clearInitiatingWidget();
                        });
                    }
                } else {  // no prefab objects available
                    auto action = addItemMenu->addAction("No templates available");
                    action->setEnabled(false);
                }

                // disable add item menu if list property is already fully filled
                const bool enable =
                    (listProperty_->getMaxNumberOfElements() == 0) ||
                    (listProperty_->size() < listProperty_->getMaxNumberOfElements());
                addItemMenu->setEnabled(enable);
            }
        }

        if ((listProperty_->getUIFlags() & ListPropertyUIFlag::Remove) ==
            ListPropertyUIFlag::Remove) {
            auto clearAction = menu->addAction(tr("&Clear Items"));
            connect(clearAction, &QAction::triggered, this, [&]() {
                listProperty_->setInitiatingWidget(this);
                listProperty_->clear();
                listProperty_->clearInitiatingWidget();
            });
        }

        menu->addSeparator();
    }

    return menu;
}
/*
void ListPropertyWidgetQt::onDidAddProperty(Property* property, size_t index) {
    addItemButton_->setEnabled(canAddElements());

    CompositePropertyWidgetQt::onDidAddProperty(property, index);
}

void ListPropertyWidgetQt::onDidRemoveProperty(Property* property, size_t index) {
    addItemButton_->setEnabled(canAddElements());

    CompositePropertyWidgetQt::onDidRemoveProperty(property, index);
}
*/
bool ListPropertyWidgetQt::canAddElements() const {
    return (listProperty_->getMaxNumberOfElements() == 0) ||
           (listProperty_->size() < listProperty_->getMaxNumberOfElements());
}

}  // namespace inviwo
<|endoftext|>