<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 *
 * Modified by Cloudius Systems.
 * Copyright 2015 Cloudius Systems.
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <sstream>
#include <string>
#include <chrono>
#include <boost/algorithm/string.hpp>
#include <experimental/optional>
#include "production_snitch_base.hh"
#include "exceptions/exceptions.hh"
#include "service/storage_service.hh"
#include "core/file.hh"
#include "log.hh"

namespace locator {

/**
 * cassandra-rackdc.properties file has the following format:
 *
 * dc=<Data Center name>
 * rack=<Rack name>
 * prefer_local=<true|false>
 */
class gossiping_property_file_snitch : public production_snitch_base {
public:
    // Check the property file for changes every 60s.
    static constexpr timer<>::duration reload_property_file_period() {
        return std::chrono::seconds(60);
    }

    virtual void gossiper_starting() override;
    virtual future<> stop() override;
    virtual future<> start() override;
    virtual future<> pause_io() override;
    virtual void resume_io() override;
    virtual sstring get_name() const override {
        return "org.apache.cassandra.locator.GossipingPropertyFileSnitch";
    }

    gossiping_property_file_snitch(
        const sstring& fname = snitch_properties_filename,
        unsigned io_cpuid = 0);

private:
    void periodic_reader_callback();

    /**
     * Parse the property file and indicate the StorageService and a Gossiper if
     * there was a configuration change.
     *
     * @return a ready-future when we are done
     */
    future<> reload_configuration();

    /**
     * Check if the property file has been modified since the last time we
     * parsed it.
     *
     * @return TRUE if property file has been modified
     */
    future<bool> property_file_was_modified();

    /**
     * Read the propery file if it has changed since the last time we read it.
     */
    future<> read_property_file();

    /**
     * TODO: this function is expected to trigger a Gossiper to reconnect
     * according to the new "prefer_local" value, namely use either an internal
     * or extenal IP address.
     *
     * This is currently relevant to EC2/GCE(?) only.
     */
    void reload_gossiper_state();

    /**
     * Indicate that the snitch has stopped its I/O.
     */
    void set_stopped();

    future<> stop_io();
    void start_io();

private:
    timer<> _file_reader;
    std::experimental::optional<timespec> _last_file_mod;
    std::istringstream _istrm;
    bool _gossip_started = false;
    bool _prefer_local = false;
    bool _file_reader_runs = false;
    unsigned _file_reader_cpu_id;
};
} // namespace locator
<commit_msg>locator::gossiping_property_file_snitch: use empty string as a default config file name<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 *
 * Modified by Cloudius Systems.
 * Copyright 2015 Cloudius Systems.
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <sstream>
#include <string>
#include <chrono>
#include <boost/algorithm/string.hpp>
#include <experimental/optional>
#include "production_snitch_base.hh"
#include "exceptions/exceptions.hh"
#include "service/storage_service.hh"
#include "core/file.hh"
#include "log.hh"

namespace locator {

/**
 * cassandra-rackdc.properties file has the following format:
 *
 * dc=<Data Center name>
 * rack=<Rack name>
 * prefer_local=<true|false>
 */
class gossiping_property_file_snitch : public production_snitch_base {
public:
    // Check the property file for changes every 60s.
    static constexpr timer<>::duration reload_property_file_period() {
        return std::chrono::seconds(60);
    }

    virtual void gossiper_starting() override;
    virtual future<> stop() override;
    virtual future<> start() override;
    virtual future<> pause_io() override;
    virtual void resume_io() override;
    virtual sstring get_name() const override {
        return "org.apache.cassandra.locator.GossipingPropertyFileSnitch";
    }

    gossiping_property_file_snitch(
        const sstring& fname = "",
        unsigned io_cpuid = 0);

private:
    void periodic_reader_callback();

    /**
     * Parse the property file and indicate the StorageService and a Gossiper if
     * there was a configuration change.
     *
     * @return a ready-future when we are done
     */
    future<> reload_configuration();

    /**
     * Check if the property file has been modified since the last time we
     * parsed it.
     *
     * @return TRUE if property file has been modified
     */
    future<bool> property_file_was_modified();

    /**
     * Read the propery file if it has changed since the last time we read it.
     */
    future<> read_property_file();

    /**
     * TODO: this function is expected to trigger a Gossiper to reconnect
     * according to the new "prefer_local" value, namely use either an internal
     * or extenal IP address.
     *
     * This is currently relevant to EC2/GCE(?) only.
     */
    void reload_gossiper_state();

    /**
     * Indicate that the snitch has stopped its I/O.
     */
    void set_stopped();

    future<> stop_io();
    void start_io();

private:
    timer<> _file_reader;
    std::experimental::optional<timespec> _last_file_mod;
    std::istringstream _istrm;
    bool _gossip_started = false;
    bool _prefer_local = false;
    bool _file_reader_runs = false;
    unsigned _file_reader_cpu_id;
};
} // namespace locator
<|endoftext|>


<commit_before>/* * This file is part of meego-keyboard *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * 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
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "mreactionmaptester.h"

#include "mgconfitem_stub.h"
#include "mvirtualkeyboard.h"
#include "mvirtualkeyboardstyle.h"
#include "horizontalswitcher.h"
#include "keyevent.h"
#include "mimabstractkeyarea.h"
#include "layoutsmanager.h"
#include "symbolview.h"
#include "ut_symbolview.h"
#include "mplainwindow.h"
#include "utils.h"

#include <MApplication>
#include <MButton>
#include <MScene>
#include <MSceneManager>
#include <MSceneWindow>
#include <MTheme>

#include <QDir>
#include <QGraphicsLinearLayout>
#include <QSignalSpy>

namespace
{
    const QString InputMethodSettingName("/meegotouch/inputmethods/virtualkeyboard/layouts");
    const QString DefaultLayoutSettingName("/meegotouch/inputmethods/virtualkeyboard/layouts/default");
    const QString DefaultLayout("en_us.xml");

    const QString TargetSettingsName("/meegotouch/target/name");
    const QString DefaultTargetName("Default");

    const int SceneRotationTime = 1400;
} // namespace

Q_DECLARE_METATYPE(QList<QPoint>)
Q_DECLARE_METATYPE(HorizontalSwitcher::SwitchDirection)

void Ut_SymbolView::initTestCase()
{
    static int argc = 2;
    static char *app_name[2] = { (char *) "ut_symbolview",
                                 (char *) "-software" };

    disableQtPlugins();

    MGConfItem target(TargetSettingsName);
    target.set(DefaultTargetName); // this value is required by the theme daemon

    app = new MApplication(argc, app_name);
    style = new MVirtualKeyboardStyleContainer;
    style->initialize("MVirtualKeyboard", "MVirtualKeyboardView", 0);

    MGConfItem inputMethodSetting(InputMethodSettingName);

    QStringList langlist;
    langlist << "en_us.xml";
    inputMethodSetting.set(QVariant(langlist));

    MGConfItem defaultLayoutSetting(DefaultLayoutSettingName);
    defaultLayoutSetting.set(QVariant(DefaultLayout));

    LayoutsManager::createInstance();

    qRegisterMetaType<KeyEvent>("KeyEvent");

    new MPlainWindow;

    if ((*style)->paddingTop() <= 0) {
        QSKIP("This test is sipped due to incorrect value received from CSS", SkipAll);
    }
}

void Ut_SymbolView::cleanupTestCase()
{
    delete MPlainWindow::instance();
    LayoutsManager::destroyInstance();
    delete style;
    style = 0;
    delete app;
    app = 0;
}

void Ut_SymbolView::init()
{
    subject = new SymbolView(LayoutsManager::instance(), style, DefaultLayout);

    // Add to scene so reaction maps are drawn.
    // SymView needs scene window as parent so positions itself correctly
    // in the scene in portrait mode.
    parent = new MSceneWindow;
    MPlainWindow::instance()->sceneManager()->appearSceneWindowNow(parent);
    subject->setParentItem(parent);
}

void Ut_SymbolView::cleanup()
{
    // Make sure default stub is restored.
    gMReactionMapStub = &gDefaultMReactionMapStub;

    MPlainWindow::instance()->sceneManager()->appearSceneWindowNow(parent);
    subject->setParentItem(0);
    delete parent;
    delete subject;
    subject = 0;
}

void Ut_SymbolView::testReactiveButtonAreas_data()
{
    QTest::addColumn<int>("orientationAngle");

    // The following locations are supplementary to reactionmaptester's tests
    // and only required to check special cases.
    QTest::addColumn< QList<QPoint> >("transparentLocations");

    QList<QPoint> transparentLocationsLandscape;
    transparentLocationsLandscape
        << QPoint(1, -10) // transparent above symbol view
        << QPoint(600, -10); // transparent above symbol view

    QList<QPoint> transparentLocationsPortrait;
    transparentLocationsPortrait
        << QPoint(1, -10) // transparent above symbol view
        << QPoint(400, -10); // transparent above symbol view

    QTest::newRow("Angle 0") << 0 << transparentLocationsLandscape;
    QTest::newRow("Angle 90") << 90 << transparentLocationsPortrait;
}

void Ut_SymbolView::testReactiveButtonAreas()
{
    QFETCH(int, orientationAngle);
    QFETCH(QList<QPoint>, transparentLocations);

    rotateToAngle(static_cast<M::OrientationAngle>(orientationAngle));

    MReactionMapTester tester;
    gMReactionMapStub = &tester;

    QGraphicsView *view = MPlainWindow::instance();

    // Clear with transparent color
    gMReactionMapStub->setTransparentDrawingValue();
    gMReactionMapStub->setTransform(QTransform());
    gMReactionMapStub->fillRectangle(0, 0, gMReactionMapStub->width(), gMReactionMapStub->height());

    subject->showSymbolView();

    subject->paintReactionMap(MReactionMap::instance(view), view);

    // Check that all buttons are covered by reactive area
    QVERIFY(tester.testChildButtonReactiveAreas(view, subject));

    // Test the next tab also.
    subject->switchToNextPage();
    QTest::qWait(600);
    QVERIFY(!subject->pageSwitcher->isRunning());
    // After the switch the reactive areas should be updated.

    // Check that all buttons are covered by reactive area
    QVERIFY(tester.testChildButtonReactiveAreas(view, subject));

    // Following coordinates will be given in subject coordinates.
    gMReactionMapStub->setTransform(subject, view);

    foreach(const QPoint & pos, transparentLocations) {
        QCOMPARE(tester.colorAt(pos), MReactionMapTester::Transparent);
    }

    // Check locations that should be inactive. This test is really only for
    // testing that at least something is drawn inactive, and not only reactive
    // areas are drawn.
    const QRectF br(subject->boundingRect());
    QList<QPoint> inactiveLocations;
    inactiveLocations
            << QPoint(br.left(), br.center().y()) // Left margin
            << QPoint(br.right()-1, br.center().y()); // Right margin

    foreach(const QPointF & pos, inactiveLocations) {
        QCOMPARE(tester.colorAt(pos), MReactionMapTester::Inactive);
    }
}

void Ut_SymbolView::testReactiveWholeScreen_data()
{
    QTest::addColumn<int>("orientationAngle");

    QTest::newRow("Angle 0") << 0;
    QTest::newRow("Angle 90") << 90;
    QTest::newRow("Angle 180") << 180;
    QTest::newRow("Angle 270") << 270;
}

void Ut_SymbolView::testReactiveWholeScreen()
{
    QFETCH(int, orientationAngle);

    rotateToAngle(static_cast<M::OrientationAngle>(orientationAngle));

    MReactionMapTester tester;
    gMReactionMapStub = &tester;
    // Clear with transparent
    gMReactionMapStub->setTransparentDrawingValue();
    gMReactionMapStub->setTransform(QTransform());
    gMReactionMapStub->fillRectangle(0, 0, gMReactionMapStub->width(), gMReactionMapStub->height());

    subject->showSymbolView();

    subject->paintReactionMap(MReactionMap::instance(MPlainWindow::instance()), MPlainWindow::instance());

    const bool gridpass = tester.testReactionMapGrid(
                              MPlainWindow::instance(),
                              20, 50, subject->interactiveRegion(),
                              subject);

    QVERIFY(gridpass);

    gMReactionMapStub = &gDefaultMReactionMapStub;
}

void Ut_SymbolView::testOthers()
{
    //at least we should not crash
    subject->organizeContent();

    subject->hideSymbolView();
    subject->showSymbolView();
}

void Ut_SymbolView::testChangeToOpenMode()
{
    subject->showSymbolView();
    QVERIFY(subject->isActive() == true);
    subject->hideSymbolView();
    QVERIFY(subject->isActive() == false);
}

void Ut_SymbolView::testChangeTab_data()
{
    QTest::addColumn<int>("initialTabIndex");
    QTest::addColumn<HorizontalSwitcher::SwitchDirection>("direction");
    QTest::addColumn<int>("finalTabIndex"); // expected

    QTest::newRow("Next tab")   << 0 << HorizontalSwitcher::Right << 1;
    QTest::newRow("Prev tab")   << 1 << HorizontalSwitcher::Left << 0;
}

void Ut_SymbolView::testChangeTab()
{
    QFETCH(int, initialTabIndex);
    QFETCH(HorizontalSwitcher::SwitchDirection, direction);
    QFETCH(int, finalTabIndex);

    subject->pageSwitcher->setDuration(0);
    subject->pageSwitcher->setCurrent(initialTabIndex);

    QCOMPARE(subject->activePage, subject->pageSwitcher->current());

    if (direction == HorizontalSwitcher::Right) {
        subject->switchToNextPage();
    } else if (direction == HorizontalSwitcher::Left){
        subject->switchToPrevPage();
    }

    QCOMPARE(subject->activePage, finalTabIndex);
}

void Ut_SymbolView::testHideWithFlick_data()
{
    QTest::addColumn<int>("tabIndex");
    QTest::newRow("Sym tab") << 0;
    QTest::newRow("Ace tab") << 1;
}

void Ut_SymbolView::testHideWithFlick()
{
    QFETCH(int, tabIndex);
    QVERIFY(subject->pageSwitcher && subject->pageSwitcher->count() >= tabIndex);
    MImAbstractKeyArea *page = static_cast<MImAbstractKeyArea *>(subject->pageSwitcher->widget(tabIndex));

    // Using qtest rows we dont need to worry about symbol view's show/hide timers
    // ignoring the call because subject is re-created every time.
    subject->showSymbolView();
    QCOMPARE(subject->isActive(), true);
    emit page->flickDown();
    QCOMPARE(subject->isActive(), false);
}

void Ut_SymbolView::testSetLayout()
{
    // set an invalid layout, at least it won't crash
    // and still has the laste valid layout.
    QString oldLayout = subject->currentLayout;
    subject->setLayout("ThisLayoutShouldNotExist");
    QVERIFY(subject->currentLayout != "ThisLayoutShouldNotExist");
    QCOMPARE(subject->currentLayout, oldLayout);
}

void Ut_SymbolView::testHardwareState()
{
    subject->setKeyboardState(MInputMethod::OnScreen);
    QCOMPARE(subject->activeState, MInputMethod::OnScreen);

    // Make sure were in landscape mode when in hardware state
    rotateToAngle(M::Angle0);

    subject->setKeyboardState(MInputMethod::Hardware);
    QCOMPARE(subject->activeState, MInputMethod::Hardware);
}

void Ut_SymbolView::testSetTemporarilyHidden()
{
    QCOMPARE(subject->activity, SymbolView::Inactive);

    subject->setTemporarilyHidden(true);
    QCOMPARE(subject->activity, SymbolView::Inactive);

    subject->setTemporarilyHidden(false);
    QCOMPARE(subject->activity, SymbolView::Inactive);

    subject->showSymbolView();

    QTest::qWait(200);

    QCOMPARE(subject->activity, SymbolView::Active);

    subject->setTemporarilyHidden(false);
    QCOMPARE(subject->activity, SymbolView::Active);

    subject->setTemporarilyHidden(true);
    QCOMPARE(subject->activity, SymbolView::TemporarilyInactive);

    QTest::qWait(200);

    subject->setTemporarilyHidden(false);
    QCOMPARE(subject->activity, SymbolView::Active);
}

void Ut_SymbolView::rotateToAngle(M::OrientationAngle angle)
{
    subject->prepareToOrientationChange();
    MPlainWindow::instance()->setOrientationAngle(angle);
    QTest::qWait(SceneRotationTime);// wait until MSceneManager::orientationAngle() is updated.
    subject->finalizeOrientationChange();
}

QTEST_APPLESS_MAIN(Ut_SymbolView);
<commit_msg>Changes: Enable Ut_SymbolView test.<commit_after>/* * This file is part of meego-keyboard *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * 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
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "mreactionmaptester.h"

#include "mgconfitem_stub.h"
#include "mvirtualkeyboard.h"
#include "mvirtualkeyboardstyle.h"
#include "horizontalswitcher.h"
#include "keyevent.h"
#include "mimabstractkeyarea.h"
#include "layoutsmanager.h"
#include "regiontracker.h"
#include "symbolview.h"
#include "ut_symbolview.h"
#include "mplainwindow.h"
#include "utils.h"

#include <MApplication>
#include <MButton>
#include <MScene>
#include <MSceneManager>
#include <MSceneWindow>
#include <MTheme>

#include <QDir>
#include <QGraphicsLinearLayout>
#include <QSignalSpy>

namespace
{
    const QString InputMethodSettingName("/meegotouch/inputmethods/virtualkeyboard/layouts");
    const QString DefaultLayoutSettingName("/meegotouch/inputmethods/virtualkeyboard/layouts/default");
    const QString DefaultLayout("en_us.xml");

    const QString TargetSettingsName("/meegotouch/target/name");
    const QString DefaultTargetName("Default");

    const int SceneRotationTime = 1400;
} // namespace

Q_DECLARE_METATYPE(QList<QPoint>)
Q_DECLARE_METATYPE(HorizontalSwitcher::SwitchDirection)

void Ut_SymbolView::initTestCase()
{
    static int argc = 2;
    static char *app_name[2] = { (char *) "ut_symbolview",
                                 (char *) "-software" };

    disableQtPlugins();

    MGConfItem target(TargetSettingsName);
    target.set(DefaultTargetName); // this value is required by the theme daemon

    app = new MApplication(argc, app_name);
    style = new MVirtualKeyboardStyleContainer;
    style->initialize("MVirtualKeyboard", "MVirtualKeyboardView", 0);

    MGConfItem inputMethodSetting(InputMethodSettingName);

    QStringList langlist;
    langlist << "en_us.xml";
    inputMethodSetting.set(QVariant(langlist));

    LayoutsManager::createInstance();

    qRegisterMetaType<KeyEvent>("KeyEvent");

    new MPlainWindow;
    RegionTracker::createInstance();
}

void Ut_SymbolView::cleanupTestCase()
{
    RegionTracker::destroyInstance();
    delete MPlainWindow::instance();
    LayoutsManager::destroyInstance();
    delete style;
    style = 0;
    delete app;
    app = 0;
}

void Ut_SymbolView::init()
{
    subject = new SymbolView(LayoutsManager::instance(), style, DefaultLayout);

    // Add to scene so reaction maps are drawn.
    // SymView needs scene window as parent so positions itself correctly
    // in the scene in portrait mode.
    parent = new MSceneWindow;
    MPlainWindow::instance()->sceneManager()->appearSceneWindowNow(parent);
    subject->setParentItem(parent);
}

void Ut_SymbolView::cleanup()
{
    // Make sure default stub is restored.
    gMReactionMapStub = &gDefaultMReactionMapStub;

    MPlainWindow::instance()->sceneManager()->appearSceneWindowNow(parent);
    subject->setParentItem(0);
    delete parent;
    delete subject;
    subject = 0;
}

void Ut_SymbolView::testReactiveButtonAreas_data()
{
    QTest::addColumn<int>("orientationAngle");

    QTest::newRow("Angle 0") << 0;
    QTest::newRow("Angle 90") << 90;
}

void Ut_SymbolView::testReactiveButtonAreas()
{
    QFETCH(int, orientationAngle);;

    rotateToAngle(static_cast<M::OrientationAngle>(orientationAngle));

    MReactionMapTester tester;
    gMReactionMapStub = &tester;

    QGraphicsView *view = MPlainWindow::instance();

    // Clear with transparent color
    gMReactionMapStub->setTransparentDrawingValue();
    gMReactionMapStub->setTransform(QTransform());
    gMReactionMapStub->fillRectangle(0, 0, gMReactionMapStub->width(), gMReactionMapStub->height());

    subject->showSymbolView();

    subject->paintReactionMap(MReactionMap::instance(view), view);

    // Check that all buttons are covered by reactive area
    QVERIFY(tester.testChildButtonReactiveAreas(view, subject));

    // Test the next tab also.
    QSignalSpy reactionMapUpdate(&RegionTracker::instance(),
                                 SIGNAL(reactionMapUpdateNeeded()));
    subject->switchToNextPage();
    QTest::qWait(600);
    QVERIFY(!subject->pageSwitcher->isRunning());
    // After the switch the reactive areas should be updated.
    QVERIFY(reactionMapUpdate.count() >= 1);

    // However since we don't have MKeyboardHost here we call this directly again.
    gMReactionMapStub->setTransparentDrawingValue();
    gMReactionMapStub->setTransform(QTransform());
    gMReactionMapStub->fillRectangle(0, 0, gMReactionMapStub->width(), gMReactionMapStub->height());
    subject->paintReactionMap(MReactionMap::instance(view), view);

    // Check that all buttons are covered by reactive area
    QVERIFY(tester.testChildButtonReactiveAreas(view, subject));

    // Following coordinates will be given in subject coordinates.
    gMReactionMapStub->setTransform(subject, view);

    // Check locations that should be inactive. This test is really only for
    // testing that at least something is drawn inactive, and not only reactive
    // areas are drawn.
    const QRectF br(subject->boundingRect());
    QList<QPoint> inactiveLocations;
    inactiveLocations
            << QPoint(br.left(), br.center().y()) // Left margin
            << QPoint(br.right()-1, br.center().y()); // Right margin

    foreach(const QPointF & pos, inactiveLocations) {
        QCOMPARE(tester.colorAt(pos), MReactionMapTester::Inactive);
    }
}

void Ut_SymbolView::testReactiveWholeScreen_data()
{
    QTest::addColumn<int>("orientationAngle");

    QTest::newRow("Angle 0") << 0;
    QTest::newRow("Angle 90") << 90;
    QTest::newRow("Angle 180") << 180;
    QTest::newRow("Angle 270") << 270;
}

void Ut_SymbolView::testReactiveWholeScreen()
{
    QFETCH(int, orientationAngle);

    rotateToAngle(static_cast<M::OrientationAngle>(orientationAngle));

    MReactionMapTester tester;
    gMReactionMapStub = &tester;
    // Clear with transparent
    gMReactionMapStub->setTransparentDrawingValue();
    gMReactionMapStub->setTransform(QTransform());
    gMReactionMapStub->fillRectangle(0, 0, gMReactionMapStub->width(), gMReactionMapStub->height());

    subject->showSymbolView();

    subject->paintReactionMap(MReactionMap::instance(MPlainWindow::instance()), MPlainWindow::instance());

    const bool gridpass = tester.testReactionMapGrid(
                              MPlainWindow::instance(),
                              20, 50, subject->interactiveRegion(),
                              subject);

    QVERIFY(gridpass);

    gMReactionMapStub = &gDefaultMReactionMapStub;
}

void Ut_SymbolView::testOthers()
{
    //at least we should not crash
    subject->organizeContent();

    subject->hideSymbolView();
    subject->showSymbolView();
}

void Ut_SymbolView::testChangeToOpenMode()
{
    subject->showSymbolView();
    QVERIFY(subject->isActive() == true);
    subject->hideSymbolView();
    QVERIFY(subject->isActive() == false);
}

void Ut_SymbolView::testChangeTab_data()
{
    QTest::addColumn<int>("initialTabIndex");
    QTest::addColumn<HorizontalSwitcher::SwitchDirection>("direction");
    QTest::addColumn<int>("finalTabIndex"); // expected

    QTest::newRow("Next tab")   << 0 << HorizontalSwitcher::Right << 1;
    QTest::newRow("Prev tab")   << 1 << HorizontalSwitcher::Left << 0;
}

void Ut_SymbolView::testChangeTab()
{
    QFETCH(int, initialTabIndex);
    QFETCH(HorizontalSwitcher::SwitchDirection, direction);
    QFETCH(int, finalTabIndex);

    subject->pageSwitcher->setDuration(0);
    subject->pageSwitcher->setCurrent(initialTabIndex);

    QCOMPARE(subject->activePage, subject->pageSwitcher->current());

    if (direction == HorizontalSwitcher::Right) {
        subject->switchToNextPage();
    } else if (direction == HorizontalSwitcher::Left){
        subject->switchToPrevPage();
    }

    QCOMPARE(subject->activePage, finalTabIndex);
}

void Ut_SymbolView::testHideWithFlick_data()
{
    QTest::addColumn<int>("tabIndex");
    QTest::newRow("Sym tab") << 0;
    QTest::newRow("Ace tab") << 1;
}

void Ut_SymbolView::testHideWithFlick()
{
    QFETCH(int, tabIndex);
    QVERIFY(subject->pageSwitcher && subject->pageSwitcher->count() >= tabIndex);
    MImAbstractKeyArea *page = static_cast<MImAbstractKeyArea *>(subject->pageSwitcher->widget(tabIndex));

    // Using qtest rows we dont need to worry about symbol view's show/hide timers
    // ignoring the call because subject is re-created every time.
    subject->showSymbolView();
    QCOMPARE(subject->isActive(), true);
    emit page->flickDown();
    QCOMPARE(subject->isActive(), false);
}

void Ut_SymbolView::testSetLayout()
{
    // set an invalid layout, at least it won't crash
    // and still has the laste valid layout.
    QString oldLayout = subject->currentLayout;
    subject->setLayout("ThisLayoutShouldNotExist");
    QVERIFY(subject->currentLayout != "ThisLayoutShouldNotExist");
    QCOMPARE(subject->currentLayout, oldLayout);
}

void Ut_SymbolView::testHardwareState()
{
    subject->setKeyboardState(MInputMethod::OnScreen);
    QCOMPARE(subject->activeState, MInputMethod::OnScreen);

    // Make sure were in landscape mode when in hardware state
    rotateToAngle(M::Angle0);

    subject->setKeyboardState(MInputMethod::Hardware);
    QCOMPARE(subject->activeState, MInputMethod::Hardware);
}

void Ut_SymbolView::testSetTemporarilyHidden()
{
    QCOMPARE(subject->activity, SymbolView::Inactive);

    subject->setTemporarilyHidden(true);
    QCOMPARE(subject->activity, SymbolView::Inactive);

    subject->setTemporarilyHidden(false);
    QCOMPARE(subject->activity, SymbolView::Inactive);

    subject->showSymbolView();

    QTest::qWait(200);

    QCOMPARE(subject->activity, SymbolView::Active);

    subject->setTemporarilyHidden(false);
    QCOMPARE(subject->activity, SymbolView::Active);

    subject->setTemporarilyHidden(true);
    QCOMPARE(subject->activity, SymbolView::TemporarilyInactive);

    QTest::qWait(200);

    subject->setTemporarilyHidden(false);
    QCOMPARE(subject->activity, SymbolView::Active);
}

void Ut_SymbolView::rotateToAngle(M::OrientationAngle angle)
{
    subject->prepareToOrientationChange();
    MPlainWindow::instance()->setOrientationAngle(angle);
    QTest::qWait(SceneRotationTime);// wait until MSceneManager::orientationAngle() is updated.
    subject->finalizeOrientationChange();
}

QTEST_APPLESS_MAIN(Ut_SymbolView);
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: seinitializer_nssimpl.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: mmi $ $Date: 2004-07-23 04:53:50 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

/*
 * Turn off DEBUG Assertions
 */
#ifdef _DEBUG
    #define _DEBUG_WAS_DEFINED _DEBUG
    #undef _DEBUG
#else
    #undef _DEBUG_WAS_DEFINED
#endif

/*
 * and turn off the additional virtual methods which are part of some interfaces when compiled
 * with debug
 */
#ifdef DEBUG
    #define DEBUG_WAS_DEFINED DEBUG
    #undef DEBUG
#else
    #undef DEBUG_WAS_DEFINED
#endif

/*
 * header files needed for getCurrentProfilePath
 */
/*
#include "nsIServiceManager.h"
#include "nsIProfileInternal.h"
#include "nsString.h"
#include "nsEmbedAPI.h"
*/

#include <sal/types.h>

#include <tools/debug.hxx>

#include "seinitializer_nssimpl.hxx"

#include "securityenvironment_nssimpl.hxx"

#include "nspr.h"
#include "prtypes.h"
#include "pk11func.h"
#include "cert.h"
#include "cryptohi.h"
#include "certdb.h"
#include "nss.h"

namespace cssu = com::sun::star::uno;
namespace cssl = com::sun::star::lang;
namespace cssxc = com::sun::star::xml::crypto;

using namespace com::sun::star;

#define SERVICE_NAME "com.sun.star.xml.crypto.SEInitializer"
#define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.SEInitializer_NssImpl"
#define SECURITY_ENVIRONMENT "com.sun.star.xml.crypto.SecurityEnvironment"
#define SECURITY_CONTEXT "com.sun.star.xml.crypto.XMLSecurityContext"

/*
 * MM : get the current user profile
 */

// MM : By now, the XPCOM is initialized only once in the current thread, and it will
//      not be shutdown until StarOffice exits.
//      This is a bug, because any other component who will initialize the XPCOM afterward
//      will always fail.
//      This bug will be fixed when there is solution.
#if 0
static nsIServiceManager           *sServiceManager = nsnull;
static nsIDirectoryServiceProvider *appFileLocProvider = nsnull;
static NS_DEFINE_CID(kProfileCID, NS_PROFILE_CID);

char* getCurrentProfilePath( )
{
/*
        nsCOMPtr<nsILocalFile> binDir;

        // Note: if getenv() returns NULL, mozilla will default to using MOZILLA_FIVE_HOME in the NS_InitXPCOM2()
        // The NS_NewNativeLocalFile() will accept NULL as its first parameter.
        char * env = getenv("OPENOFFICE_MOZILLA_FIVE_HOME");
        if (env)
        {
        nsDependentCString sPath(env);
        nsresult rv = NS_NewNativeLocalFile(sPath, PR_TRUE, getter_AddRefs(binDir));
        if (NS_FAILED(rv))
            return NULL;
        }

    if (sServiceManager == nsnull)
    {
        NS_InitXPCOM2(&sServiceManager, binDir, appFileLocProvider);
    }

    if (!sServiceManager)
        return NULL;

    nsresult rv;
    nsCOMPtr< nsIProfile > theProfile = do_GetService( kProfileCID, &rv );
    if (NS_SUCCEEDED(rv))
    {
        nsXPIDLString profileName;
        rv = theProfile->GetCurrentProfile(getter_Copies(profileName));
        if (NS_SUCCEEDED(rv))
        {
            nsCOMPtr<nsIFile> curProfileDir;
            PRBool exists = PR_FALSE;
            nsCOMPtr<nsIProfileInternal> profileInternal=do_QueryInterface(theProfile);
            if (NS_SUCCEEDED(rv))
            {
                rv = profileInternal->GetProfileDir(profileName, getter_AddRefs(curProfileDir));
                if (NS_SUCCEEDED(rv))
                {
                    nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(curProfileDir));

                    nsAutoString path;
                    rv = localFile->GetPath(path);
                    if (NS_SUCCEEDED(rv))
                    {
                        char cs[1024];
                        path.ToCString(cs, 1024);

                        // MM : I can't shutdown, because the XPCom can't be initialized twice in
                        //      one program
                        //NS_RELEASE(sServiceManager);
                        //NS_ShutdownXPCOM(sServiceManager);

                        return (strdup(cs));
                    }
                }
            }
        }
    }

    // MM : I can't shutdown, because the XPCom can't be initialized twice in
    //      one program
    //NS_RELEASE(sServiceManager);
    //NS_ShutdownXPCOM(sServiceManager);
    */

    return NULL;
}

/*
 * get the current user profile (end)
 */

#endif

bool getMozillaCurrentProfile(rtl::OUString& profilePath);

SEInitializer_NssImpl::SEInitializer_NssImpl(
    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &rxMSF)
    :mxMSF( rxMSF )
{
}

SEInitializer_NssImpl::~SEInitializer_NssImpl()
{
}

/* XSEInitializer */
cssu::Reference< cssxc::XXMLSecurityContext > SAL_CALL
    SEInitializer_NssImpl::createSecurityContext(
    const rtl::OUString& sCertDB )
    throw (cssu::RuntimeException)
{
    CERTCertDBHandle*   pCertHandle = NULL ;
    PK11SlotInfo*       pSlot = NULL ;

    rtl::OString sCertDir;
    if( sCertDB.getLength() > 0 )
    {
        sCertDir = rtl::OString(sCertDB, sCertDB.getLength(), RTL_TEXTENCODING_ASCII_US);
    }
    else
    {
        rtl::OUString ouCertDir;
        if (!getMozillaCurrentProfile(ouCertDir))
        {
            return NULL;
        }

        sCertDir = rtl::OString(ouCertDir, ouCertDir.getLength(), RTL_TEXTENCODING_ASCII_US);

        DBG_ASSERT(0, sCertDir.getStr());
        /*
        char *pCurrentProfilePath = getCurrentProfilePath();

        if (pCurrentProfilePath == NULL)
        {
            return NULL;
        }
        else
        {
            sCertDir = rtl::OString(pCurrentProfilePath);
            free(pCurrentProfilePath);
        }
        */
    }

    /* Initialize NSPR and NSS */
    PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1 ) ;

    if (NSS_Init(sCertDir.getStr()) != SECSuccess )
    {
        PK11_LogoutAll();
        return NULL;
    }

    pCertHandle = CERT_GetDefaultCertDB() ;
    pSlot = PK11_GetInternalKeySlot() ;

    if (pSlot == NULL)
    {
        PK11_LogoutAll();
        NSS_Shutdown();
        return NULL;
    }

    PK11SymKey* pSymKey = PK11_KeyGen( pSlot , CKM_DES3_CBC, NULL, 128, NULL ) ;
    if( pSymKey == NULL )
    {
        PK11_FreeSlot( pSlot ) ;
        PK11_LogoutAll();
        NSS_Shutdown();
        return NULL;
    }

    try
    {
        /* Build Security Environment */
        const rtl::OUString sSecyrutyEnvironment ( RTL_CONSTASCII_USTRINGPARAM( SECURITY_ENVIRONMENT ) );
        cssu::Reference< cssxc::XSecurityEnvironment > xSecEnv( mxMSF->createInstance ( sSecyrutyEnvironment ), cssu::UNO_QUERY );
        if( !xSecEnv.is() )
        {
            PK11_FreeSymKey( pSymKey ) ;
            PK11_FreeSlot( pSlot ) ;
            PK11_LogoutAll();
            NSS_Shutdown();
            return NULL;
        }

        /* Setup key slot and certDb */
        cssu::Reference< cssl::XUnoTunnel > xEnvTunnel( xSecEnv , cssu::UNO_QUERY ) ;
        if( !xEnvTunnel.is() )
        {
            PK11_FreeSymKey( pSymKey ) ;
            PK11_FreeSlot( pSlot ) ;
            PK11_LogoutAll();
            NSS_Shutdown();
            return NULL;
        }

        SecurityEnvironment_NssImpl* pSecEnv = ( SecurityEnvironment_NssImpl* )xEnvTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ) ;
        if( pSecEnv == NULL )
        {
            PK11_FreeSymKey( pSymKey ) ;
            PK11_FreeSlot( pSlot ) ;
            PK11_LogoutAll();
            NSS_Shutdown();
            return NULL;
        }

        pSecEnv->setCryptoSlot( pSlot ) ;
        PK11_FreeSlot( pSlot ) ;
        pSlot = NULL;

        pSecEnv->setCertDb( pCertHandle ) ;

        pSecEnv->adoptSymKey( pSymKey ) ;
        PK11_FreeSymKey( pSymKey ) ;
        pSymKey = NULL;

        /* Build XML Security Context */
        const rtl::OUString sSecyrutyContext ( RTL_CONSTASCII_USTRINGPARAM( SECURITY_CONTEXT ) );
        cssu::Reference< cssxc::XXMLSecurityContext > xSecCtx( mxMSF->createInstance ( sSecyrutyContext ), cssu::UNO_QUERY );
        if( !xSecCtx.is() )
        {
            PK11_LogoutAll();
            NSS_Shutdown();
            return NULL;
        }

        xSecCtx->setSecurityEnvironment( xSecEnv ) ;
        return xSecCtx;
    }
    catch( cssu::Exception& )
    {
        if (pSymKey != NULL)
        {
            PK11_FreeSymKey( pSymKey ) ;
        }

        if (pSlot != NULL)
        {
            PK11_FreeSlot( pSlot ) ;
        }

        PK11_LogoutAll();
        NSS_Shutdown();
        return NULL;
    }
}

void SAL_CALL SEInitializer_NssImpl::freeSecurityContext( const cssu::Reference< cssxc::XXMLSecurityContext >& securityContext )
    throw (cssu::RuntimeException)
{
    /*
     * because the security context will free all its content when it
     * is destructed, so here no free process for the security context
     * is needed.
     */
    PK11_LogoutAll();
    NSS_Shutdown();
}

rtl::OUString SEInitializer_NssImpl_getImplementationName ()
    throw (cssu::RuntimeException)
{
    return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
}

sal_Bool SAL_CALL SEInitializer_NssImpl_supportsService( const rtl::OUString& ServiceName )
    throw (cssu::RuntimeException)
{
    return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ));
}

cssu::Sequence< rtl::OUString > SAL_CALL SEInitializer_NssImpl_getSupportedServiceNames(  )
    throw (cssu::RuntimeException)
{
    cssu::Sequence < rtl::OUString > aRet(1);
    rtl::OUString* pArray = aRet.getArray();
    pArray[0] =  rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
    return aRet;
}
#undef SERVICE_NAME

cssu::Reference< cssu::XInterface > SAL_CALL SEInitializer_NssImpl_createInstance( const cssu::Reference< cssl::XMultiServiceFactory > & rSMgr)
    throw( cssu::Exception )
{
    return (cppu::OWeakObject*) new SEInitializer_NssImpl(rSMgr);
}

/* XServiceInfo */
rtl::OUString SAL_CALL SEInitializer_NssImpl::getImplementationName(  )
    throw (cssu::RuntimeException)
{
    return SEInitializer_NssImpl_getImplementationName();
}
sal_Bool SAL_CALL SEInitializer_NssImpl::supportsService( const rtl::OUString& rServiceName )
    throw (cssu::RuntimeException)
{
    return SEInitializer_NssImpl_supportsService( rServiceName );
}
cssu::Sequence< rtl::OUString > SAL_CALL SEInitializer_NssImpl::getSupportedServiceNames(  )
    throw (cssu::RuntimeException)
{
    return SEInitializer_NssImpl_getSupportedServiceNames();
}

<commit_msg>#i21596# Digital Signatures...<commit_after>/*************************************************************************
 *
 *  $RCSfile: seinitializer_nssimpl.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: mt $ $Date: 2004-07-23 08:34:25 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

/*
 * Turn off DEBUG Assertions
 */
#ifdef _DEBUG
    #define _DEBUG_WAS_DEFINED _DEBUG
    #undef _DEBUG
#else
    #undef _DEBUG_WAS_DEFINED
#endif

/*
 * and turn off the additional virtual methods which are part of some interfaces when compiled
 * with debug
 */
#ifdef DEBUG
    #define DEBUG_WAS_DEFINED DEBUG
    #undef DEBUG
#else
    #undef DEBUG_WAS_DEFINED
#endif

/*
 * header files needed for getCurrentProfilePath
 */
/*
#include "nsIServiceManager.h"
#include "nsIProfileInternal.h"
#include "nsString.h"
#include "nsEmbedAPI.h"
*/

#include <sal/types.h>

#include <tools/debug.hxx>

#include "seinitializer_nssimpl.hxx"

#include "securityenvironment_nssimpl.hxx"

#include "nspr.h"
#include "prtypes.h"
#include "pk11func.h"
#include "cert.h"
#include "cryptohi.h"
#include "certdb.h"
#include "nss.h"

namespace cssu = com::sun::star::uno;
namespace cssl = com::sun::star::lang;
namespace cssxc = com::sun::star::xml::crypto;

using namespace com::sun::star;

#define SERVICE_NAME "com.sun.star.xml.crypto.SEInitializer"
#define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.SEInitializer_NssImpl"
#define SECURITY_ENVIRONMENT "com.sun.star.xml.crypto.SecurityEnvironment"
#define SECURITY_CONTEXT "com.sun.star.xml.crypto.XMLSecurityContext"

/*
 * MM : get the current user profile
 */

// MM : By now, the XPCOM is initialized only once in the current thread, and it will
//      not be shutdown until StarOffice exits.
//      This is a bug, because any other component who will initialize the XPCOM afterward
//      will always fail.
//      This bug will be fixed when there is solution.
#if 0
static nsIServiceManager           *sServiceManager = nsnull;
static nsIDirectoryServiceProvider *appFileLocProvider = nsnull;
static NS_DEFINE_CID(kProfileCID, NS_PROFILE_CID);

char* getCurrentProfilePath( )
{
/*
        nsCOMPtr<nsILocalFile> binDir;

        // Note: if getenv() returns NULL, mozilla will default to using MOZILLA_FIVE_HOME in the NS_InitXPCOM2()
        // The NS_NewNativeLocalFile() will accept NULL as its first parameter.
        char * env = getenv("OPENOFFICE_MOZILLA_FIVE_HOME");
        if (env)
        {
        nsDependentCString sPath(env);
        nsresult rv = NS_NewNativeLocalFile(sPath, PR_TRUE, getter_AddRefs(binDir));
        if (NS_FAILED(rv))
            return NULL;
        }

    if (sServiceManager == nsnull)
    {
        NS_InitXPCOM2(&sServiceManager, binDir, appFileLocProvider);
    }

    if (!sServiceManager)
        return NULL;

    nsresult rv;
    nsCOMPtr< nsIProfile > theProfile = do_GetService( kProfileCID, &rv );
    if (NS_SUCCEEDED(rv))
    {
        nsXPIDLString profileName;
        rv = theProfile->GetCurrentProfile(getter_Copies(profileName));
        if (NS_SUCCEEDED(rv))
        {
            nsCOMPtr<nsIFile> curProfileDir;
            PRBool exists = PR_FALSE;
            nsCOMPtr<nsIProfileInternal> profileInternal=do_QueryInterface(theProfile);
            if (NS_SUCCEEDED(rv))
            {
                rv = profileInternal->GetProfileDir(profileName, getter_AddRefs(curProfileDir));
                if (NS_SUCCEEDED(rv))
                {
                    nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(curProfileDir));

                    nsAutoString path;
                    rv = localFile->GetPath(path);
                    if (NS_SUCCEEDED(rv))
                    {
                        char cs[1024];
                        path.ToCString(cs, 1024);

                        // MM : I can't shutdown, because the XPCom can't be initialized twice in
                        //      one program
                        //NS_RELEASE(sServiceManager);
                        //NS_ShutdownXPCOM(sServiceManager);

                        return (strdup(cs));
                    }
                }
            }
        }
    }

    // MM : I can't shutdown, because the XPCom can't be initialized twice in
    //      one program
    //NS_RELEASE(sServiceManager);
    //NS_ShutdownXPCOM(sServiceManager);
    */

    return NULL;
}

/*
 * get the current user profile (end)
 */

#endif

bool getMozillaCurrentProfile(rtl::OUString& profilePath);

SEInitializer_NssImpl::SEInitializer_NssImpl(
    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &rxMSF)
    :mxMSF( rxMSF )
{
}

SEInitializer_NssImpl::~SEInitializer_NssImpl()
{
}

/* XSEInitializer */
cssu::Reference< cssxc::XXMLSecurityContext > SAL_CALL
    SEInitializer_NssImpl::createSecurityContext(
    const rtl::OUString& sCertDB )
    throw (cssu::RuntimeException)
{
    CERTCertDBHandle*   pCertHandle = NULL ;
    PK11SlotInfo*       pSlot = NULL ;

    rtl::OString sCertDir;
    if( sCertDB.getLength() )
    {
        sCertDir = rtl::OString(sCertDB, sCertDB.getLength(), RTL_TEXTENCODING_ASCII_US);
    }
    else
    {
        static rtl::OString* pDefaultCertDir = NULL;
        if ( !pDefaultCertDir )
        {
            pDefaultCertDir = new rtl::OString;
            rtl::OUString ouCertDir;
            if ( getMozillaCurrentProfile(ouCertDir) )
            {
                *pDefaultCertDir = rtl::OString(ouCertDir, ouCertDir.getLength(), RTL_TEXTENCODING_ASCII_US);
                DBG_ERROR( pDefaultCertDir->getStr() );
            }
        }
        sCertDir = *pDefaultCertDir;

    }

    if( !sCertDir.getLength() )
        return NULL;

    /* Initialize NSPR and NSS */
    PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1 ) ;

    if (NSS_Init(sCertDir.getStr()) != SECSuccess )
    {
        PK11_LogoutAll();
        return NULL;
    }

    pCertHandle = CERT_GetDefaultCertDB() ;
    pSlot = PK11_GetInternalKeySlot() ;

    if (pSlot == NULL)
    {
        PK11_LogoutAll();
        NSS_Shutdown();
        return NULL;
    }

    PK11SymKey* pSymKey = PK11_KeyGen( pSlot , CKM_DES3_CBC, NULL, 128, NULL ) ;
    if( pSymKey == NULL )
    {
        PK11_FreeSlot( pSlot ) ;
        PK11_LogoutAll();
        NSS_Shutdown();
        return NULL;
    }

    try
    {
        /* Build Security Environment */
        const rtl::OUString sSecyrutyEnvironment ( RTL_CONSTASCII_USTRINGPARAM( SECURITY_ENVIRONMENT ) );
        cssu::Reference< cssxc::XSecurityEnvironment > xSecEnv( mxMSF->createInstance ( sSecyrutyEnvironment ), cssu::UNO_QUERY );
        if( !xSecEnv.is() )
        {
            PK11_FreeSymKey( pSymKey ) ;
            PK11_FreeSlot( pSlot ) ;
            PK11_LogoutAll();
            NSS_Shutdown();
            return NULL;
        }

        /* Setup key slot and certDb */
        cssu::Reference< cssl::XUnoTunnel > xEnvTunnel( xSecEnv , cssu::UNO_QUERY ) ;
        if( !xEnvTunnel.is() )
        {
            PK11_FreeSymKey( pSymKey ) ;
            PK11_FreeSlot( pSlot ) ;
            PK11_LogoutAll();
            NSS_Shutdown();
            return NULL;
        }

        SecurityEnvironment_NssImpl* pSecEnv = ( SecurityEnvironment_NssImpl* )xEnvTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ) ;
        if( pSecEnv == NULL )
        {
            PK11_FreeSymKey( pSymKey ) ;
            PK11_FreeSlot( pSlot ) ;
            PK11_LogoutAll();
            NSS_Shutdown();
            return NULL;
        }

        pSecEnv->setCryptoSlot( pSlot ) ;
        PK11_FreeSlot( pSlot ) ;
        pSlot = NULL;

        pSecEnv->setCertDb( pCertHandle ) ;

        pSecEnv->adoptSymKey( pSymKey ) ;
        PK11_FreeSymKey( pSymKey ) ;
        pSymKey = NULL;

        /* Build XML Security Context */
        const rtl::OUString sSecyrutyContext ( RTL_CONSTASCII_USTRINGPARAM( SECURITY_CONTEXT ) );
        cssu::Reference< cssxc::XXMLSecurityContext > xSecCtx( mxMSF->createInstance ( sSecyrutyContext ), cssu::UNO_QUERY );
        if( !xSecCtx.is() )
        {
            PK11_LogoutAll();
            NSS_Shutdown();
            return NULL;
        }

        xSecCtx->setSecurityEnvironment( xSecEnv ) ;
        return xSecCtx;
    }
    catch( cssu::Exception& )
    {
        if (pSymKey != NULL)
        {
            PK11_FreeSymKey( pSymKey ) ;
        }

        if (pSlot != NULL)
        {
            PK11_FreeSlot( pSlot ) ;
        }

        PK11_LogoutAll();
        NSS_Shutdown();
        return NULL;
    }
}

void SAL_CALL SEInitializer_NssImpl::freeSecurityContext( const cssu::Reference< cssxc::XXMLSecurityContext >& securityContext )
    throw (cssu::RuntimeException)
{
    /*
     * because the security context will free all its content when it
     * is destructed, so here no free process for the security context
     * is needed.
     */
    PK11_LogoutAll();
    NSS_Shutdown();
}

rtl::OUString SEInitializer_NssImpl_getImplementationName ()
    throw (cssu::RuntimeException)
{
    return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
}

sal_Bool SAL_CALL SEInitializer_NssImpl_supportsService( const rtl::OUString& ServiceName )
    throw (cssu::RuntimeException)
{
    return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ));
}

cssu::Sequence< rtl::OUString > SAL_CALL SEInitializer_NssImpl_getSupportedServiceNames(  )
    throw (cssu::RuntimeException)
{
    cssu::Sequence < rtl::OUString > aRet(1);
    rtl::OUString* pArray = aRet.getArray();
    pArray[0] =  rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
    return aRet;
}
#undef SERVICE_NAME

cssu::Reference< cssu::XInterface > SAL_CALL SEInitializer_NssImpl_createInstance( const cssu::Reference< cssl::XMultiServiceFactory > & rSMgr)
    throw( cssu::Exception )
{
    return (cppu::OWeakObject*) new SEInitializer_NssImpl(rSMgr);
}

/* XServiceInfo */
rtl::OUString SAL_CALL SEInitializer_NssImpl::getImplementationName(  )
    throw (cssu::RuntimeException)
{
    return SEInitializer_NssImpl_getImplementationName();
}
sal_Bool SAL_CALL SEInitializer_NssImpl::supportsService( const rtl::OUString& rServiceName )
    throw (cssu::RuntimeException)
{
    return SEInitializer_NssImpl_supportsService( rServiceName );
}
cssu::Sequence< rtl::OUString > SAL_CALL SEInitializer_NssImpl::getSupportedServiceNames(  )
    throw (cssu::RuntimeException)
{
    return SEInitializer_NssImpl_getSupportedServiceNames();
}

<|endoftext|>


<commit_before>// json_entity.cpp
#include "json_entity.h"

namespace StevensDev
{

namespace sgdd
{

JsonEntity::JsonEntity( const JsonEntity& other )
    : d_type( other.d_type )
{
    switch ( d_type )
    {
        case OBJECT:
            d_mapAlloc = other.d_mapAlloc;
            d_map = d_mapAlloc.get( 1 );
            d_mapAlloc.construct( d_map, *other.d_map );
            break;

        case ARRAY:
            d_arrAlloc = other.d_arrAlloc;
            d_array = d_arrAlloc.get( 1 );
            d_arrAlloc.construct( d_array, *other.d_array );
            break;

        case STRING:
            d_strAlloc = other.d_strAlloc;
            d_string = d_strAlloc.get( 1 );
            d_strAlloc.construct( d_string, *other.d_string );
            break;

        case DECIMAL:
            d_decimal = other.d_decimal;
            break;

        case INTEGRAL:
            d_integral = other.d_integral;
            break;

        case BOOLEAN:
            d_boolean = other.d_boolean;
            break;

        default:
            d_integral = 0;
            break;
    }
}

JsonEntity::JsonEntity( JsonEntity&& other ) : d_type( other.d_type )
{
    switch ( d_type )
    {
        case OBJECT:
            d_mapAlloc = other.d_mapAlloc;
            d_map = other.d_map;

            other.d_map = nullptr;
            break;

        case ARRAY:
            d_arrAlloc = other.d_arrAlloc;
            d_array = other.d_array;

            other.d_array = nullptr;
            break;

        case STRING:
            d_strAlloc = other.d_strAlloc;
            d_string = other.d_string;

            other.d_string = nullptr;
            break;

        case DECIMAL:
            d_decimal = other.d_decimal;
            break;

        case INTEGRAL:
            d_integral = other.d_integral;
            break;

        case BOOLEAN:
            d_boolean = other.d_boolean;
            break;

        default:
            d_integral = 0;
            break;
    }
}

JsonEntity::~JsonEntity()
{
    switch ( d_type )
    {
        case OBJECT:
            if ( d_map != nullptr )
            {
                d_mapAlloc.release( d_map, 1 );
            }
            break;

        case ARRAY:
            if ( d_array != nullptr )
            {
                d_arrAlloc.release( d_array, 1 );
            }
            break;

        case STRING:
            if ( d_string != nullptr )
            {
                d_strAlloc.release( d_string, 1 );
            }
            break;
    }
}

JsonEntity& JsonEntity::operator=( const JsonEntity& other )
{
    switch ( d_type )
    {
        case OBJECT:
            if ( d_map != nullptr )
            {
                d_mapAlloc.release( d_map, 1 );
            }
            break;

        case ARRAY:
            if ( d_array != nullptr )
            {
                d_arrAlloc.release( d_array, 1 );
            }
            break;

        case STRING:
            if ( d_string != nullptr )
            {
                d_strAlloc.release( d_string, 1 );
            }
            break;
    }

    d_type = other.d_type;

    switch ( d_type )
    {
        case OBJECT:
            d_mapAlloc = other.d_mapAlloc;
            d_map = d_mapAlloc.get( 1 );
            d_mapAlloc.construct( d_map, *other.d_map );
            break;

        case ARRAY:
            d_arrAlloc = other.d_arrAlloc;
            d_array = d_arrAlloc.get( 1 );
            d_arrAlloc.construct( d_array, *other.d_array );
            break;

        case STRING:
            d_strAlloc = other.d_strAlloc;
            d_string = d_strAlloc.get( 1 );
            d_strAlloc.construct( d_string, *other.d_string );
            break;

        case DECIMAL:
            d_decimal = other.d_decimal;
            break;

        case INTEGRAL:
            d_integral = other.d_integral;
            break;

        case BOOLEAN:
            d_boolean = other.d_boolean;
            break;

        default:
            d_integral = 0;
            break;
    }

    return *this;
}

JsonEntity& JsonEntity::operator=( JsonEntity&& other )
{
    switch ( d_type )
    {
        case OBJECT:
            if ( d_map != nullptr )
            {
                d_mapAlloc.release( d_map, 1 );
            }
            break;

        case ARRAY:
            if ( d_array != nullptr )
            {
                d_arrAlloc.release( d_array, 1 );
            }
            break;

        case STRING:
            if ( d_string != nullptr )
            {
                d_strAlloc.release( d_string, 1 );
            }
            break;
    }

    d_type = other.d_type;

    switch ( d_type )
    {
        case OBJECT:
            d_mapAlloc = other.d_mapAlloc;
            d_map = other.d_map;

            other.d_map = nullptr;
            break;

        case ARRAY:
            d_arrAlloc = other.d_arrAlloc;
            d_array = other.d_array;

            other.d_array = nullptr;
            break;

        case STRING:
            d_strAlloc = other.d_strAlloc;
            d_string = other.d_string;

            other.d_string = nullptr;
            break;

        case DECIMAL:
            d_decimal = other.d_decimal;
            break;

        case INTEGRAL:
            d_integral = other.d_integral;
            break;

        case BOOLEAN:
            d_boolean = other.d_boolean;
            break;

        default:
            d_integral = 0;
            break;
    }

    return *this;
}

} // End nspc sgdd

} // End nspc StevensDev<commit_msg>Force move<commit_after>// json_entity.cpp
#include "json_entity.h"

namespace StevensDev
{

namespace sgdd
{

JsonEntity::JsonEntity( const JsonEntity& other )
    : d_type( other.d_type )
{
    switch ( d_type )
    {
        case OBJECT:
            d_mapAlloc = other.d_mapAlloc;
            d_map = d_mapAlloc.get( 1 );
            d_mapAlloc.construct( d_map, *other.d_map );
            break;

        case ARRAY:
            d_arrAlloc = other.d_arrAlloc;
            d_array = d_arrAlloc.get( 1 );
            d_arrAlloc.construct( d_array, *other.d_array );
            break;

        case STRING:
            d_strAlloc = other.d_strAlloc;
            d_string = d_strAlloc.get( 1 );
            d_strAlloc.construct( d_string, *other.d_string );
            break;

        case DECIMAL:
            d_decimal = other.d_decimal;
            break;

        case INTEGRAL:
            d_integral = other.d_integral;
            break;

        case BOOLEAN:
            d_boolean = other.d_boolean;
            break;

        default:
            d_integral = 0;
            break;
    }
}

JsonEntity::JsonEntity( JsonEntity&& other ) : d_type( other.d_type )
{
    switch ( d_type )
    {
        case OBJECT:
            d_mapAlloc = other.d_mapAlloc;
            d_map = std::move( other.d_map );

            other.d_map = nullptr;
            break;

        case ARRAY:
            d_arrAlloc = other.d_arrAlloc;
            d_array = std::move( other.d_array );

            other.d_array = nullptr;
            break;

        case STRING:
            d_strAlloc = other.d_strAlloc;
            d_string = std::move( other.d_string );

            other.d_string = nullptr;
            break;

        case DECIMAL:
            d_decimal = other.d_decimal;
            break;

        case INTEGRAL:
            d_integral = other.d_integral;
            break;

        case BOOLEAN:
            d_boolean = other.d_boolean;
            break;

        default:
            d_integral = 0;
            break;
    }
}

JsonEntity::~JsonEntity()
{
    switch ( d_type )
    {
        case OBJECT:
            if ( d_map != nullptr )
            {
                d_mapAlloc.release( d_map, 1 );
            }
            break;

        case ARRAY:
            if ( d_array != nullptr )
            {
                d_arrAlloc.release( d_array, 1 );
            }
            break;

        case STRING:
            if ( d_string != nullptr )
            {
                d_strAlloc.release( d_string, 1 );
            }
            break;
    }
}

JsonEntity& JsonEntity::operator=( const JsonEntity& other )
{
    switch ( d_type )
    {
        case OBJECT:
            if ( d_map != nullptr )
            {
                d_mapAlloc.release( d_map, 1 );
            }
            break;

        case ARRAY:
            if ( d_array != nullptr )
            {
                d_arrAlloc.release( d_array, 1 );
            }
            break;

        case STRING:
            if ( d_string != nullptr )
            {
                d_strAlloc.release( d_string, 1 );
            }
            break;
    }

    d_type = other.d_type;

    switch ( d_type )
    {
        case OBJECT:
            d_mapAlloc = other.d_mapAlloc;
            d_map = d_mapAlloc.get( 1 );
            d_mapAlloc.construct( d_map, *other.d_map );
            break;

        case ARRAY:
            d_arrAlloc = other.d_arrAlloc;
            d_array = d_arrAlloc.get( 1 );
            d_arrAlloc.construct( d_array, *other.d_array );
            break;

        case STRING:
            d_strAlloc = other.d_strAlloc;
            d_string = d_strAlloc.get( 1 );
            d_strAlloc.construct( d_string, *other.d_string );
            break;

        case DECIMAL:
            d_decimal = other.d_decimal;
            break;

        case INTEGRAL:
            d_integral = other.d_integral;
            break;

        case BOOLEAN:
            d_boolean = other.d_boolean;
            break;

        default:
            d_integral = 0;
            break;
    }

    return *this;
}

JsonEntity& JsonEntity::operator=( JsonEntity&& other )
{
    switch ( d_type )
    {
        case OBJECT:
            if ( d_map != nullptr )
            {
                d_mapAlloc.release( d_map, 1 );
            }
            break;

        case ARRAY:
            if ( d_array != nullptr )
            {
                d_arrAlloc.release( d_array, 1 );
            }
            break;

        case STRING:
            if ( d_string != nullptr )
            {
                d_strAlloc.release( d_string, 1 );
            }
            break;
    }

    d_type = other.d_type;

    switch ( d_type )
    {
        case OBJECT:
            d_mapAlloc = other.d_mapAlloc;
            d_map = std::move( other.d_map );

            other.d_map = nullptr;
            break;

        case ARRAY:
            d_arrAlloc = other.d_arrAlloc;
            d_array = std::move( other.d_array );

            other.d_array = nullptr;
            break;

        case STRING:
            d_strAlloc = other.d_strAlloc;
            d_string = std::move( other.d_string );

            other.d_string = nullptr;
            break;

        case DECIMAL:
            d_decimal = other.d_decimal;
            break;

        case INTEGRAL:
            d_integral = other.d_integral;
            break;

        case BOOLEAN:
            d_boolean = other.d_boolean;
            break;

        default:
            d_integral = 0;
            break;
    }

    return *this;
}

} // End nspc sgdd

} // End nspc StevensDev<|endoftext|>


<commit_before>/* hhdataproxy.cc			KPilot
**
** Copyright (C) 2007 by Bertjan Broeksema <b.broeksema@kdemail.net>
** Copyright (C) 2007 by Jason "vanRijn" Kasper <vr@movingparts.net>
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

#include "hhdataproxy.h"

#include <klocalizedstring.h>

#include "pilotDatabase.h"
#include "pilotAppInfo.h"
#include "pilotRecord.h"
#include "options.h"
#include "pilot.h"

#include "hhrecord.h"

HHDataProxy::HHDataProxy( PilotDatabase *db ) : fDatabase( db )
	, fLastUsedUniqueId( 0L )
{
}

void HHDataProxy::syncFinished()
{
	FUNCTIONSETUP;

	if( fDatabase && fDatabase->isOpen() )
	{
		fDatabase->cleanup();
		storeAppInfo();
		fDatabase->resetSyncFlags();
	}
}

void HHDataProxy::clearCategory( HHRecord *rec )
{
	FUNCTIONSETUP;

	rec->setCategory( Pilot::Unfiled, CSL1( "Unfiled" ) );
}

bool HHDataProxy::containsCategory( const QString& category ) const
{
	FUNCTIONSETUP;

	return fAppInfo->findCategory( category, false ) != -1;
}

bool HHDataProxy::addGlobalCategory( const QString& category )
{
	FUNCTIONSETUP;

	if( fAppInfo->findCategory( category, false ) != -1 )
	{
		// The category is already there.
		return true;
	}

	if( (unsigned int) category.size() > Pilot::CATEGORY_SIZE )
	{
		// Let's not start on this one. It will get truncated and I don't have time
		// energy to think about what should happen in that case.
		return false;
	}

	bool canHaveNewCategory = false;
	unsigned int i = 0;
	QString cat;

	while( i < Pilot::CATEGORY_COUNT && !canHaveNewCategory )
	{
		cat = fAppInfo->categoryName( i );

		if( cat.isEmpty() )
		{
			canHaveNewCategory = true;
		}
		else
		{
			// Try the next one.
			i++;
		}
	}

	if( canHaveNewCategory )
	{
		fAppInfo->setCategoryName( i, category );
		fAddedCategories.insert( i, category );
		return true;
	}

	return false;
}

void HHDataProxy::setCategory( Record* rec, const QString& category )
{
	FUNCTIONSETUP;

	// Get the category id or let findCategory return -1 if it does not exist.
	int id = fAppInfo->findCategory( category, false );

	if( id != -1 )
	{
		if( HHRecord *hhRec = static_cast<HHRecord*>( rec ) )
		{
			// Set the id to 0 to make sure that the database asigns a valid id to the
			// record.
			hhRec->setCategory( id, category );
		}
		else
		{
			DEBUGKPILOT << "Record " << rec->id() << " is not of type HHRecord*.";
		}
	}
}

QString HHDataProxy::generateUniqueId()
{
	recordid_t id = 0;

	QList<QString> ids = fRecords.keys();

	for( int i = 0; i < fRecords.size(); i++ )
	{
		if( ids.at( i ).toULong() > id )
		{
			id = ids.at( i ).toULong();
		}
	}

	return QString::number( id + 1 );
}

bool HHDataProxy::_commit()
{
	FUNCTIONSETUP;

	if( fAppInfo )
	{
		fAppInfo->writeTo( fDatabase );
	}

	return true;
}

bool HHDataProxy::_rollback()
{
	FUNCTIONSETUP;

	// Roll back the categories.
	foreach( uint i, fAddedCategories.keys() )
	{
		fAppInfo->setCategoryName( i, "" );
	}

	fAppInfo->writeTo( fDatabase );

	// Make sure we can commit them again if we want to.
	foreach( uint i, fAddedCategories.keys() )
	{
		fAppInfo->setCategoryName( i, fAddedCategories.value( i ) );
	}

	return true;
}

void HHDataProxy::commitCreate( Record *rec )
{
	FUNCTIONSETUP;

	if( fDatabase && rec )
	{
		if( HHRecord *hhRec = static_cast<HHRecord*>( rec ) )
		{
			// Set the id to 0 to make sure that the database asigns a valid id to the
			// record.
			hhRec->setId( QString::number( 0 ) );
			fDatabase->writeRecord( hhRec->pilotRecord() );
		}
		else
		{
			DEBUGKPILOT << "Record " << rec->id() << " is not of type HHRecord*.";
		}
	}
}

void HHDataProxy::commitUpdate( Record *rec )
{
	FUNCTIONSETUP;

	if( fDatabase && rec )
	{
		if( HHRecord *hhRec = static_cast<HHRecord*>( rec ) )
		{
			fDatabase->writeRecord( hhRec->pilotRecord() );
		}
		else
		{
			DEBUGKPILOT << "Record " << rec->id() << " is not of type HHRecord*.";
		}
	}
}

void HHDataProxy::commitDelete( Record *rec )
{
	FUNCTIONSETUP;

	if( !rec || !fDatabase )
	{
		return;
	}
	else
	{
		if( HHRecord *hhRec = static_cast<HHRecord*>( rec ) )
		{
			fDatabase->deleteRecord( hhRec->pilotRecord()->id() );
		}
		else
		{
			DEBUGKPILOT << "Record " << rec->id() << " is not of type HHRecord*.";
		}
	}
}

bool HHDataProxy::isOpen() const
{
	FUNCTIONSETUP;

	if( fDatabase )
	{
		return fDatabase->isOpen();
	}
	else
	{
		return false;
	}
}

void HHDataProxy::loadAllRecords()
{
	FUNCTIONSETUP;

	if( fDatabase && fDatabase->isOpen() )
	{
		fAppInfo = readAppInfo();

		int index = 0;

		PilotRecord *pRec = fDatabase->readRecordByIndex( index );

		while( pRec )
		{
			// Create a record object.
			HHRecord *rec = createHHRecord( pRec );
			fRecords.insert( rec->id(), rec );

			QString cat = fAppInfo->categoryName( pRec->category() );

			if( cat.isEmpty() )
			{
				// This is strange, should not happen I think. However if it happens
				// make sure that the record has some reasonable values.
				rec->setCategory( Pilot::Unfiled, cat );
			}
			else
			{
				rec->setCategory( pRec->category(), cat );
			}

			// Read the next one.
			pRec = fDatabase->readRecordByIndex( ++index );
		}
		fCounter.setStartCount( fRecords.count() );

		DEBUGKPILOT << "Loaded " << fRecords.count() << " records.";
	}
}
<commit_msg>Initialize all pointer types to 0L to make sure that we don't get weird crashes when we try to access these members.<commit_after>/* hhdataproxy.cc			KPilot
**
** Copyright (C) 2007 by Bertjan Broeksema <b.broeksema@kdemail.net>
** Copyright (C) 2007 by Jason "vanRijn" Kasper <vr@movingparts.net>
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

#include "hhdataproxy.h"

#include <klocalizedstring.h>

#include "pilotDatabase.h"
#include "pilotAppInfo.h"
#include "pilotRecord.h"
#include "options.h"
#include "pilot.h"

#include "hhrecord.h"

HHDataProxy::HHDataProxy( PilotDatabase *db ) : fDatabase( db )
	, fLastUsedUniqueId( 0L ), fAppInfo( 0L )
{
}

void HHDataProxy::syncFinished()
{
	FUNCTIONSETUP;

	if( fDatabase && fDatabase->isOpen() )
	{
		fDatabase->cleanup();
		storeAppInfo();
		fDatabase->resetSyncFlags();
	}
}

void HHDataProxy::clearCategory( HHRecord *rec )
{
	FUNCTIONSETUP;

	rec->setCategory( Pilot::Unfiled, CSL1( "Unfiled" ) );
}

bool HHDataProxy::containsCategory( const QString& category ) const
{
	FUNCTIONSETUP;

	return fAppInfo->findCategory( category, false ) != -1;
}

bool HHDataProxy::addGlobalCategory( const QString& category )
{
	FUNCTIONSETUP;

	if( fAppInfo->findCategory( category, false ) != -1 )
	{
		// The category is already there.
		return true;
	}

	if( (unsigned int) category.size() > Pilot::CATEGORY_SIZE )
	{
		// Let's not start on this one. It will get truncated and I don't have time
		// energy to think about what should happen in that case.
		return false;
	}

	bool canHaveNewCategory = false;
	unsigned int i = 0;
	QString cat;

	while( i < Pilot::CATEGORY_COUNT && !canHaveNewCategory )
	{
		cat = fAppInfo->categoryName( i );

		if( cat.isEmpty() )
		{
			canHaveNewCategory = true;
		}
		else
		{
			// Try the next one.
			i++;
		}
	}

	if( canHaveNewCategory )
	{
		fAppInfo->setCategoryName( i, category );
		fAddedCategories.insert( i, category );
		return true;
	}

	return false;
}

void HHDataProxy::setCategory( Record* rec, const QString& category )
{
	FUNCTIONSETUP;

	// Get the category id or let findCategory return -1 if it does not exist.
	int id = fAppInfo->findCategory( category, false );

	if( id != -1 )
	{
		if( HHRecord *hhRec = static_cast<HHRecord*>( rec ) )
		{
			// Set the id to 0 to make sure that the database asigns a valid id to the
			// record.
			hhRec->setCategory( id, category );
		}
		else
		{
			DEBUGKPILOT << "Record " << rec->id() << " is not of type HHRecord*.";
		}
	}
}

QString HHDataProxy::generateUniqueId()
{
	recordid_t id = 0;

	QList<QString> ids = fRecords.keys();

	for( int i = 0; i < fRecords.size(); i++ )
	{
		if( ids.at( i ).toULong() > id )
		{
			id = ids.at( i ).toULong();
		}
	}

	return QString::number( id + 1 );
}

bool HHDataProxy::_commit()
{
	FUNCTIONSETUP;

	if( fAppInfo )
	{
		fAppInfo->writeTo( fDatabase );
	}

	return true;
}

bool HHDataProxy::_rollback()
{
	FUNCTIONSETUP;

	// Roll back the categories.
	foreach( uint i, fAddedCategories.keys() )
	{
		fAppInfo->setCategoryName( i, "" );
	}

	fAppInfo->writeTo( fDatabase );

	// Make sure we can commit them again if we want to.
	foreach( uint i, fAddedCategories.keys() )
	{
		fAppInfo->setCategoryName( i, fAddedCategories.value( i ) );
	}

	return true;
}

void HHDataProxy::commitCreate( Record *rec )
{
	FUNCTIONSETUP;

	if( fDatabase && rec )
	{
		if( HHRecord *hhRec = static_cast<HHRecord*>( rec ) )
		{
			// Set the id to 0 to make sure that the database asigns a valid id to the
			// record.
			hhRec->setId( QString::number( 0 ) );
			fDatabase->writeRecord( hhRec->pilotRecord() );
		}
		else
		{
			DEBUGKPILOT << "Record " << rec->id() << " is not of type HHRecord*.";
		}
	}
}

void HHDataProxy::commitUpdate( Record *rec )
{
	FUNCTIONSETUP;

	if( fDatabase && rec )
	{
		if( HHRecord *hhRec = static_cast<HHRecord*>( rec ) )
		{
			fDatabase->writeRecord( hhRec->pilotRecord() );
		}
		else
		{
			DEBUGKPILOT << "Record " << rec->id() << " is not of type HHRecord*.";
		}
	}
}

void HHDataProxy::commitDelete( Record *rec )
{
	FUNCTIONSETUP;

	if( !rec || !fDatabase )
	{
		return;
	}
	else
	{
		if( HHRecord *hhRec = static_cast<HHRecord*>( rec ) )
		{
			fDatabase->deleteRecord( hhRec->pilotRecord()->id() );
		}
		else
		{
			DEBUGKPILOT << "Record " << rec->id() << " is not of type HHRecord*.";
		}
	}
}

bool HHDataProxy::isOpen() const
{
	FUNCTIONSETUP;

	if( fDatabase )
	{
		return fDatabase->isOpen();
	}
	else
	{
		return false;
	}
}

void HHDataProxy::loadAllRecords()
{
	FUNCTIONSETUP;

	if( fDatabase && fDatabase->isOpen() )
	{
		fAppInfo = readAppInfo();

		int index = 0;

		PilotRecord *pRec = fDatabase->readRecordByIndex( index );

		while( pRec )
		{
			// Create a record object.
			HHRecord *rec = createHHRecord( pRec );
			fRecords.insert( rec->id(), rec );

			QString cat = fAppInfo->categoryName( pRec->category() );

			if( cat.isEmpty() )
			{
				// This is strange, should not happen I think. However if it happens
				// make sure that the record has some reasonable values.
				rec->setCategory( Pilot::Unfiled, cat );
			}
			else
			{
				rec->setCategory( pRec->category(), cat );
			}

			// Read the next one.
			pRec = fDatabase->readRecordByIndex( ++index );
		}
		fCounter.setStartCount( fRecords.count() );

		DEBUGKPILOT << "Loaded " << fRecords.count() << " records.";
	}
}
<|endoftext|>