<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// When possible, we implement allocator functions on top of the basic
// low-level functions malloc() and free().  This way, including a new
// allocator is as simple as providing just a small interface.
//
// As such, this file should not contain any allocator-specific code.

// Implement a C++ style allocation, which always calls the new_handler
// on failure.
inline void* generic_cpp_alloc(size_t size, bool nothrow) {
  void* ptr;
  for (;;) {
    ptr = malloc(size);
    if (ptr)
      return ptr;
    if (!call_new_handler(nothrow))
      break;
  }
  return ptr;
}

extern "C++" {

void* __cdecl operator new(size_t size) {
  return generic_cpp_alloc(size, false);
}

void operator delete(void* p) __THROW {
  free(p);
}

void* operator new[](size_t size) {
  return generic_cpp_alloc(size, false);
}

void operator delete[](void* p) __THROW {
  free(p);
}

void* operator new(size_t size, const std::nothrow_t& nt) __THROW {
  return generic_cpp_alloc(size, true);
}

void* operator new[](size_t size, const std::nothrow_t& nt) __THROW {
  return generic_cpp_alloc(size, true);
}

// This function behaves similarly to MSVC's _set_new_mode.
// If flag is 0 (default), calls to malloc will behave normally.
// If flag is 1, calls to malloc will behave like calls to new,
// and the std_new_handler will be invoked on failure.
// Returns the previous mode.
int _set_new_mode(int flag) __THROW {
  int old_mode = new_mode;
  new_mode = flag;
  return old_mode;
}

}  // extern "C++"

extern "C" {

void* calloc(size_t n, size_t elem_size) __THROW {
  // Overflow check
  const size_t size = n * elem_size;
  if (elem_size != 0 && size / elem_size != n) return NULL;

  void* result = malloc(size);
  if (result != NULL) {
    memset(result, 0, size);
  }
  return result;
}

void cfree(void* p) __THROW {
  free(p);
}

#ifdef WIN32

void* _recalloc(void* p, size_t n, size_t elem_size) {
  if (!p)
    return calloc(n, elem_size);

  // This API is a bit odd.
  // Note: recalloc only guarantees zeroed memory when p is NULL.
  //   Generally, calls to malloc() have padding.  So a request
  //   to malloc N bytes actually malloc's N+x bytes.  Later, if
  //   that buffer is passed to recalloc, we don't know what N
  //   was anymore.  We only know what N+x is.  As such, there is
  //   no way to know what to zero out.
  const size_t size = n * elem_size;
  if (elem_size != 0 && size / elem_size != n) return NULL;
  return realloc(p, size);
}

void* _calloc_impl(size_t n, size_t size) {
  return calloc(n, size);
}

#ifndef NDEBUG
#undef malloc
#undef free
#undef calloc
int _CrtDbgReport(int, const char*, int, const char*, const char*, ...) {
  return 0;
}

int _CrtDbgReportW(int, const wchar_t*, int, const wchar_t*,
                   const wchar_t*, ...) {
  return 0;
}

int _CrtSetReportMode(int, int) {
  return 0;
}

void* _malloc_dbg(size_t size, int , const char*, int) {
  return malloc(size);
}

void _free_dbg(void* ptr, int) {
  free(ptr);
}

void* _calloc_dbg(size_t n, size_t size, int, const char*, int) {
  return calloc(n, size);
}
#endif  // NDEBUG

#endif  // WIN32

}  // extern C

<commit_msg>Crash on error or assert message in Debug build<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// When possible, we implement allocator functions on top of the basic
// low-level functions malloc() and free().  This way, including a new
// allocator is as simple as providing just a small interface.
//
// As such, this file should not contain any allocator-specific code.

// Implement a C++ style allocation, which always calls the new_handler
// on failure.
inline void* generic_cpp_alloc(size_t size, bool nothrow) {
  void* ptr;
  for (;;) {
    ptr = malloc(size);
    if (ptr)
      return ptr;
    if (!call_new_handler(nothrow))
      break;
  }
  return ptr;
}

extern "C++" {

void* __cdecl operator new(size_t size) {
  return generic_cpp_alloc(size, false);
}

void operator delete(void* p) __THROW {
  free(p);
}

void* operator new[](size_t size) {
  return generic_cpp_alloc(size, false);
}

void operator delete[](void* p) __THROW {
  free(p);
}

void* operator new(size_t size, const std::nothrow_t& nt) __THROW {
  return generic_cpp_alloc(size, true);
}

void* operator new[](size_t size, const std::nothrow_t& nt) __THROW {
  return generic_cpp_alloc(size, true);
}

// This function behaves similarly to MSVC's _set_new_mode.
// If flag is 0 (default), calls to malloc will behave normally.
// If flag is 1, calls to malloc will behave like calls to new,
// and the std_new_handler will be invoked on failure.
// Returns the previous mode.
int _set_new_mode(int flag) __THROW {
  int old_mode = new_mode;
  new_mode = flag;
  return old_mode;
}

}  // extern "C++"

extern "C" {

void* calloc(size_t n, size_t elem_size) __THROW {
  // Overflow check
  const size_t size = n * elem_size;
  if (elem_size != 0 && size / elem_size != n) return NULL;

  void* result = malloc(size);
  if (result != NULL) {
    memset(result, 0, size);
  }
  return result;
}

void cfree(void* p) __THROW {
  free(p);
}

#ifdef WIN32

void* _recalloc(void* p, size_t n, size_t elem_size) {
  if (!p)
    return calloc(n, elem_size);

  // This API is a bit odd.
  // Note: recalloc only guarantees zeroed memory when p is NULL.
  //   Generally, calls to malloc() have padding.  So a request
  //   to malloc N bytes actually malloc's N+x bytes.  Later, if
  //   that buffer is passed to recalloc, we don't know what N
  //   was anymore.  We only know what N+x is.  As such, there is
  //   no way to know what to zero out.
  const size_t size = n * elem_size;
  if (elem_size != 0 && size / elem_size != n) return NULL;
  return realloc(p, size);
}

void* _calloc_impl(size_t n, size_t size) {
  return calloc(n, size);
}

#ifndef NDEBUG
#undef malloc
#undef free
#undef calloc

static int error_handler(int reportType) {
  switch (reportType) {
    case 0:  // _CRT_WARN
      __debugbreak();
      return 0;

    case 1:  // _CRT_ERROR
      __debugbreak();
      return 0;

    case 2:  // _CRT_ASSERT
      __debugbreak();
      return 0;
  }
  char* p = NULL;
  *p = '\0';
  return 0;
}

int _CrtDbgReport(int reportType,
                  const char*,
                  int, const char*,
                  const char*,
                  ...) {
  return error_handler(reportType);
}

int _CrtDbgReportW(int reportType,
                   const wchar_t*,
                   int, const wchar_t*,
                   const wchar_t*,
                   ...) {
  return error_handler(reportType);
}

int _CrtSetReportMode(int, int) {
  return 0;
}

void* _malloc_dbg(size_t size, int , const char*, int) {
  return malloc(size);
}

void _free_dbg(void* ptr, int) {
  free(ptr);
}

void* _calloc_dbg(size_t n, size_t size, int, const char*, int) {
  return calloc(n, size);
}
#endif  // NDEBUG

#endif  // WIN32

}  // extern C

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <sal/config.h>

#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/reflection/XServiceConstructorDescription.hpp>
#include <com/sun/star/reflection/XServiceTypeDescription2.hpp>
#include <test/bootstrapfixture.hxx>

using namespace css::container;
using namespace css::reflection;
using namespace css::uno;

namespace {

class ServicesTest: public test::BootstrapFixture
{
public:
    void test();

    CPPUNIT_TEST_SUITE(ServicesTest);
    CPPUNIT_TEST(test);
    CPPUNIT_TEST_SUITE_END();
};

void ServicesTest::test()
{
    Reference< XHierarchicalNameAccess > xTypeManager(
            m_xContext->getValueByName(
                "/singletons/com.sun.star.reflection.theTypeDescriptionManager"),
            UNO_QUERY_THROW );
    Sequence<OUString> s = m_xContext->getServiceManager()->getAvailableServiceNames();
    for (sal_Int32 i = 0; i < s.getLength(); i++)
    {
        if (!xTypeManager->hasByHierarchicalName(s[i]))
        {
            SAL_WARN(
                "postprocess.cppunit",
                "fantasy service name \"" << s[i] << "\"");
            continue;
        }
        Reference< XServiceTypeDescription2 > xDesc(
            xTypeManager->getByHierarchicalName(s[i]), UNO_QUERY_THROW);
        Sequence< Reference< XServiceConstructorDescription > > xseq = xDesc->getConstructors();
        for (sal_Int32 c = 0; c < xseq.getLength(); c++)
            if (!xseq[c]->getParameters().hasElements())
                try
                {
                    CPPUNIT_ASSERT_MESSAGE(
                        OUStringToOString(s[i], RTL_TEXTENCODING_UTF8).getStr(),
                        ((xseq[c]->isDefaultConstructor()
                          ? (m_xContext->getServiceManager()
                             ->createInstanceWithContext(s[i], m_xContext))
                          : (m_xContext->getServiceManager()
                             ->createInstanceWithArgumentsAndContext(
                                 s[i], css::uno::Sequence<css::uno::Any>(),
                                 m_xContext)))
                         .is()));
                }
                catch(const Exception & e)
                {
                    OString exc = "Exception thrown while creating " +
                        OUStringToOString(s[i] + ": " + e.Message, RTL_TEXTENCODING_UTF8);
                    CPPUNIT_FAIL(exc.getStr());
                }
    }
}

CPPUNIT_TEST_SUITE_REGISTRATION(ServicesTest);

}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Add more logging so that we have the info even in case of weird crashes.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <sal/config.h>

#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/reflection/XServiceConstructorDescription.hpp>
#include <com/sun/star/reflection/XServiceTypeDescription2.hpp>
#include <test/bootstrapfixture.hxx>

using namespace css::container;
using namespace css::reflection;
using namespace css::uno;

namespace {

class ServicesTest: public test::BootstrapFixture
{
public:
    void test();

    CPPUNIT_TEST_SUITE(ServicesTest);
    CPPUNIT_TEST(test);
    CPPUNIT_TEST_SUITE_END();
};

void ServicesTest::test()
{
    Reference< XHierarchicalNameAccess > xTypeManager(
            m_xContext->getValueByName(
                "/singletons/com.sun.star.reflection.theTypeDescriptionManager"),
            UNO_QUERY_THROW );
    Sequence<OUString> s = m_xContext->getServiceManager()->getAvailableServiceNames();
    for (sal_Int32 i = 0; i < s.getLength(); i++)
    {
        if (!xTypeManager->hasByHierarchicalName(s[i]))
        {
            SAL_WARN(
                "postprocess.cppunit",
                "fantasy service name \"" << s[i] << "\"");
            continue;
        }
        SAL_WARN(
                "postprocess.cppunit",
                "trying \"" << s[i] << "\"");
        Reference< XServiceTypeDescription2 > xDesc(
            xTypeManager->getByHierarchicalName(s[i]), UNO_QUERY_THROW);
        Sequence< Reference< XServiceConstructorDescription > > xseq = xDesc->getConstructors();
        for (sal_Int32 c = 0; c < xseq.getLength(); c++)
            if (!xseq[c]->getParameters().hasElements())
                try
                {
                    CPPUNIT_ASSERT_MESSAGE(
                        OUStringToOString(s[i], RTL_TEXTENCODING_UTF8).getStr(),
                        ((xseq[c]->isDefaultConstructor()
                          ? (m_xContext->getServiceManager()
                             ->createInstanceWithContext(s[i], m_xContext))
                          : (m_xContext->getServiceManager()
                             ->createInstanceWithArgumentsAndContext(
                                 s[i], css::uno::Sequence<css::uno::Any>(),
                                 m_xContext)))
                         .is()));
                }
                catch(const Exception & e)
                {
                    OString exc = "Exception thrown while creating " +
                        OUStringToOString(s[i] + ": " + e.Message, RTL_TEXTENCODING_UTF8);
                    CPPUNIT_FAIL(exc.getStr());
                }
    }
}

CPPUNIT_TEST_SUITE_REGISTRATION(ServicesTest);

}

CPPUNIT_PLUGIN_IMPLEMENT();

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


<commit_before>#include "stdafx.h"
#include <terark/util/autoclose.hpp>
#include <terark/util/linebuf.hpp>
#include <terark/util/profiling.hpp>
#include <terark/db/db_table.hpp>
#include <getopt.h>

void usage(const char* prog) {
	fprintf(stderr, "usage: %s options db-dir input-data-files...\n", prog);
}

int main(int argc, char* argv[]) {
	int inputFormat = 't';
	int compressionThreadsNum = 1;
	size_t rowsLimit = 10000000;
	for (;;) {
		int opt = getopt(argc, argv, "tjL:T:");
		switch (opt) {
		case -1:
			goto GetoptDone;
		case 'j':
		case 't':
			inputFormat = opt;
			break;
		case 'L':
			rowsLimit = strtoull(optarg, NULL, 10);
			break;
		case 'T':
			compressionThreadsNum = std::min(atoi(optarg), 8);
			break;
		}
	}
GetoptDone:
	if (optind + 2 < argc) {
		usage(argv[0]);
		return 1;
	}
	const char* dbdir = argv[optind + 0];
	terark::db::CompositeTablePtr tab(terark::db::CompositeTable::createTable("DfaDbTable"));
	terark::db::DbContextPtr ctx = tab->createDbContext();
	tab->load(dbdir);
	ctx->syncIndex = false;
	terark::LineBuf line;
	terark::valvec<unsigned char> row;
	size_t existedRows = tab->numDataRows();
	size_t skippedRows = 0;
	size_t rows = 0;
	size_t lines = 0;
	size_t bytes = 0;
	size_t colnum = tab->rowSchema().columnNum();
//	std::thread thr(std::bind(&compactThreadProc, &tab));
	for (int argIdx = optind + 1; argIdx < argc; ++argIdx) {
		const char* fname = argv[argIdx];
		terark::Auto_fclose fp(fopen(fname, "r"));
		if (!fp) {
			fprintf(stderr, "ERROR: fopen(%s, r) = %s\n", fname, strerror(errno));
			continue;
		}
		while (skippedRows < existedRows && line.getline(fp) > 0) {
			skippedRows++;
			if (skippedRows % TERARK_IF_DEBUG(100000, 1000000) == 0) {
				fprintf(stderr, "skipped %zd rows\n", skippedRows);
			}
		}
		fprintf(stderr, "total skipped %zd rows\n", skippedRows);
		while (rows < rowsLimit && line.getline(fp) > 0) {
			bytes += line.size();
			line.chomp();
			size_t parsed = tab->rowSchema().parseDelimText('\t', line, &row);
			if (parsed == colnum) {
				ctx->insertRow(row);
				rows++;
				if (lines % TERARK_IF_DEBUG(10000, 1000000) == 0) {
					printf("lines=%zd rows=%zd bytes=%zd currRow: %s\n",
						lines, rows, bytes,
						tab->rowSchema().toJsonStr(row).c_str());
					if (tab->getWritableSegNum() > 3) {
						printf("Waiting 10 seconds for compact thread catching up...\n");
						std::this_thread::sleep_for(std::chrono::seconds(10));
					}
					else {
						TERARK_IF_DEBUG(std::this_thread::sleep_for(std::chrono::seconds(2)),;);
					}
				}
			}
			lines++;
		}
	}
	printf("waiting for compact thread complete...\n");
	terark::db::CompositeTable::safeStopAndWaitForCompress();
	printf("done!\n");
    return 0;
}

<commit_msg>vs2015/terark-db/terarkdb_import/terarkdb_import.cpp: minor fix and use unix line feed<commit_after>#include "stdafx.h"
#include <terark/util/autoclose.hpp>
#include <terark/util/linebuf.hpp>
#include <terark/util/profiling.hpp>
#include <terark/db/db_table.hpp>
#include <getopt.h>

void usage(const char* prog) {
	fprintf(stderr, "usage: %s options db-dir input-data-files...\n", prog);
}

int main(int argc, char* argv[]) {
	int inputFormat = 't';
	int compressionThreadsNum = 1;
	size_t rowsLimit = 10000000;
	for (;;) {
		int opt = getopt(argc, argv, "tjL:T:");
		switch (opt) {
		case -1:
			goto GetoptDone;
		case 'j':
		case 't':
			inputFormat = opt;
			break;
		case 'L':
			rowsLimit = strtoull(optarg, NULL, 10);
			break;
		case 'T':
			compressionThreadsNum = std::min(atoi(optarg), 8);
			break;
		}
	}
GetoptDone:
	if (optind + 2 < argc) {
		usage(argv[0]);
		return 1;
	}
	const char* dbdir = argv[optind + 0];
	terark::db::CompositeTablePtr tab = terark::db::CompositeTable::open(dbdir);
	terark::db::DbContextPtr ctx = tab->createDbContext();
	ctx->syncIndex = false;
	terark::LineBuf line;
	terark::valvec<unsigned char> row;
	size_t existedRows = tab->numDataRows();
	size_t skippedRows = 0;
	size_t rows = 0;
	size_t lines = 0;
	size_t bytes = 0;
	size_t colnum = tab->rowSchema().columnNum();
	for (int argIdx = optind + 1; argIdx < argc; ++argIdx) {
		const char* fname = argv[argIdx];
		terark::Auto_fclose fp(fopen(fname, "r"));
		if (!fp) {
			fprintf(stderr, "ERROR: fopen(%s, r) = %s\n", fname, strerror(errno));
			continue;
		}
		while (skippedRows < existedRows && line.getline(fp) > 0) {
			skippedRows++;
			if (skippedRows % TERARK_IF_DEBUG(100000, 1000000) == 0) {
				fprintf(stderr, "skipped %zd rows\n", skippedRows);
			}
		}
		fprintf(stderr, "total skipped %zd rows\n", skippedRows);
		while (rows < rowsLimit && line.getline(fp) > 0) {
			bytes += line.size();
			line.chomp();
			size_t parsed = tab->rowSchema().parseDelimText('\t', line, &row);
			if (parsed == colnum) {
				ctx->insertRow(row);
				rows++;
				if (lines % TERARK_IF_DEBUG(10000, 1000000) == 0) {
					printf("lines=%zd rows=%zd bytes=%zd currRow: %s\n",
						lines, rows, bytes,
						tab->rowSchema().toJsonStr(row).c_str());
					if (tab->getWritableSegNum() > 3) {
						printf("Waiting 10 seconds for compact thread catching up...\n");
						std::this_thread::sleep_for(std::chrono::seconds(10));
					}
					else {
						TERARK_IF_DEBUG(std::this_thread::sleep_for(std::chrono::seconds(2)),;);
					}
				}
			}
			lines++;
		}
	}
	printf("waiting for compact thread complete...\n");
	terark::db::CompositeTable::safeStopAndWaitForCompress();
	printf("done!\n");
    return 0;
}

<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file contains the implementation of TestWebViewDelegate, which serves
// as the WebViewDelegate for the TestShellWebHost.  The host is expected to
// have initialized a MessageLoop before these methods are called.

#include "webkit/tools/test_shell/test_webview_delegate.h"

#include <objidl.h>
#include <shlobj.h>
#include <shlwapi.h>

#include "base/gfx/point.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/trace_event.h"
#include "net/base/net_errors.h"
#include "webkit/glue/webdatasource.h"
#include "webkit/glue/webdropdata.h"
#include "webkit/glue/weberror.h"
#include "webkit/glue/webframe.h"
#include "webkit/glue/webpreferences.h"
#include "webkit/glue/weburlrequest.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webview.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include "webkit/glue/window_open_disposition.h"
#include "webkit/tools/test_shell/drag_delegate.h"
#include "webkit/tools/test_shell/drop_delegate.h"
#include "webkit/tools/test_shell/test_navigation_controller.h"
#include "webkit/tools/test_shell/test_shell.h"

// WebViewDelegate -----------------------------------------------------------

TestWebViewDelegate::~TestWebViewDelegate() {
  if (custom_cursor_)
    DestroyIcon(custom_cursor_);
  RevokeDragDrop(shell_->webViewWnd());
}

WebPluginDelegate* TestWebViewDelegate::CreatePluginDelegate(
    WebView* webview,
    const GURL& url,
    const std::string& mime_type,
    const std::string& clsid,
    std::string* actual_mime_type) {
  HWND hwnd = GetContainingWindow(webview);
  if (!hwnd)
    return NULL;

  bool allow_wildcard = true;
  WebPluginInfo info;
  if (!NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid,
                                                     allow_wildcard, &info,
                                                     actual_mime_type))
    return NULL;

  if (actual_mime_type && !actual_mime_type->empty())
    return WebPluginDelegateImpl::Create(info.file, *actual_mime_type, hwnd);
  else
    return WebPluginDelegateImpl::Create(info.file, mime_type, hwnd);
}

void TestWebViewDelegate::ShowJavaScriptAlert(const std::wstring& message) {
}

void TestWebViewDelegate::Show(WebWidget* webwidget, WindowOpenDisposition) {
  if (webwidget == shell_->webView()) {
    ShowWindow(shell_->mainWnd(), SW_SHOW);
    UpdateWindow(shell_->mainWnd());
  } else if (webwidget == shell_->popup()) {
    ShowWindow(shell_->popupWnd(), SW_SHOW);
    UpdateWindow(shell_->popupWnd());
  }
}

void TestWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) {
  if (webwidget == shell_->webView()) {
    PostMessage(shell_->mainWnd(), WM_CLOSE, 0, 0);
  } else if (webwidget == shell_->popup()) {
    shell_->ClosePopup();
  }
}

void TestWebViewDelegate::SetCursor(WebWidget* webwidget,
                                    const WebCursor& cursor) {
  if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
    if (custom_cursor_) {
      DestroyIcon(custom_cursor_);
      custom_cursor_ = NULL;
    }
    if (cursor.IsCustom()) {
      custom_cursor_ = cursor.GetCustomCursor();
      host->SetCursor(custom_cursor_);
    } else {
      HINSTANCE mod_handle = GetModuleHandle(NULL);
      host->SetCursor(cursor.GetCursor(mod_handle));
    }
  }
}

void TestWebViewDelegate::GetWindowRect(WebWidget* webwidget,
                                        gfx::Rect* out_rect) {
  if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
    RECT rect;
    ::GetWindowRect(host->view_handle(), &rect);
    *out_rect = gfx::Rect(rect);
  }
}

void TestWebViewDelegate::SetWindowRect(WebWidget* webwidget,
                                        const gfx::Rect& rect) {
  if (webwidget == shell_->webView()) {
    // ignored
  } else if (webwidget == shell_->popup()) {
    MoveWindow(shell_->popupWnd(),
               rect.x(), rect.y(), rect.width(), rect.height(), FALSE);
  }
}

void TestWebViewDelegate::GetRootWindowRect(WebWidget* webwidget,
                                            gfx::Rect* out_rect) {
  if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
    RECT rect;
    HWND root_window = ::GetAncestor(host->view_handle(), GA_ROOT);
    ::GetWindowRect(root_window, &rect);
    *out_rect = gfx::Rect(rect);
  }
}

void TestWebViewDelegate::GetRootWindowResizerRect(WebWidget* webwidget,
                                                   gfx::Rect* out_rect) {
  // Not necessary on Windows.
  *out_rect = gfx::Rect();
}

void TestWebViewDelegate::RunModal(WebWidget* webwidget) {
  Show(webwidget, NEW_WINDOW);

  WindowList* wl = TestShell::windowList();
  for (WindowList::const_iterator i = wl->begin(); i != wl->end(); ++i) {
    if (*i != shell_->mainWnd())
      EnableWindow(*i, FALSE);
  }

  shell_->set_is_modal(true);
  MessageLoop::current()->Run();

  for (WindowList::const_iterator i = wl->begin(); i != wl->end(); ++i)
    EnableWindow(*i, TRUE);
}

// Private methods -----------------------------------------------------------

void TestWebViewDelegate::SetPageTitle(const std::wstring& title) {
  // The Windows test shell, pre-refactoring, ignored this.  *shrug*
}

void TestWebViewDelegate::SetAddressBarURL(const GURL& url) {
  std::wstring url_string = UTF8ToWide(url.spec());
  SendMessage(shell_->editWnd(), WM_SETTEXT, 0,
              reinterpret_cast<LPARAM>(url_string.c_str()));
}

<commit_msg>The javascript alert dialog was removed from test shell. I assume this is an accident; as I'd like to have it back! :-)<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file contains the implementation of TestWebViewDelegate, which serves
// as the WebViewDelegate for the TestShellWebHost.  The host is expected to
// have initialized a MessageLoop before these methods are called.

#include "webkit/tools/test_shell/test_webview_delegate.h"

#include <objidl.h>
#include <shlobj.h>
#include <shlwapi.h>

#include "base/gfx/point.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/trace_event.h"
#include "net/base/net_errors.h"
#include "webkit/glue/webdatasource.h"
#include "webkit/glue/webdropdata.h"
#include "webkit/glue/weberror.h"
#include "webkit/glue/webframe.h"
#include "webkit/glue/webpreferences.h"
#include "webkit/glue/weburlrequest.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webview.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include "webkit/glue/window_open_disposition.h"
#include "webkit/tools/test_shell/drag_delegate.h"
#include "webkit/tools/test_shell/drop_delegate.h"
#include "webkit/tools/test_shell/test_navigation_controller.h"
#include "webkit/tools/test_shell/test_shell.h"

// WebViewDelegate -----------------------------------------------------------

TestWebViewDelegate::~TestWebViewDelegate() {
  if (custom_cursor_)
    DestroyIcon(custom_cursor_);
  RevokeDragDrop(shell_->webViewWnd());
}

WebPluginDelegate* TestWebViewDelegate::CreatePluginDelegate(
    WebView* webview,
    const GURL& url,
    const std::string& mime_type,
    const std::string& clsid,
    std::string* actual_mime_type) {
  HWND hwnd = GetContainingWindow(webview);
  if (!hwnd)
    return NULL;

  bool allow_wildcard = true;
  WebPluginInfo info;
  if (!NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid,
                                                     allow_wildcard, &info,
                                                     actual_mime_type))
    return NULL;

  if (actual_mime_type && !actual_mime_type->empty())
    return WebPluginDelegateImpl::Create(info.file, *actual_mime_type, hwnd);
  else
    return WebPluginDelegateImpl::Create(info.file, mime_type, hwnd);
}

void TestWebViewDelegate::ShowJavaScriptAlert(const std::wstring& message) {
  MessageBox(NULL, message.c_str(), L"JavaScript Alert", MB_OK);
}

void TestWebViewDelegate::Show(WebWidget* webwidget, WindowOpenDisposition) {
  if (webwidget == shell_->webView()) {
    ShowWindow(shell_->mainWnd(), SW_SHOW);
    UpdateWindow(shell_->mainWnd());
  } else if (webwidget == shell_->popup()) {
    ShowWindow(shell_->popupWnd(), SW_SHOW);
    UpdateWindow(shell_->popupWnd());
  }
}

void TestWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) {
  if (webwidget == shell_->webView()) {
    PostMessage(shell_->mainWnd(), WM_CLOSE, 0, 0);
  } else if (webwidget == shell_->popup()) {
    shell_->ClosePopup();
  }
}

void TestWebViewDelegate::SetCursor(WebWidget* webwidget,
                                    const WebCursor& cursor) {
  if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
    if (custom_cursor_) {
      DestroyIcon(custom_cursor_);
      custom_cursor_ = NULL;
    }
    if (cursor.IsCustom()) {
      custom_cursor_ = cursor.GetCustomCursor();
      host->SetCursor(custom_cursor_);
    } else {
      HINSTANCE mod_handle = GetModuleHandle(NULL);
      host->SetCursor(cursor.GetCursor(mod_handle));
    }
  }
}

void TestWebViewDelegate::GetWindowRect(WebWidget* webwidget,
                                        gfx::Rect* out_rect) {
  if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
    RECT rect;
    ::GetWindowRect(host->view_handle(), &rect);
    *out_rect = gfx::Rect(rect);
  }
}

void TestWebViewDelegate::SetWindowRect(WebWidget* webwidget,
                                        const gfx::Rect& rect) {
  if (webwidget == shell_->webView()) {
    // ignored
  } else if (webwidget == shell_->popup()) {
    MoveWindow(shell_->popupWnd(),
               rect.x(), rect.y(), rect.width(), rect.height(), FALSE);
  }
}

void TestWebViewDelegate::GetRootWindowRect(WebWidget* webwidget,
                                            gfx::Rect* out_rect) {
  if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
    RECT rect;
    HWND root_window = ::GetAncestor(host->view_handle(), GA_ROOT);
    ::GetWindowRect(root_window, &rect);
    *out_rect = gfx::Rect(rect);
  }
}

void TestWebViewDelegate::GetRootWindowResizerRect(WebWidget* webwidget,
                                                   gfx::Rect* out_rect) {
  // Not necessary on Windows.
  *out_rect = gfx::Rect();
}

void TestWebViewDelegate::RunModal(WebWidget* webwidget) {
  Show(webwidget, NEW_WINDOW);

  WindowList* wl = TestShell::windowList();
  for (WindowList::const_iterator i = wl->begin(); i != wl->end(); ++i) {
    if (*i != shell_->mainWnd())
      EnableWindow(*i, FALSE);
  }

  shell_->set_is_modal(true);
  MessageLoop::current()->Run();

  for (WindowList::const_iterator i = wl->begin(); i != wl->end(); ++i)
    EnableWindow(*i, TRUE);
}

// Private methods -----------------------------------------------------------

void TestWebViewDelegate::SetPageTitle(const std::wstring& title) {
  // The Windows test shell, pre-refactoring, ignored this.  *shrug*
}

void TestWebViewDelegate::SetAddressBarURL(const GURL& url) {
  std::wstring url_string = UTF8ToWide(url.spec());
  SendMessage(shell_->editWnd(), WM_SETTEXT, 0,
              reinterpret_cast<LPARAM>(url_string.c_str()));
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: XMLLineNumberingImportContext.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: mib $ $Date: 2001-03-19 09:41:43 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLLINENUMBERINGIMPORTCONTEXT_HXX_
#include "XMLLineNumberingImportContext.hxx"
#endif

#ifndef _XMLOFF_XMLLINENUMBERINGSEPARATORIMPORTCONTEXT_HXX_
#include "XMLLineNumberingSeparatorImportContext.hxx"
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include "com/sun/star/beans/XPropertySet.hpp"
#endif

#ifndef _COM_SUN_STAR_TEXT_XLINENUMBERINGPROPERTIES_HPP_
#include "com/sun/star/text/XLineNumberingProperties.hpp"
#endif

#ifndef _COM_SUN_STAR_STYLE_LINENUMBERPOSITION_HPP_
#include <com/sun/star/style/LineNumberPosition.hpp>
#endif
#ifndef _COM_SUN_STAR_STYLE_NUMBERINGTYPE_HPP_
#include <com/sun/star/style/NumberingType.hpp>
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include "xmlimp.hxx"
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif

#ifndef _XMLOFF_XMLKYWD_HXX
#include "xmlkywd.hxx"
#endif

#ifndef _XMLOFF_XMLNUMI_HXX
#include "xmlnumi.hxx"
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::style;

using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::text::XLineNumberingProperties;
using ::rtl::OUString;

TYPEINIT1( XMLLineNumberingImportContext, SvXMLStyleContext );

XMLLineNumberingImportContext::XMLLineNumberingImportContext(
    SvXMLImport& rImport,
    sal_uInt16 nPrfx,
    const OUString& rLocalName,
    const Reference<XAttributeList> & xAttrList) :
        SvXMLStyleContext(rImport, nPrfx, rLocalName, xAttrList, XML_STYLE_FAMILY_TEXT_LINENUMBERINGCONFIG),
        sStyleName(),
        sNumFormat(RTL_CONSTASCII_USTRINGPARAM(sXML_1)),
        sNumLetterSync(RTL_CONSTASCII_USTRINGPARAM(sXML_false)),
        sSeparator(),
        nOffset(-1),
        nNumberPosition(style::LineNumberPosition::LEFT),
        nIncrement(-1),
        nSeparatorIncrement(-1),
        bNumberLines(sal_True),
        bCountEmptyLines(sal_True),
        bCountInFloatingFrames(sal_False),
        bRestartNumbering(sal_False),
        sCharStyleName(RTL_CONSTASCII_USTRINGPARAM("CharStyleName")),
        sCountEmptyLines(RTL_CONSTASCII_USTRINGPARAM("CountEmptyLines")),
        sCountLinesInFrames(RTL_CONSTASCII_USTRINGPARAM("CountLinesInFrames")),
        sDistance(RTL_CONSTASCII_USTRINGPARAM("Distance")),
        sInterval(RTL_CONSTASCII_USTRINGPARAM("Interval")),
        sSeparatorText(RTL_CONSTASCII_USTRINGPARAM("SeparatorText")),
        sNumberPosition(RTL_CONSTASCII_USTRINGPARAM("NumberPosition")),
        sNumberingType(RTL_CONSTASCII_USTRINGPARAM("NumberingType")),
        sIsOn(RTL_CONSTASCII_USTRINGPARAM("IsOn")),
        sRestartAtEachPage(RTL_CONSTASCII_USTRINGPARAM("RestartAtEachPage")),
        sSeparatorInterval(RTL_CONSTASCII_USTRINGPARAM("SeparatorInterval"))
{
}

XMLLineNumberingImportContext::~XMLLineNumberingImportContext()
{
}

static const SvXMLEnumMapEntry aLineNumberPositionMap[] =
{
    { sXML_left,    style::LineNumberPosition::LEFT },
    { sXML_right,   style::LineNumberPosition::RIGHT },
    { sXML_inside,  style::LineNumberPosition::INSIDE },
    { sXML_outside, style::LineNumberPosition::OUTSIDE },
    { NULL, 0 }
};

static SvXMLTokenMapEntry aLineNumberingTokenMap[] =
{
    { XML_NAMESPACE_TEXT, sXML_style_name, XML_TOK_LINENUMBERING_STYLE_NAME },
    { XML_NAMESPACE_TEXT, sXML_number_lines,
          XML_TOK_LINENUMBERING_NUMBER_LINES },
    { XML_NAMESPACE_TEXT, sXML_count_empty_lines,
          XML_TOK_LINENUMBERING_COUNT_EMPTY_LINES },
    { XML_NAMESPACE_TEXT, sXML_count_in_floating_frames,
          XML_TOK_LINENUMBERING_COUNT_IN_FLOATING_FRAMES },
    { XML_NAMESPACE_TEXT, sXML_restart_on_page,
          XML_TOK_LINENUMBERING_RESTART_NUMBERING },
    { XML_NAMESPACE_TEXT, sXML_offset, XML_TOK_LINENUMBERING_OFFSET },
    { XML_NAMESPACE_STYLE, sXML_num_format, XML_TOK_LINENUMBERING_NUM_FORMAT },
    { XML_NAMESPACE_STYLE, sXML_num_letter_sync,
          XML_TOK_LINENUMBERING_NUM_LETTER_SYNC },
    { XML_NAMESPACE_TEXT, sXML_number_position,
          XML_TOK_LINENUMBERING_NUMBER_POSITION },
    { XML_NAMESPACE_TEXT, sXML_increment, XML_TOK_LINENUMBERING_INCREMENT },
//  { XML_NAMESPACE_TEXT, sXML_linenumbering_configuration,
//        XML_TOK_LINENUMBERING_LINENUMBERING_CONFIGURATION },
//  { XML_NAMESPACE_TEXT, sXML_increment, XML_TOK_LINENUMBERING_INCREMENT },
//  { XML_NAMESPACE_TEXT, sXML_linenumbering_separator,
//        XML_TOK_LINENUMBERING_LINENUMBERING_SEPARATOR },

    XML_TOKEN_MAP_END
};

void XMLLineNumberingImportContext::StartElement(
    const Reference<XAttributeList> & xAttrList)
{
    SvXMLTokenMap aTokenMap(aLineNumberingTokenMap);

    // process attributes
    sal_Int16 nLength = xAttrList->getLength();
    for(sal_Int16 i=0; i<nLength; i++)
    {
        OUString sLocalName;
        sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
            GetKeyByAttrName( xAttrList->getNameByIndex(i), &sLocalName );

        ProcessAttribute(
            (enum LineNumberingToken)aTokenMap.Get(nPrefix, sLocalName),
            xAttrList->getValueByIndex(i));
    }
}

void XMLLineNumberingImportContext::ProcessAttribute(
    enum LineNumberingToken eToken,
    OUString sValue)
{
    sal_Bool bTmp;
    sal_Int32 nTmp;

    switch (eToken)
    {
        case XML_TOK_LINENUMBERING_STYLE_NAME:
            sStyleName = sValue;
            break;

        case XML_TOK_LINENUMBERING_NUMBER_LINES:
            if (SvXMLUnitConverter::convertBool(bTmp, sValue))
            {
                bNumberLines = bTmp;
            }
            break;

        case XML_TOK_LINENUMBERING_COUNT_EMPTY_LINES:
            if (SvXMLUnitConverter::convertBool(bTmp, sValue))
            {
                bCountEmptyLines = bTmp;
            }
            break;

        case XML_TOK_LINENUMBERING_COUNT_IN_FLOATING_FRAMES:
            if (SvXMLUnitConverter::convertBool(bTmp, sValue))
            {
                bCountInFloatingFrames = bTmp;
            }
            break;

        case XML_TOK_LINENUMBERING_RESTART_NUMBERING:
            if (SvXMLUnitConverter::convertBool(bTmp, sValue))
            {
                bRestartNumbering = bTmp;
            }
            break;

        case XML_TOK_LINENUMBERING_OFFSET:
            if (GetImport().GetMM100UnitConverter().
                convertMeasure(nTmp, sValue))
            {
                nOffset = nTmp;
            }
            break;

        case XML_TOK_LINENUMBERING_NUM_FORMAT:
            sNumFormat = sValue;
            break;

        case XML_TOK_LINENUMBERING_NUM_LETTER_SYNC:
            sNumLetterSync = sValue;
            break;

        case XML_TOK_LINENUMBERING_NUMBER_POSITION:
        {
            sal_uInt16 nTmp;
            if (SvXMLUnitConverter::convertEnum(nTmp, sValue,
                                                aLineNumberPositionMap))
            {
                nNumberPosition = nTmp;
            }
            break;
        }

        case XML_TOK_LINENUMBERING_INCREMENT:
            if (SvXMLUnitConverter::convertNumber(nTmp, sValue, 0))
            {
                nIncrement = (sal_Int16)nTmp;
            }
            break;
    }
}

void XMLLineNumberingImportContext::CreateAndInsert(
    sal_Bool bOverwrite)
{
    // insert and block mode is handled in insertStyleFamily

    // we'll try to get the LineNumberingProperties
    Reference<XLineNumberingProperties> xSupplier(GetImport().GetModel(),
                                                  UNO_QUERY);
    if (xSupplier.is())
    {
        Reference<XPropertySet> xLineNumbering =
            xSupplier->getLineNumberingProperties();

        if (xLineNumbering.is())
        {
            Any aAny;

            // TODO: check if style name exists
            aAny <<= sStyleName;
            xLineNumbering->setPropertyValue(sCharStyleName, aAny);

            aAny <<= sSeparator;
            xLineNumbering->setPropertyValue(sSeparatorText, aAny);

            aAny <<= nOffset;
            xLineNumbering->setPropertyValue(sDistance, aAny);

            aAny <<= nNumberPosition;
            xLineNumbering->setPropertyValue(sNumberPosition, aAny);

            if (nIncrement >= 0)
            {
                aAny <<= nIncrement;
                xLineNumbering->setPropertyValue(sInterval, aAny);
            }

            if (nSeparatorIncrement >= 0)
            {
                aAny <<= nSeparatorIncrement;
                xLineNumbering->setPropertyValue(sSeparatorInterval, aAny);
            }

            aAny.setValue(&bNumberLines, ::getBooleanCppuType());
            xLineNumbering->setPropertyValue(sIsOn, aAny);

            aAny.setValue(&bCountEmptyLines, ::getBooleanCppuType());
            xLineNumbering->setPropertyValue(sCountEmptyLines, aAny);

            aAny.setValue(&bCountInFloatingFrames, ::getBooleanCppuType());
            xLineNumbering->setPropertyValue(sCountLinesInFrames, aAny);

            aAny.setValue(&bRestartNumbering, ::getBooleanCppuType());
            xLineNumbering->setPropertyValue(sRestartAtEachPage, aAny);

            sal_Int16 nNumType = NumberingType::ARABIC;
            GetImport().GetMM100UnitConverter().convertNumFormat( nNumType,
                                                    sNumFormat,
                                                    sNumLetterSync );
            aAny <<= nNumType;
            xLineNumbering->setPropertyValue(sNumberingType, aAny);
        }
    }
}

SvXMLImportContext* XMLLineNumberingImportContext::CreateChildContext(
    sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const Reference<XAttributeList> & xAttrList )
{
    if ( (nPrefix == XML_NAMESPACE_TEXT) &&
         rLocalName.equalsAsciiL(sXML_linenumbering_separator,
                                 sizeof(sXML_linenumbering_separator)-1) )
    {
        return new XMLLineNumberingSeparatorImportContext(GetImport(),
                                                          nPrefix, rLocalName,
                                                          *this);
    }
    else
    {
        // unknown element: default context
        return SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
                                                      xAttrList);
    }
}

void XMLLineNumberingImportContext::SetSeparatorText(
    const OUString& sText)
{
    sSeparator = sText;
}

void XMLLineNumberingImportContext::SetSeparatorIncrement(
    sal_Int16 nIncr)
{
    nSeparatorIncrement = nIncr;
}

<commit_msg>#87257# check for valid character style in line numbering config<commit_after>/*************************************************************************
 *
 *  $RCSfile: XMLLineNumberingImportContext.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: dvo $ $Date: 2001-05-30 10:21:38 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _XMLOFF_XMLLINENUMBERINGIMPORTCONTEXT_HXX_
#include "XMLLineNumberingImportContext.hxx"
#endif

#ifndef _XMLOFF_XMLLINENUMBERINGSEPARATORIMPORTCONTEXT_HXX_
#include "XMLLineNumberingSeparatorImportContext.hxx"
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include "com/sun/star/beans/XPropertySet.hpp"
#endif

#ifndef _COM_SUN_STAR_TEXT_XLINENUMBERINGPROPERTIES_HPP_
#include "com/sun/star/text/XLineNumberingProperties.hpp"
#endif

#ifndef _COM_SUN_STAR_STYLE_LINENUMBERPOSITION_HPP_
#include <com/sun/star/style/LineNumberPosition.hpp>
#endif
#ifndef _COM_SUN_STAR_STYLE_NUMBERINGTYPE_HPP_
#include <com/sun/star/style/NumberingType.hpp>
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include "xmlimp.hxx"
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif

#ifndef _XMLOFF_XMLKYWD_HXX
#include "xmlkywd.hxx"
#endif

#ifndef _XMLOFF_XMLNUMI_HXX
#include "xmlnumi.hxx"
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::style;

using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::text::XLineNumberingProperties;
using ::rtl::OUString;

TYPEINIT1( XMLLineNumberingImportContext, SvXMLStyleContext );

XMLLineNumberingImportContext::XMLLineNumberingImportContext(
    SvXMLImport& rImport,
    sal_uInt16 nPrfx,
    const OUString& rLocalName,
    const Reference<XAttributeList> & xAttrList) :
        SvXMLStyleContext(rImport, nPrfx, rLocalName, xAttrList, XML_STYLE_FAMILY_TEXT_LINENUMBERINGCONFIG),
        sStyleName(),
        sNumFormat(RTL_CONSTASCII_USTRINGPARAM(sXML_1)),
        sNumLetterSync(RTL_CONSTASCII_USTRINGPARAM(sXML_false)),
        sSeparator(),
        nOffset(-1),
        nNumberPosition(style::LineNumberPosition::LEFT),
        nIncrement(-1),
        nSeparatorIncrement(-1),
        bNumberLines(sal_True),
        bCountEmptyLines(sal_True),
        bCountInFloatingFrames(sal_False),
        bRestartNumbering(sal_False),
        sCharStyleName(RTL_CONSTASCII_USTRINGPARAM("CharStyleName")),
        sCountEmptyLines(RTL_CONSTASCII_USTRINGPARAM("CountEmptyLines")),
        sCountLinesInFrames(RTL_CONSTASCII_USTRINGPARAM("CountLinesInFrames")),
        sDistance(RTL_CONSTASCII_USTRINGPARAM("Distance")),
        sInterval(RTL_CONSTASCII_USTRINGPARAM("Interval")),
        sSeparatorText(RTL_CONSTASCII_USTRINGPARAM("SeparatorText")),
        sNumberPosition(RTL_CONSTASCII_USTRINGPARAM("NumberPosition")),
        sNumberingType(RTL_CONSTASCII_USTRINGPARAM("NumberingType")),
        sIsOn(RTL_CONSTASCII_USTRINGPARAM("IsOn")),
        sRestartAtEachPage(RTL_CONSTASCII_USTRINGPARAM("RestartAtEachPage")),
        sSeparatorInterval(RTL_CONSTASCII_USTRINGPARAM("SeparatorInterval"))
{
}

XMLLineNumberingImportContext::~XMLLineNumberingImportContext()
{
}

static const SvXMLEnumMapEntry aLineNumberPositionMap[] =
{
    { sXML_left,    style::LineNumberPosition::LEFT },
    { sXML_right,   style::LineNumberPosition::RIGHT },
    { sXML_inside,  style::LineNumberPosition::INSIDE },
    { sXML_outside, style::LineNumberPosition::OUTSIDE },
    { NULL, 0 }
};

static SvXMLTokenMapEntry aLineNumberingTokenMap[] =
{
    { XML_NAMESPACE_TEXT, sXML_style_name, XML_TOK_LINENUMBERING_STYLE_NAME },
    { XML_NAMESPACE_TEXT, sXML_number_lines,
          XML_TOK_LINENUMBERING_NUMBER_LINES },
    { XML_NAMESPACE_TEXT, sXML_count_empty_lines,
          XML_TOK_LINENUMBERING_COUNT_EMPTY_LINES },
    { XML_NAMESPACE_TEXT, sXML_count_in_floating_frames,
          XML_TOK_LINENUMBERING_COUNT_IN_FLOATING_FRAMES },
    { XML_NAMESPACE_TEXT, sXML_restart_on_page,
          XML_TOK_LINENUMBERING_RESTART_NUMBERING },
    { XML_NAMESPACE_TEXT, sXML_offset, XML_TOK_LINENUMBERING_OFFSET },
    { XML_NAMESPACE_STYLE, sXML_num_format, XML_TOK_LINENUMBERING_NUM_FORMAT },
    { XML_NAMESPACE_STYLE, sXML_num_letter_sync,
          XML_TOK_LINENUMBERING_NUM_LETTER_SYNC },
    { XML_NAMESPACE_TEXT, sXML_number_position,
          XML_TOK_LINENUMBERING_NUMBER_POSITION },
    { XML_NAMESPACE_TEXT, sXML_increment, XML_TOK_LINENUMBERING_INCREMENT },
//  { XML_NAMESPACE_TEXT, sXML_linenumbering_configuration,
//        XML_TOK_LINENUMBERING_LINENUMBERING_CONFIGURATION },
//  { XML_NAMESPACE_TEXT, sXML_increment, XML_TOK_LINENUMBERING_INCREMENT },
//  { XML_NAMESPACE_TEXT, sXML_linenumbering_separator,
//        XML_TOK_LINENUMBERING_LINENUMBERING_SEPARATOR },

    XML_TOKEN_MAP_END
};

void XMLLineNumberingImportContext::StartElement(
    const Reference<XAttributeList> & xAttrList)
{
    SvXMLTokenMap aTokenMap(aLineNumberingTokenMap);

    // process attributes
    sal_Int16 nLength = xAttrList->getLength();
    for(sal_Int16 i=0; i<nLength; i++)
    {
        OUString sLocalName;
        sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
            GetKeyByAttrName( xAttrList->getNameByIndex(i), &sLocalName );

        ProcessAttribute(
            (enum LineNumberingToken)aTokenMap.Get(nPrefix, sLocalName),
            xAttrList->getValueByIndex(i));
    }
}

void XMLLineNumberingImportContext::ProcessAttribute(
    enum LineNumberingToken eToken,
    OUString sValue)
{
    sal_Bool bTmp;
    sal_Int32 nTmp;

    switch (eToken)
    {
        case XML_TOK_LINENUMBERING_STYLE_NAME:
            sStyleName = sValue;
            break;

        case XML_TOK_LINENUMBERING_NUMBER_LINES:
            if (SvXMLUnitConverter::convertBool(bTmp, sValue))
            {
                bNumberLines = bTmp;
            }
            break;

        case XML_TOK_LINENUMBERING_COUNT_EMPTY_LINES:
            if (SvXMLUnitConverter::convertBool(bTmp, sValue))
            {
                bCountEmptyLines = bTmp;
            }
            break;

        case XML_TOK_LINENUMBERING_COUNT_IN_FLOATING_FRAMES:
            if (SvXMLUnitConverter::convertBool(bTmp, sValue))
            {
                bCountInFloatingFrames = bTmp;
            }
            break;

        case XML_TOK_LINENUMBERING_RESTART_NUMBERING:
            if (SvXMLUnitConverter::convertBool(bTmp, sValue))
            {
                bRestartNumbering = bTmp;
            }
            break;

        case XML_TOK_LINENUMBERING_OFFSET:
            if (GetImport().GetMM100UnitConverter().
                convertMeasure(nTmp, sValue))
            {
                nOffset = nTmp;
            }
            break;

        case XML_TOK_LINENUMBERING_NUM_FORMAT:
            sNumFormat = sValue;
            break;

        case XML_TOK_LINENUMBERING_NUM_LETTER_SYNC:
            sNumLetterSync = sValue;
            break;

        case XML_TOK_LINENUMBERING_NUMBER_POSITION:
        {
            sal_uInt16 nTmp;
            if (SvXMLUnitConverter::convertEnum(nTmp, sValue,
                                                aLineNumberPositionMap))
            {
                nNumberPosition = nTmp;
            }
            break;
        }

        case XML_TOK_LINENUMBERING_INCREMENT:
            if (SvXMLUnitConverter::convertNumber(nTmp, sValue, 0))
            {
                nIncrement = (sal_Int16)nTmp;
            }
            break;
    }
}

void XMLLineNumberingImportContext::CreateAndInsert(
    sal_Bool bOverwrite)
{
    // insert and block mode is handled in insertStyleFamily

    // we'll try to get the LineNumberingProperties
    Reference<XLineNumberingProperties> xSupplier(GetImport().GetModel(),
                                                  UNO_QUERY);
    if (xSupplier.is())
    {
        Reference<XPropertySet> xLineNumbering =
            xSupplier->getLineNumberingProperties();

        if (xLineNumbering.is())
        {
            Any aAny;

            // set style name (if it exists)
            if ( GetImport().GetStyles()->FindStyleChildContext(
                            XML_STYLE_FAMILY_TEXT_TEXT, sStyleName ) != NULL )
            {
                aAny <<= sStyleName;
                xLineNumbering->setPropertyValue(sCharStyleName, aAny);
            }

            aAny <<= sSeparator;
            xLineNumbering->setPropertyValue(sSeparatorText, aAny);

            aAny <<= nOffset;
            xLineNumbering->setPropertyValue(sDistance, aAny);

            aAny <<= nNumberPosition;
            xLineNumbering->setPropertyValue(sNumberPosition, aAny);

            if (nIncrement >= 0)
            {
                aAny <<= nIncrement;
                xLineNumbering->setPropertyValue(sInterval, aAny);
            }

            if (nSeparatorIncrement >= 0)
            {
                aAny <<= nSeparatorIncrement;
                xLineNumbering->setPropertyValue(sSeparatorInterval, aAny);
            }

            aAny.setValue(&bNumberLines, ::getBooleanCppuType());
            xLineNumbering->setPropertyValue(sIsOn, aAny);

            aAny.setValue(&bCountEmptyLines, ::getBooleanCppuType());
            xLineNumbering->setPropertyValue(sCountEmptyLines, aAny);

            aAny.setValue(&bCountInFloatingFrames, ::getBooleanCppuType());
            xLineNumbering->setPropertyValue(sCountLinesInFrames, aAny);

            aAny.setValue(&bRestartNumbering, ::getBooleanCppuType());
            xLineNumbering->setPropertyValue(sRestartAtEachPage, aAny);

            sal_Int16 nNumType = NumberingType::ARABIC;
            GetImport().GetMM100UnitConverter().convertNumFormat( nNumType,
                                                    sNumFormat,
                                                    sNumLetterSync );
            aAny <<= nNumType;
            xLineNumbering->setPropertyValue(sNumberingType, aAny);
        }
    }
}

SvXMLImportContext* XMLLineNumberingImportContext::CreateChildContext(
    sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const Reference<XAttributeList> & xAttrList )
{
    if ( (nPrefix == XML_NAMESPACE_TEXT) &&
         rLocalName.equalsAsciiL(sXML_linenumbering_separator,
                                 sizeof(sXML_linenumbering_separator)-1) )
    {
        return new XMLLineNumberingSeparatorImportContext(GetImport(),
                                                          nPrefix, rLocalName,
                                                          *this);
    }
    else
    {
        // unknown element: default context
        return SvXMLImportContext::CreateChildContext(nPrefix, rLocalName,
                                                      xAttrList);
    }
}

void XMLLineNumberingImportContext::SetSeparatorText(
    const OUString& sText)
{
    sSeparator = sText;
}

void XMLLineNumberingImportContext::SetSeparatorIncrement(
    sal_Int16 nIncr)
{
    nSeparatorIncrement = nIncr;
}

<|endoftext|>


<commit_before>/*
    Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
    Copyright (c) 2007 Volker Krause <vkrause@kde.org>

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

    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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "itemsync.h"

#include <libakonadi/item.h>
#include <libakonadi/itemappendjob.h>
#include <libakonadi/itemdeletejob.h>
#include <libakonadi/itemfetchjob.h>
#include <libakonadi/itemstorejob.h>

#include <kdebug.h>

using namespace Akonadi;

class ItemSync::Private
{
  public:
    Private() :
      pendingJobs( 0 ),
      progress( 0 ),
      incremental( false )
    {
    }

    Collection syncCollection;

    // local: mapped id -> item
    QHash<int, Akonadi::Item> localItems;
    QSet<Akonadi::Item> unprocessedLocalItems;

    // remote items
    Akonadi::Item::List remoteItems;

    // removed remote items
    Item::List removedRemoteItems;

    // create counter
    int pendingJobs;
    int progress;

    bool incremental;
};

ItemSync::ItemSync( const Collection &collection, QObject *parent ) :
    TransactionSequence( parent ),
    d( new Private )
{
  d->syncCollection = collection;
}

ItemSync::~ItemSync()
{
  delete d;
}

void ItemSync::setRemoteItems( const Item::List & remoteItems )
{
  d->remoteItems = remoteItems;
  setTotalAmount( KJob::Bytes, d->remoteItems.count() );
}

void ItemSync::setRemoteItems( const Item::List & changedItems, const Item::List & removedItems )
{
  d->incremental = true;
  d->remoteItems = changedItems;
  d->removedRemoteItems = removedItems;
  setTotalAmount( KJob::Bytes, d->remoteItems.count() + d->removedRemoteItems.count() );
}

void ItemSync::doStart()
{
  ItemFetchJob* job = new ItemFetchJob( d->syncCollection, this );
  // FIXME this will deadlock, we only can fetch parts already in the cache
//   if ( !d->incremental )
//     job->fetchAllParts();

  connect( job, SIGNAL( result( KJob* ) ), SLOT( slotLocalListDone( KJob* ) ) );
}

void ItemSync::slotLocalListDone( KJob * job )
{
  if ( job->error() )
    return;

  const Item::List list = static_cast<ItemFetchJob*>( job )->items();
  foreach ( const Item item, list ) {
    d->localItems.insert( item.reference().id(), item );
    d->unprocessedLocalItems.insert( item );
  }

  // added / updated
  foreach ( const Item remoteItem, d->remoteItems ) {
#ifndef NDEBUG
    if ( remoteItem.reference().remoteId().isEmpty() ) {
      kWarning( 5250 ) << "Item " << remoteItem.reference().id() << " does not have a remote identifier";
    }
#endif

    const Item localItem = d->localItems.value( remoteItem.reference().id() );
    d->unprocessedLocalItems.remove( localItem );
    // missing locally
    if ( !localItem.isValid() ) {
      createLocalItem( remoteItem );
      continue;
    }

    bool needsUpdate = false;

    if ( d->incremental ) {
      /**
       * We know that this item has changed (as it is part of the
       * incremental changed list), so we just put it into the
       * storage.
       */
      needsUpdate = true;
    } else {
      if ( localItem.flags() != remoteItem.flags() ) { // Check whether the flags differ
        kDebug( 5250 ) << "Local flags "  << localItem.flags()
                       << "remote flags " << remoteItem.flags();
        needsUpdate = true;
      } else {
        /*
         * Check whether the new item contains unknown parts
         */
        const QStringList localParts = localItem.availableParts();
        QStringList missingParts = localParts;
        foreach( const QString remotePart, remoteItem.availableParts() )
          missingParts.removeAll( remotePart );
        if ( !missingParts.isEmpty() )
          needsUpdate = true;
        else {
          /**
           * If the available part identifiers don't differ, check
           * whether the content of the parts differs.
           */
          foreach ( const QString partId, localParts ) {
            if ( localItem.part( partId ) != remoteItem.part( partId ) ) {
              needsUpdate = true;
              break;
            }
          }
        }
      }
    }

    if ( needsUpdate ) {
      d->pendingJobs++;

      Item i( remoteItem );
      i.setReference( DataReference( localItem.reference().id(), remoteItem.reference().remoteId() ) );
      i.setRev( localItem.rev() );
      ItemStoreJob *mod = new ItemStoreJob( (const Item)i, this );
      mod->storePayload();
      mod->setCollection( d->syncCollection );
      connect( mod, SIGNAL( result( KJob* ) ), SLOT( slotLocalChangeDone( KJob* ) ) );
    } else {
      d->progress++;
    }
  }

  // removed
  if ( !d->incremental )
    d->removedRemoteItems = d->unprocessedLocalItems.toList();

  foreach ( const Item item, d->removedRemoteItems ) {
    d->pendingJobs++;
    ItemDeleteJob *job = new ItemDeleteJob( item.reference(), this );
    connect( job, SIGNAL( result( KJob* ) ), SLOT( slotLocalChangeDone( KJob* ) ) );
  }
  d->localItems.clear();

  checkDone();
}

void ItemSync::createLocalItem( const Item & item )
{
  d->pendingJobs++;
  ItemAppendJob *create = new ItemAppendJob( item, d->syncCollection, this );
  connect( create, SIGNAL( result( KJob* ) ), SLOT( slotLocalChangeDone( KJob* ) ) );
}

void ItemSync::checkDone()
{
  setProcessedAmount( KJob::Bytes, d->progress );
  if ( d->pendingJobs > 0 )
    return;

  commit();
}

void ItemSync::slotLocalChangeDone( KJob * job )
{
  if ( job->error() )
    return;

  d->pendingJobs--;
  d->progress++;
  checkDone();
}

#include "itemsync.moc"
<commit_msg>Restore lookup by remoteId since this is needed for ItemSync use in ResourceBase<commit_after>/*
    Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>
    Copyright (c) 2007 Volker Krause <vkrause@kde.org>

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

    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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "itemsync.h"

#include <libakonadi/item.h>
#include <libakonadi/itemappendjob.h>
#include <libakonadi/itemdeletejob.h>
#include <libakonadi/itemfetchjob.h>
#include <libakonadi/itemstorejob.h>

#include <kdebug.h>

using namespace Akonadi;

class ItemSync::Private
{
  public:
    Private() :
      pendingJobs( 0 ),
      progress( 0 ),
      incremental( false )
    {
    }

    Collection syncCollection;

    QHash<int, Akonadi::Item> localItemsById;
    QHash<QString, Akonadi::Item> localItemsByRemoteId;
    QSet<Akonadi::Item> unprocessedLocalItems;

    // remote items
    Akonadi::Item::List remoteItems;

    // removed remote items
    Item::List removedRemoteItems;

    // create counter
    int pendingJobs;
    int progress;

    bool incremental;
};

ItemSync::ItemSync( const Collection &collection, QObject *parent ) :
    TransactionSequence( parent ),
    d( new Private )
{
  d->syncCollection = collection;
}

ItemSync::~ItemSync()
{
  delete d;
}

void ItemSync::setRemoteItems( const Item::List & remoteItems )
{
  d->remoteItems = remoteItems;
  setTotalAmount( KJob::Bytes, d->remoteItems.count() );
}

void ItemSync::setRemoteItems( const Item::List & changedItems, const Item::List & removedItems )
{
  d->incremental = true;
  d->remoteItems = changedItems;
  d->removedRemoteItems = removedItems;
  setTotalAmount( KJob::Bytes, d->remoteItems.count() + d->removedRemoteItems.count() );
}

void ItemSync::doStart()
{
  ItemFetchJob* job = new ItemFetchJob( d->syncCollection, this );
  // FIXME this will deadlock, we only can fetch parts already in the cache
//   if ( !d->incremental )
//     job->fetchAllParts();

  connect( job, SIGNAL( result( KJob* ) ), SLOT( slotLocalListDone( KJob* ) ) );
}

void ItemSync::slotLocalListDone( KJob * job )
{
  if ( job->error() )
    return;

  const Item::List list = static_cast<ItemFetchJob*>( job )->items();
  foreach ( const Item item, list ) {
    d->localItemsById.insert( item.reference().id(), item );
    d->localItemsByRemoteId.insert( item.reference().remoteId(), item );
    d->unprocessedLocalItems.insert( item );
  }

  // added / updated
  foreach ( const Item remoteItem, d->remoteItems ) {
#ifndef NDEBUG
    if ( remoteItem.reference().remoteId().isEmpty() ) {
      kWarning( 5250 ) << "Item " << remoteItem.reference().id() << " does not have a remote identifier";
    }
#endif

    Item localItem = d->localItemsById.value( remoteItem.reference().id() );
    if ( !localItem.isValid() )
      localItem = d->localItemsByRemoteId.value( remoteItem.reference().remoteId() );
    d->unprocessedLocalItems.remove( localItem );
    // missing locally
    if ( !localItem.isValid() ) {
      createLocalItem( remoteItem );
      continue;
    }

    bool needsUpdate = false;

    if ( d->incremental ) {
      /**
       * We know that this item has changed (as it is part of the
       * incremental changed list), so we just put it into the
       * storage.
       */
      needsUpdate = true;
    } else {
      if ( localItem.flags() != remoteItem.flags() ) { // Check whether the flags differ
        kDebug( 5250 ) << "Local flags "  << localItem.flags()
                       << "remote flags " << remoteItem.flags();
        needsUpdate = true;
      } else {
        /*
         * Check whether the new item contains unknown parts
         */
        const QStringList localParts = localItem.availableParts();
        QStringList missingParts = localParts;
        foreach( const QString remotePart, remoteItem.availableParts() )
          missingParts.removeAll( remotePart );
        if ( !missingParts.isEmpty() )
          needsUpdate = true;
        else {
          /**
           * If the available part identifiers don't differ, check
           * whether the content of the parts differs.
           */
          foreach ( const QString partId, localParts ) {
            if ( localItem.part( partId ) != remoteItem.part( partId ) ) {
              needsUpdate = true;
              break;
            }
          }
        }
      }
    }

    if ( needsUpdate ) {
      d->pendingJobs++;

      Item i( remoteItem );
      i.setReference( DataReference( localItem.reference().id(), remoteItem.reference().remoteId() ) );
      i.setRev( localItem.rev() );
      ItemStoreJob *mod = new ItemStoreJob( (const Item)i, this );
      mod->storePayload();
      mod->setCollection( d->syncCollection );
      connect( mod, SIGNAL( result( KJob* ) ), SLOT( slotLocalChangeDone( KJob* ) ) );
    } else {
      d->progress++;
    }
  }

  // removed
  if ( !d->incremental )
    d->removedRemoteItems = d->unprocessedLocalItems.toList();

  foreach ( const Item item, d->removedRemoteItems ) {
    d->pendingJobs++;
    ItemDeleteJob *job = new ItemDeleteJob( item.reference(), this );
    connect( job, SIGNAL( result( KJob* ) ), SLOT( slotLocalChangeDone( KJob* ) ) );
  }
  d->localItemsById.clear();
  d->localItemsByRemoteId.clear();

  checkDone();
}

void ItemSync::createLocalItem( const Item & item )
{
  d->pendingJobs++;
  ItemAppendJob *create = new ItemAppendJob( item, d->syncCollection, this );
  connect( create, SIGNAL( result( KJob* ) ), SLOT( slotLocalChangeDone( KJob* ) ) );
}

void ItemSync::checkDone()
{
  setProcessedAmount( KJob::Bytes, d->progress );
  if ( d->pendingJobs > 0 )
    return;

  commit();
}

void ItemSync::slotLocalChangeDone( KJob * job )
{
  if ( job->error() )
    return;

  d->pendingJobs--;
  d->progress++;
  checkDone();
}

#include "itemsync.moc"
<|endoftext|>


<commit_before>/***************************************************************************
begin                : 2004/03/12
copyright            : (C) Mark Kretschmann
email                : markey@web.de
***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "plugin.h"
#include "pluginmanager.h"

#include <vector>
#include <QList>
#include <QFile>
#include <QString>

#include <klibloader.h>
#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>

using std::vector;
using Akregator::Plugin;

namespace Akregator {

vector<PluginManager::StoreItem>
PluginManager::m_store;

/////////////////////////////////////////////////////////////////////////////////////
// PUBLIC INTERFACE
/////////////////////////////////////////////////////////////////////////////////////

KService::List
PluginManager::query( const QString& constraint )
{
    // Add versioning constraint
    QString
    str  = "[X-KDE-akregator-framework-version] == ";
    str += QString::number( FrameworkVersion );
    str += " and ";
    if (!constraint.trimmed().isEmpty())
        str += constraint + " and ";
    str += "[X-KDE-akregator-rank] > 0";

    kDebug() <<"Plugin trader constraint:" << str;

    return KServiceTypeTrader::self()->query( "Akregator/Plugin", str );
}

Plugin*
PluginManager::createFromQuery( const QString &constraint )
{
    KService::List offers = query( constraint );

    if ( offers.isEmpty() ) {
        kWarning() <<"No matching plugin found.";
        return 0;
    }

    // Select plugin with highest rank
    int rank = 0;
    uint current = 0;
    for ( int i = 0; i < offers.count(); i++ ) {
        if ( offers[i]->property( "X-KDE-akregator-rank" ).toInt() > rank )
            current = i;
    }

    return createFromService( offers[current] );
}

Plugin*
PluginManager::createFromService( const KService::Ptr service )
{
    kDebug() <<"Trying to load:" << service->library();

    //get the library loader instance
    KLibLoader *loader = KLibLoader::self();
    //try to load the specified library
    KLibrary *lib = loader->library( QFile::encodeName( service->library() ), QLibrary::ExportExternalSymbolsHint );

    if ( !lib ) {
        KMessageBox::error( 0, i18n( "
KLibLoader could not load the plugin:
%1
"
                                     "
Error message:
%2
" ,
                                 service->library() ,
                                 loader->lastErrorMessage() ) );
        return 0;
    }
    //look up address of init function and cast it to pointer-to-function
    Plugin* (*create_plugin)() = ( Plugin* (*)() ) lib->resolveFunction( "create_plugin" );

    if ( !create_plugin ) {
        kWarning() <<"create_plugin == NULL";
        return 0;
    }
    //create plugin on the heap
    Plugin* plugin = create_plugin();

    //put plugin into store
    StoreItem item;
    item.plugin = plugin;
    item.library = lib;
    item.service = service;
    m_store.push_back( item );

    dump( service );
    return plugin;
}

void
PluginManager::unload( Plugin* plugin )
{
    vector<StoreItem>::iterator iter = lookupPlugin( plugin );

    if ( iter != m_store.end() ) {
        delete (*iter).plugin;
        kDebug() <<"Unloading library:"<< (*iter).service->library();
        (*iter).library->unload();

        m_store.erase( iter );
    }
    else
        kWarning() <<"Could not unload plugin (not found in store).";
}

KService::Ptr
PluginManager::getService( const Plugin* plugin )
{
    if ( !plugin ) {
        kWarning() <<"pointer == NULL";
        return KService::Ptr( 0 );
    }

    //search plugin in store
    vector<StoreItem>::const_iterator iter = lookupPlugin( plugin );

    if ( iter == m_store.end() ) {
        kWarning() <<"Plugin not found in store.";
        return KService::Ptr( 0 );
    }

    return (*iter).service;
}

void
PluginManager::showAbout( const QString &constraint )
{
    KService::List offers = query( constraint );

    if ( offers.isEmpty() )
        return;

    KService::Ptr s = offers.front();

    const QString body = "
%1	%2
";

    QString str  = "
";

    str += body.arg( i18n( "Name" ),                s->name() );
    str += body.arg( i18n( "Library" ),             s->library() );
    str += body.arg( i18n( "Authors" ),             s->property( "X-KDE-akregator-authors" ).toStringList().join( "\n" ) );
    str += body.arg( i18n( "Email" ),               s->property( "X-KDE-akregator-email" ).toStringList().join( "\n" ) );
    str += body.arg( i18n( "Version" ),             s->property( "X-KDE-akregator-version" ).toString() );
    str += body.arg( i18n( "Framework Version" ),   s->property( "X-KDE-akregator-framework-version" ).toString() );

    str += "
";

    KMessageBox::information( 0, str, i18n( "Plugin Information" ) );
}

void
PluginManager::dump( const KService::Ptr service )
{
    kDebug()
      << "PluginManager Service Info:" << endl
      << "---------------------------" << endl
      << "name                          : " << service->name() << endl
      << "library                       : " << service->library() << endl
      << "desktopEntryPath              : " << service->desktopEntryPath() << endl
      << "X-KDE-akregator-plugintype       : " << service->property( "X-KDE-akregator-plugintype" ).toString() << endl
      << "X-KDE-akregator-name             : " << service->property( "X-KDE-akregator-name" ).toString() << endl
      << "X-KDE-akregator-authors          : " << service->property( "X-KDE-akregator-authors" ).toStringList() << endl
      << "X-KDE-akregator-rank             : " << service->property( "X-KDE-akregator-rank" ).toString() << endl
      << "X-KDE-akregator-version          : " << service->property( "X-KDE-akregator-version" ).toString() << endl
      << "X-KDE-akregator-framework-version: " << service->property( "X-KDE-akregator-framework-version" ).toString()
      << endl;

}

/////////////////////////////////////////////////////////////////////////////////////
// PRIVATE INTERFACE
/////////////////////////////////////////////////////////////////////////////////////

vector<PluginManager::StoreItem>::iterator
PluginManager::lookupPlugin( const Plugin* plugin )
{
    vector<StoreItem>::iterator iter;

    //search plugin pointer in store
    vector<StoreItem>::const_iterator end;
    for ( iter = m_store.begin(); iter != end; ++iter ) {
        if ( (*iter).plugin == plugin )
            break;
    }

    return iter;
}

} // namespace Akregator
<commit_msg>Deprecated--<commit_after>/***************************************************************************
begin                : 2004/03/12
copyright            : (C) Mark Kretschmann
email                : markey@web.de
***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "plugin.h"
#include "pluginmanager.h"

#include <vector>
#include <QList>
#include <QFile>
#include <QString>

#include <klibloader.h>
#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>

using std::vector;
using Akregator::Plugin;

namespace Akregator {

vector<PluginManager::StoreItem>
PluginManager::m_store;

/////////////////////////////////////////////////////////////////////////////////////
// PUBLIC INTERFACE
/////////////////////////////////////////////////////////////////////////////////////

KService::List
PluginManager::query( const QString& constraint )
{
    // Add versioning constraint
    QString
    str  = "[X-KDE-akregator-framework-version] == ";
    str += QString::number( FrameworkVersion );
    str += " and ";
    if (!constraint.trimmed().isEmpty())
        str += constraint + " and ";
    str += "[X-KDE-akregator-rank] > 0";

    kDebug() <<"Plugin trader constraint:" << str;

    return KServiceTypeTrader::self()->query( "Akregator/Plugin", str );
}

Plugin*
PluginManager::createFromQuery( const QString &constraint )
{
    KService::List offers = query( constraint );

    if ( offers.isEmpty() ) {
        kWarning() <<"No matching plugin found.";
        return 0;
    }

    // Select plugin with highest rank
    int rank = 0;
    uint current = 0;
    for ( int i = 0; i < offers.count(); i++ ) {
        if ( offers[i]->property( "X-KDE-akregator-rank" ).toInt() > rank )
            current = i;
    }

    return createFromService( offers[current] );
}

Plugin*
PluginManager::createFromService( const KService::Ptr service )
{
    kDebug() <<"Trying to load:" << service->library();

    //get the library loader instance
    KLibLoader *loader = KLibLoader::self();
    //try to load the specified library
    KLibrary *lib = loader->library( QFile::encodeName( service->library() ), QLibrary::ExportExternalSymbolsHint );

    if ( !lib ) {
        KMessageBox::error( 0, i18n( "
KLibLoader could not load the plugin:
%1
"
                                     "
Error message:
%2
" ,
                                 service->library() ,
                                 loader->lastErrorMessage() ) );
        return 0;
    }
    //look up address of init function and cast it to pointer-to-function
    Plugin* (*create_plugin)() = ( Plugin* (*)() ) lib->resolveFunction( "create_plugin" );

    if ( !create_plugin ) {
        kWarning() <<"create_plugin == NULL";
        return 0;
    }
    //create plugin on the heap
    Plugin* plugin = create_plugin();

    //put plugin into store
    StoreItem item;
    item.plugin = plugin;
    item.library = lib;
    item.service = service;
    m_store.push_back( item );

    dump( service );
    return plugin;
}

void
PluginManager::unload( Plugin* plugin )
{
    vector<StoreItem>::iterator iter = lookupPlugin( plugin );

    if ( iter != m_store.end() ) {
        delete (*iter).plugin;
        kDebug() <<"Unloading library:"<< (*iter).service->library();
        (*iter).library->unload();

        m_store.erase( iter );
    }
    else
        kWarning() <<"Could not unload plugin (not found in store).";
}

KService::Ptr
PluginManager::getService( const Plugin* plugin )
{
    if ( !plugin ) {
        kWarning() <<"pointer == NULL";
        return KService::Ptr( 0 );
    }

    //search plugin in store
    vector<StoreItem>::const_iterator iter = lookupPlugin( plugin );

    if ( iter == m_store.end() ) {
        kWarning() <<"Plugin not found in store.";
        return KService::Ptr( 0 );
    }

    return (*iter).service;
}

void
PluginManager::showAbout( const QString &constraint )
{
    KService::List offers = query( constraint );

    if ( offers.isEmpty() )
        return;

    KService::Ptr s = offers.front();

    const QString body = "
%1	%2
";

    QString str  = "
";

    str += body.arg( i18n( "Name" ),                s->name() );
    str += body.arg( i18n( "Library" ),             s->library() );
    str += body.arg( i18n( "Authors" ),             s->property( "X-KDE-akregator-authors" ).toStringList().join( "\n" ) );
    str += body.arg( i18n( "Email" ),               s->property( "X-KDE-akregator-email" ).toStringList().join( "\n" ) );
    str += body.arg( i18n( "Version" ),             s->property( "X-KDE-akregator-version" ).toString() );
    str += body.arg( i18n( "Framework Version" ),   s->property( "X-KDE-akregator-framework-version" ).toString() );

    str += "
";

    KMessageBox::information( 0, str, i18n( "Plugin Information" ) );
}

void
PluginManager::dump( const KService::Ptr service )
{
    kDebug()
      << "PluginManager Service Info:" << endl
      << "---------------------------" << endl
      << "name                          : " << service->name() << endl
      << "library                       : " << service->library() << endl
      << "desktopEntryPath              : " << service->entryPath() << endl
      << "X-KDE-akregator-plugintype       : " << service->property( "X-KDE-akregator-plugintype" ).toString() << endl
      << "X-KDE-akregator-name             : " << service->property( "X-KDE-akregator-name" ).toString() << endl
      << "X-KDE-akregator-authors          : " << service->property( "X-KDE-akregator-authors" ).toStringList() << endl
      << "X-KDE-akregator-rank             : " << service->property( "X-KDE-akregator-rank" ).toString() << endl
      << "X-KDE-akregator-version          : " << service->property( "X-KDE-akregator-version" ).toString() << endl
      << "X-KDE-akregator-framework-version: " << service->property( "X-KDE-akregator-framework-version" ).toString()
      << endl;

}

/////////////////////////////////////////////////////////////////////////////////////
// PRIVATE INTERFACE
/////////////////////////////////////////////////////////////////////////////////////

vector<PluginManager::StoreItem>::iterator
PluginManager::lookupPlugin( const Plugin* plugin )
{
    vector<StoreItem>::iterator iter;

    //search plugin pointer in store
    vector<StoreItem>::const_iterator end;
    for ( iter = m_store.begin(); iter != end; ++iter ) {
        if ( (*iter).plugin == plugin )
            break;
    }

    return iter;
}

} // namespace Akregator
<|endoftext|>