<commit_before>/// @file
/// @author uentity
/// @date 28.06.2018
/// @brief BS tree links serialization code
/// @copyright
/// 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 https://mozilla.org/MPL/2.0/

#include <bs/serialize/tree.h>
#include <bs/serialize/boost_uuid.h>
#include <bs/serialize/base_types.h>
#include <cereal/types/polymorphic.hpp>

using namespace cereal;
using namespace blue_sky;

/*-----------------------------------------------------------------------------
 *  inode
 *-----------------------------------------------------------------------------*/
BSS_FCN_BEGIN(save, tree::inode)
	ar(
		make_nvp("owner", t.owner),
		make_nvp("group", t.group),
		make_nvp("suid", t.suid),
		make_nvp("sgid", t.sgid),
		make_nvp("sticky", t.sticky),
		make_nvp("u", t.u),
		make_nvp("g", t.g),
		make_nvp("o", t.o)
	);
BSS_FCN_END

BSS_FCN_BEGIN(load, tree::inode)
	ar(
		make_nvp("owner", t.owner),
		make_nvp("group", t.group)
	);
	bool bit;
	ar(make_nvp("suid", bit));
	t.suid = bit;
	ar(make_nvp("sgid", bit));
	t.sgid = bit;
	ar(make_nvp("sticky", bit));
	t.sticky = bit;

	std::uint8_t flags;
	ar(make_nvp("u", flags));
	t.u = flags;
	ar(make_nvp("g", flags));
	t.g = flags;
	ar(make_nvp("o", flags));
	t.o = flags;
BSS_FCN_END

BSS_FCN_EXPORT(save, tree::inode)
BSS_FCN_EXPORT(load, tree::inode)

/*-----------------------------------------------------------------------------
 *  link
 *-----------------------------------------------------------------------------*/
BSS_FCN_BEGIN(serialize, tree::link)
	// [NOTE] intentinaly DON'T save name,
	// because name will be saved in derived classes to invoke minimal constructor
	// also do not save owner, because owner will be correctly set by `node`
	ar(
//		make_nvp("name", t.name_),
		make_nvp("id", t.id_),
		make_nvp("flags", t.flags_),
		make_nvp("inode", t.inode_)
		// intentionally do net serialize owner, it will be set up when parent node is loaded
	);
BSS_FCN_END

BSS_FCN_EXPORT(serialize, tree::link)

/*-----------------------------------------------------------------------------
 *  hard_link
 *-----------------------------------------------------------------------------*/
// provide non-empty constructor
BSS_FCN_BEGIN(load_and_construct, tree::hard_link)
	// load name? data & construct instance
	std::string name;
	sp_obj data;
	ar(name, data);
	construct(std::move(name), std::move(data));
	// load base link
	ar(base_class<tree::link>(construct.ptr()));
BSS_FCN_END

BSS_FCN_BEGIN(serialize, tree::hard_link)
	ar(
		make_nvp("name", t.name_),
		make_nvp("data", t.data_),
		make_nvp("link_base", base_class<tree::link>(&t))
	);
BSS_FCN_END

BSS_FCN_EXPORT(serialize, tree::hard_link)

/*-----------------------------------------------------------------------------
 *  weak_link
 *-----------------------------------------------------------------------------*/
// provide non-empty constructor
BSS_FCN_BEGIN(load_and_construct, tree::weak_link)
	// load name? data & construct instance
	std::string name;
	sp_obj data;
	ar(name, data);
	construct(std::move(name), std::move(data));
	// load base link
	ar(base_class<tree::link>(construct.ptr()));
BSS_FCN_END

BSS_FCN_BEGIN(serialize, tree::weak_link)
	ar(
		make_nvp("name", t.name_),
		make_nvp("data", t.data_),
		make_nvp("link_base", base_class<tree::link>(&t))
	);
BSS_FCN_END

BSS_FCN_EXPORT(serialize, tree::weak_link)

/*-----------------------------------------------------------------------------
 *  sym_link
 *-----------------------------------------------------------------------------*/
// provide non-empty constructor
BSS_FCN_BEGIN(load_and_construct, tree::sym_link)
	// load both name and path & construct instance
	std::string name, path;
	ar(name, path);
	construct(std::move(name), std::move(path));
	// load base link
	ar(base_class<tree::link>(construct.ptr()));
BSS_FCN_END

BSS_FCN_BEGIN(serialize, tree::sym_link)
	ar(
		make_nvp("name", t.name_),
		make_nvp("path", t.path_),
		make_nvp("link_base", base_class<tree::link>(&t))
	);
BSS_FCN_END

BSS_FCN_EXPORT(serialize, tree::sym_link)

// instantiate code for polymorphic types
using namespace blue_sky;
//CEREAL_REGISTER_TYPE_WITH_NAME(tree::link, "link")
CEREAL_REGISTER_TYPE_WITH_NAME(tree::hard_link, "hard_link")
CEREAL_REGISTER_TYPE_WITH_NAME(tree::weak_link, "weak_link")
CEREAL_REGISTER_TYPE_WITH_NAME(tree::sym_link, "sym_link")

BSS_REGISTER_DYNAMIC_INIT(link)

<commit_msg>serial/link: add forgotten exports of load_and_construct for links<commit_after>/// @file
/// @author uentity
/// @date 28.06.2018
/// @brief BS tree links serialization code
/// @copyright
/// 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 https://mozilla.org/MPL/2.0/

#include <bs/serialize/tree.h>
#include <bs/serialize/boost_uuid.h>
#include <bs/serialize/base_types.h>
#include <cereal/types/polymorphic.hpp>

using namespace cereal;
using namespace blue_sky;

/*-----------------------------------------------------------------------------
 *  inode
 *-----------------------------------------------------------------------------*/
BSS_FCN_BEGIN(save, tree::inode)
	ar(
		make_nvp("owner", t.owner),
		make_nvp("group", t.group),
		make_nvp("suid", t.suid),
		make_nvp("sgid", t.sgid),
		make_nvp("sticky", t.sticky),
		make_nvp("u", t.u),
		make_nvp("g", t.g),
		make_nvp("o", t.o)
	);
BSS_FCN_END

BSS_FCN_BEGIN(load, tree::inode)
	ar(
		make_nvp("owner", t.owner),
		make_nvp("group", t.group)
	);
	bool bit;
	ar(make_nvp("suid", bit));
	t.suid = bit;
	ar(make_nvp("sgid", bit));
	t.sgid = bit;
	ar(make_nvp("sticky", bit));
	t.sticky = bit;

	std::uint8_t flags;
	ar(make_nvp("u", flags));
	t.u = flags;
	ar(make_nvp("g", flags));
	t.g = flags;
	ar(make_nvp("o", flags));
	t.o = flags;
BSS_FCN_END

BSS_FCN_EXPORT(save, tree::inode)
BSS_FCN_EXPORT(load, tree::inode)

/*-----------------------------------------------------------------------------
 *  link
 *-----------------------------------------------------------------------------*/
BSS_FCN_BEGIN(serialize, tree::link)
	// [NOTE] intentinaly DON'T save name,
	// because name will be saved in derived classes to invoke minimal constructor
	// also do not save owner, because owner will be correctly set by `node`
	ar(
//		make_nvp("name", t.name_),
		make_nvp("id", t.id_),
		make_nvp("flags", t.flags_),
		make_nvp("inode", t.inode_)
		// intentionally do net serialize owner, it will be set up when parent node is loaded
	);
BSS_FCN_END

BSS_FCN_EXPORT(serialize, tree::link)

/*-----------------------------------------------------------------------------
 *  hard_link
 *-----------------------------------------------------------------------------*/
// provide non-empty constructor
BSS_FCN_BEGIN(load_and_construct, tree::hard_link)
	// load name? data & construct instance
	std::string name;
	sp_obj data;
	ar(name, data);
	construct(std::move(name), std::move(data));
	// load base link
	ar(base_class<tree::link>(construct.ptr()));
BSS_FCN_END

BSS_FCN_BEGIN(serialize, tree::hard_link)
	ar(
		make_nvp("name", t.name_),
		make_nvp("data", t.data_),
		make_nvp("link_base", base_class<tree::link>(&t))
	);
BSS_FCN_END

BSS_FCN_EXPORT(serialize, tree::hard_link)
BSS_FCN_EXPORT(load_and_construct, tree::hard_link)

/*-----------------------------------------------------------------------------
 *  weak_link
 *-----------------------------------------------------------------------------*/
// provide non-empty constructor
BSS_FCN_BEGIN(load_and_construct, tree::weak_link)
	// load name? data & construct instance
	std::string name;
	sp_obj data;
	ar(name, data);
	construct(std::move(name), std::move(data));
	// load base link
	ar(base_class<tree::link>(construct.ptr()));
BSS_FCN_END

BSS_FCN_BEGIN(serialize, tree::weak_link)
	ar(
		make_nvp("name", t.name_),
		make_nvp("data", t.data_),
		make_nvp("link_base", base_class<tree::link>(&t))
	);
BSS_FCN_END

BSS_FCN_EXPORT(serialize, tree::weak_link)
BSS_FCN_EXPORT(load_and_construct, tree::weak_link)

/*-----------------------------------------------------------------------------
 *  sym_link
 *-----------------------------------------------------------------------------*/
// provide non-empty constructor
BSS_FCN_BEGIN(load_and_construct, tree::sym_link)
	// load both name and path & construct instance
	std::string name, path;
	ar(name, path);
	construct(std::move(name), std::move(path));
	// load base link
	ar(base_class<tree::link>(construct.ptr()));
BSS_FCN_END

BSS_FCN_BEGIN(serialize, tree::sym_link)
	ar(
		make_nvp("name", t.name_),
		make_nvp("path", t.path_),
		make_nvp("link_base", base_class<tree::link>(&t))
	);
BSS_FCN_END

BSS_FCN_EXPORT(serialize, tree::sym_link)
BSS_FCN_EXPORT(load_and_construct, tree::sym_link)

// instantiate code for polymorphic types
using namespace blue_sky;
//CEREAL_REGISTER_TYPE_WITH_NAME(tree::link, "link")
CEREAL_REGISTER_TYPE_WITH_NAME(tree::hard_link, "hard_link")
CEREAL_REGISTER_TYPE_WITH_NAME(tree::weak_link, "weak_link")
CEREAL_REGISTER_TYPE_WITH_NAME(tree::sym_link, "sym_link")

BSS_REGISTER_DYNAMIC_INIT(link)

<|endoftext|>


<commit_before>/*
 * File:  other_updates.cpp
 * Copyright (C) 2004 The Institute for System Programming of the Russian Academy of Sciences (ISP RAS)
 */

#include "common/sedna.h"

#include "tr/updates/updates.h"
#include "tr/executor/base/xptr_sequence.h"
#include "tr/mo/micro.h"
#include "tr/auth/auc.h"
#ifdef SE_ENABLE_TRIGGERS
#include "tr/triggers/triggers.h"
#endif

void replace(PPOpIn arg)
{
	//1.seq-replaced nodes
	//2.replacements
	//3. persistent replacements+their position in 2 seq
//	xptr addr(0,(void*)0x4acc0000);
//	check_blk_consistency(addr);
	xptr node, parent, tmp_node, old_node, node_child, repl_node_child, del_node;
	schema_node* scm_node;

	tuple t(arg.ts);
	descript_sequence arg3seq(2);
	xptr_sequence arg1seq;
	xptr_sequence arg1seq_tmp;
	xptr_sequence arg2seq;
	upd_ns_map* ins_swiz=NULL;
	bool is_node_updated=true;
	arg.op->next(t);
	while (!t.is_eos())
	{
		if (t.cells[0].is_node())
		{
			node=t.cells[0].get_node();
			CHECKP(node);
			if ((!is_node_updated || is_node_persistent(node))&& !is_node_document(node))
			{
				xptr indir=((n_dsc*)XADDR(node))->indir;
				if (is_node_updated)
				{
					is_node_updated=false;
					arg1seq.add(indir);
					arg1seq_tmp.add(node);
				}
				else
				{

					if (is_node_persistent(node))
					{
						tuple tup(2);
						tup.copy(tuple_cell::node(node),tuple_cell((__int64)(arg2seq.size())));
						arg3seq.add(tup);
					}
					arg2seq.add(indir);
				}
			}
#ifndef IGNORE_UPDATE_ERRORS
			else
			{
				throw USER_EXCEPTION(SE2020);
			}
#endif
		}
		else
		{
			if (t.cells[0].get_atomic_type()==se_separator)
			{
				arg2seq.add(XNULL);
				is_node_updated=true;
			}
#ifndef IGNORE_UPDATE_ERRORS
			else	throw USER_EXCEPTION(SE2021);
#endif
		}

		arg.op->next(t);
	}

	if (arg1seq.size()<=0) return;
	//merge 1'st and 3'rd sequences create copy of merged items
	// Checking authorization
	if (is_auth_check_needed(REPLACE_STATEMENT))
		auth_for_update(&arg1seq, REPLACE_STATEMENT, false);
	arg1seq_tmp.sort();
	arg3seq.sort();
	descript_sequence::iterator it3=arg3seq.begin();
	xptr_sequence::iterator it1=arg1seq_tmp.begin();
	while(it3!=arg3seq.end()&& it1!=arg1seq_tmp.end())
	{
		switch(nid_cmp_effective((*it3).cells[0].get_node(), *it1))
		{
		case 0:
			{
				node=copy_to_temp((*it3).cells[0].get_node());
				xptr indir=((n_dsc*)XADDR(node))->indir;
//				arg2seq[(*it3).cells[1].get_xs_integer()]=indir;

				arg2seq.set(indir,(*it3).cells[1].get_xs_integer());
				++it3;//++it1;
			}
			break;
		case 1:
			++it1;
			break;
		case 2:
			++it1;
			break;
		case -1:
			++it3;
			break;
		case -2:
			{
				node=copy_to_temp((*it3).cells[0].get_node());
				xptr indir=((n_dsc*)XADDR(node))->indir;
				arg2seq.set(indir,(*it3).cells[1].get_xs_integer());
				++it3;
			}
			break;
		}
	}
#ifdef SE_ENABLE_FTSEARCH
	clear_ft_sequences();
#endif
#ifdef SE_ENABLE_TRIGGERS
	apply_per_statement_triggers(&arg1seq, false, NULL, false, TRIGGER_BEFORE, TRIGGER_REPLACE_EVENT);
#endif
	//sorting arg1seq
	arg3seq.clear();
	xptr_sequence::iterator it=arg1seq.begin();
	xptr_sequence::iterator sit=arg2seq.begin();
	int ctr=0;
	do
	{
		tuple tup(2);
		tup.copy(tuple_cell::node(removeIndirection(*it)),tuple_cell((__int64)ctr));
		arg3seq.add(tup);
		while(*sit!=XNULL)
		{
			sit++;
			ctr++;
		}
		sit++;
		ctr++;
		it++;
	}
	while (it!=arg1seq.end());
	arg3seq.sort();
	it3=arg3seq.begin();
	descript_sequence arg4seq(2);
	do
	{
		node=(*it3).cells[0].get_node();
		CHECKP(node);
		xptr tind=((n_dsc*)XADDR(node))->indir;
		tuple t=(*it3);
		t.cells[0].set_node(tind);
		++it3;
		arg4seq.add(t);

	}
	while (it3!=arg3seq.end());

	// deleting- inserting new nodes
	it3=arg4seq.end();
	do
	{
		--it3;
		node = old_node = removeIndirection((*it3).cells[0].get_node());
		int pos=(*it3).cells[1].get_xs_integer();
		sit=arg2seq.begin()+pos;
		CHECKP(node);
		xptr leftn=((n_dsc*)XADDR(old_node))->ldsc;
		xptr rightn=((n_dsc*)XADDR(old_node))->rdsc;
		xptr par_ind=((n_dsc*)XADDR(old_node))->pdsc;
		bool a_m=is_node_attribute(node);
		bool d_m=a_m||is_node_text(node);

#ifdef SE_ENABLE_TRIGGERS
		CHECKP(old_node);
		scm_node = GETSCHEMENODEX(old_node);
		parent=removeIndirection(((n_dsc*)XADDR(old_node))->pdsc);
		CHECKP(old_node);
		tmp_node = prepare_old_node(old_node, scm_node, TRIGGER_REPLACE_EVENT);
#endif

#ifdef SE_ENABLE_TRIGGERS
        // Before-for-each-node triggers (cycle for all inserted nodes)
		xptr_sequence::iterator tr_it=sit;
    	while(*tr_it!=XNULL)
        {
            node_child=*tr_it;
            parent=removeIndirection(par_ind);
            if(apply_per_node_triggers(removeIndirection(node_child), old_node, parent, scm_node, TRIGGER_BEFORE, TRIGGER_REPLACE_EVENT) == XNULL)
               goto next_replacement;
            tr_it++;
		}
#endif

		//pre_deletion
		if (d_m)
		{
			delete_node(old_node);
		}
		//1.inserting attributes from sequence
		while(*sit!=XNULL)
		{
			node_child=*sit;
			if (!is_node_attribute(removeIndirection(node_child)))
				break;
			parent=removeIndirection(par_ind);

			if (is_node_persistent(node_child))
						node=deep_pers_copy(XNULL, XNULL, parent, removeIndirection(node_child),true);
			else
						node=deep_temp_copy(XNULL, XNULL, parent, removeIndirection(node_child),ins_swiz);
			sit++;
#ifdef SE_ENABLE_TRIGGERS
			apply_per_node_triggers(node, tmp_node, parent, scm_node, TRIGGER_AFTER, TRIGGER_REPLACE_EVENT);
#endif
		}
		//2. finding place of insertion
		if (a_m)
		{
			node=getFirstByOrderChildNode(removeIndirection(par_ind));
			if (node!=XNULL)
			{
				if (is_node_element(node))
				{
					rightn=node;
					node=XNULL;
				}
				else
				{
					rightn=XNULL;
				}
			}
		}
		else
		{
			if (d_m)
			{
				if (rightn==XNULL)
					node=leftn;
				else
					node=XNULL;
			}
			else
			{
				rightn=node;
				node=XNULL;
			}

		}
		//3.main insert cycle
		while(*sit!=XNULL)
		{
			node_child=*sit;
			parent=removeIndirection(par_ind);
			if (is_node_persistent(node_child))
						node=deep_pers_copy(node, rightn, parent, removeIndirection(node_child),true);
					else
						node=deep_temp_copy(node, rightn, parent, removeIndirection(node_child),ins_swiz);
			sit++;
#ifdef SE_ENABLE_TRIGGERS
			apply_per_node_triggers(node, tmp_node, parent, scm_node, TRIGGER_AFTER, TRIGGER_REPLACE_EVENT);
#endif
		}
		//post_deletion
		if (!d_m)
		{
			del_node = removeIndirection((*it3).cells[0].get_node());
			CHECKP(del_node);
			delete_node(del_node);
		}
/*
	#ifdef SE_ENABLE_TRIGGERS
			CHECKP(old_node);
			scm_node = GETSCHEMENODEX(old_node);
			parent=removeIndirection(((n_dsc*)XADDR(old_node))->pdsc);
			CHECKP(old_node);
			tmp_node = prepare_old_node(old_node, scm_node, TRIGGER_REPLACE_EVENT);
	#endif

			//1.insert

			while(*sit!=XNULL)
			{
				node_child=*sit;
	#ifdef SE_ENABLE_TRIGGERS
				repl_node_child = apply_per_node_triggers(removeIndirection(node_child), old_node, XNULL, scm_node, TRIGGER_BEFORE, TRIGGER_REPLACE_EVENT);
				if(repl_node_child==XNULL) goto next_replacement;
				CHECKP(repl_node_child);
				node_child = ((n_dsc*)XADDR(repl_node_child))->indir;
	#endif
				CHECKP(node);
				if ( is_node_attribute(removeIndirection(node_child)))
				{
					parent=removeIndirection(GETPARENTPOINTER(node));
					if (is_node_persistent(node_child))
						node=deep_pers_copy(XNULL, XNULL, parent, removeIndirection(node_child),true);
					else
						node=deep_temp_copy(XNULL, XNULL, parent, removeIndirection(node_child),ins_swiz);
				}
				else
				{
					if (is_node_persistent(node_child))
						node=deep_pers_copy(node, XNULL, XNULL, removeIndirection(node_child),true);
					else
						node=deep_temp_copy(node, XNULL, XNULL, removeIndirection(node_child),ins_swiz);
				}
				sit++;
			}

			//delete node
			del_node = removeIndirection((*it3).cells[0].get_node());
			CHECKP(del_node);
			delete_node(del_node);

	#ifdef SE_ENABLE_TRIGGERS
			apply_per_node_triggers(node, tmp_node, parent, scm_node, TRIGGER_AFTER, TRIGGER_REPLACE_EVENT);
	#endif
		}
		if (border!=XNULL)
		{
			delete_node(removeIndirection(border));
			border=XNULL;
		}
*/
next_replacement:;
	}
	while (it3!=arg4seq.begin());
	//3.delete
/*	arg2seq.clear();
	it=arg1seq.begin();
	while (it!=arg1seq.end())
	{
		arg2seq.add(removeIndirection(*it));
		++it;
	}
	arg2seq.sort();
	it=arg2seq.end();
	do
	{
		--it;
		delete_node(*it);
		if (it==arg2seq.begin()) break;
	}
	while (true);
*/
	if (ins_swiz!=NULL)
	{
//		checkSwiizleTab(ins_swiz);
		delete ins_swiz;
	}
	clear_temp();
#ifdef SE_ENABLE_FTSEARCH
	execute_modifications();
#endif
#ifdef SE_ENABLE_TRIGGERS
	apply_per_statement_triggers(NULL, false, NULL, false, TRIGGER_AFTER, TRIGGER_REPLACE_EVENT);
#endif
}<commit_msg>replace fix<commit_after>/*
 * File:  other_updates.cpp
 * Copyright (C) 2004 The Institute for System Programming of the Russian Academy of Sciences (ISP RAS)
 */

#include "common/sedna.h"

#include "tr/updates/updates.h"
#include "tr/executor/base/xptr_sequence.h"
#include "tr/mo/micro.h"
#include "tr/auth/auc.h"
#ifdef SE_ENABLE_TRIGGERS
#include "tr/triggers/triggers.h"
#endif

void replace(PPOpIn arg)
{
	//1.seq-replaced nodes
	//2.replacements
	//3. persistent replacements+their position in 2 seq
//	xptr addr(0,(void*)0x4acc0000);
//	check_blk_consistency(addr);
	xptr node, parent, tmp_node, old_node, node_child, repl_node_child, del_node;
	schema_node* scm_node;

	tuple t(arg.ts);
	descript_sequence arg3seq(2);
	xptr_sequence arg1seq;
	xptr_sequence arg1seq_tmp;
	xptr_sequence arg2seq;
	upd_ns_map* ins_swiz=NULL;
	bool is_node_updated=true;
	arg.op->next(t);
	while (!t.is_eos())
	{
		if (t.cells[0].is_node())
		{
			node=t.cells[0].get_node();
			CHECKP(node);
			if ((!is_node_updated || is_node_persistent(node))&& !is_node_document(node))
			{
				xptr indir=((n_dsc*)XADDR(node))->indir;
				if (is_node_updated)
				{
					is_node_updated=false;
					arg1seq.add(indir);
					arg1seq_tmp.add(node);
				}
				else
				{

					if (is_node_persistent(node))
					{
						tuple tup(2);
						tup.copy(tuple_cell::node(node),tuple_cell((__int64)(arg2seq.size())));
						arg3seq.add(tup);
					}
					arg2seq.add(indir);
				}
			}
#ifndef IGNORE_UPDATE_ERRORS
			else
			{
				throw USER_EXCEPTION(SE2020);
			}
#endif
		}
		else
		{
			if (t.cells[0].get_atomic_type()==se_separator)
			{
				arg2seq.add(XNULL);
				is_node_updated=true;
			}
#ifndef IGNORE_UPDATE_ERRORS
			else	throw USER_EXCEPTION(SE2021);
#endif
		}

		arg.op->next(t);
	}

	if (arg1seq.size()<=0) return;
	//merge 1'st and 3'rd sequences create copy of merged items
	// Checking authorization
	if (is_auth_check_needed(REPLACE_STATEMENT))
		auth_for_update(&arg1seq, REPLACE_STATEMENT, false);
	arg1seq_tmp.sort();
	arg3seq.sort();
	descript_sequence::iterator it3=arg3seq.begin();
	xptr_sequence::iterator it1=arg1seq_tmp.begin();
	while(it3!=arg3seq.end()&& it1!=arg1seq_tmp.end())
	{
		switch(nid_cmp_effective((*it3).cells[0].get_node(), *it1))
		{
		case 0:
			{
				node=copy_to_temp((*it3).cells[0].get_node());
				xptr indir=((n_dsc*)XADDR(node))->indir;
//				arg2seq[(*it3).cells[1].get_xs_integer()]=indir;

				arg2seq.set(indir,(*it3).cells[1].get_xs_integer());
				++it3;//++it1;
			}
			break;
		case 1:
			++it1;
			break;
		case 2:
			++it1;
			break;
		case -1:
			++it3;
			break;
		case -2:
			{
				node=copy_to_temp((*it3).cells[0].get_node());
				xptr indir=((n_dsc*)XADDR(node))->indir;
				arg2seq.set(indir,(*it3).cells[1].get_xs_integer());
				++it3;
			}
			break;
		}
	}
#ifdef SE_ENABLE_FTSEARCH
	clear_ft_sequences();
#endif
#ifdef SE_ENABLE_TRIGGERS
	apply_per_statement_triggers(&arg1seq, false, NULL, false, TRIGGER_BEFORE, TRIGGER_REPLACE_EVENT);
#endif
	//sorting arg1seq
	arg3seq.clear();
	xptr_sequence::iterator it=arg1seq.begin();
	xptr_sequence::iterator sit=arg2seq.begin();
	int ctr=0;
	do
	{
		tuple tup(2);
		tup.copy(tuple_cell::node(removeIndirection(*it)),tuple_cell((__int64)ctr));
		arg3seq.add(tup);
		while(*sit!=XNULL)
		{
			sit++;
			ctr++;
		}
		sit++;
		ctr++;
		it++;
	}
	while (it!=arg1seq.end());
	arg3seq.sort();
	it3=arg3seq.begin();
	descript_sequence arg4seq(2);
	do
	{
		node=(*it3).cells[0].get_node();
		CHECKP(node);
		xptr tind=((n_dsc*)XADDR(node))->indir;
		tuple t=(*it3);
		t.cells[0].set_node(tind);
		++it3;
		arg4seq.add(t);

	}
	while (it3!=arg3seq.end());

	// deleting- inserting new nodes
	it3=arg4seq.end();
	do
	{
		--it3;
		node = old_node = removeIndirection((*it3).cells[0].get_node());
		int pos=(*it3).cells[1].get_xs_integer();
		sit=arg2seq.begin()+pos;
		CHECKP(node);
		xptr leftn=((n_dsc*)XADDR(old_node))->ldsc;
		xptr rightn=((n_dsc*)XADDR(old_node))->rdsc;
		xptr par_ind=((n_dsc*)XADDR(old_node))->pdsc;
		bool a_m=is_node_attribute(node);
		bool d_m=a_m||is_node_text(node);

#ifdef SE_ENABLE_TRIGGERS
		CHECKP(old_node);
		scm_node = GETSCHEMENODEX(old_node);
		parent=removeIndirection(((n_dsc*)XADDR(old_node))->pdsc);
		CHECKP(old_node);
		tmp_node = prepare_old_node(old_node, scm_node, TRIGGER_REPLACE_EVENT);
#endif

#ifdef SE_ENABLE_TRIGGERS
        // Before-for-each-node triggers (cycle for all inserted nodes)
		xptr_sequence::iterator tr_it=sit;
    	while(*tr_it!=XNULL)
        {
            node_child=*tr_it;
            parent=removeIndirection(par_ind);
            if(apply_per_node_triggers(removeIndirection(node_child), old_node, parent, scm_node, TRIGGER_BEFORE, TRIGGER_REPLACE_EVENT) == XNULL)
               goto next_replacement;
            tr_it++;
		}
#endif

		//pre_deletion
		if (d_m)
		{
			delete_node(old_node);
		}
		//1.inserting attributes from sequence
		while(*sit!=XNULL)
		{
			node_child=*sit;
			if (!is_node_attribute(removeIndirection(node_child)))
				break;
			parent=removeIndirection(par_ind);

			if (is_node_persistent(node_child))
						node=deep_pers_copy(XNULL, XNULL, parent, removeIndirection(node_child),true);
			else
						node=deep_temp_copy(XNULL, XNULL, parent, removeIndirection(node_child),ins_swiz);
			sit++;
#ifdef SE_ENABLE_TRIGGERS
			apply_per_node_triggers(node, tmp_node, parent, scm_node, TRIGGER_AFTER, TRIGGER_REPLACE_EVENT);
#endif
		}
		//2. finding place of insertion
		if (a_m)
		{
			node=getFirstByOrderChildNode(removeIndirection(par_ind));
			if (node!=XNULL)
			{
				if (is_node_element(node))
				{
					rightn=node;
					node=XNULL;
				}
				else
				{
					rightn=XNULL;
				}
			}
		}
		else
		{
			if (d_m)
			{
				if (rightn==XNULL)
					node=leftn;
				else
					node=XNULL;
			}
			else
			{

			}

		}
		//3.main insert cycle
		while(*sit!=XNULL)
		{
			node_child=*sit;
			parent=removeIndirection(par_ind);
			if (is_node_persistent(node_child))
						node=deep_pers_copy(node, rightn, parent, removeIndirection(node_child),true);
					else
						node=deep_temp_copy(node, rightn, parent, removeIndirection(node_child),ins_swiz);
			sit++;
#ifdef SE_ENABLE_TRIGGERS
			apply_per_node_triggers(node, tmp_node, parent, scm_node, TRIGGER_AFTER, TRIGGER_REPLACE_EVENT);
#endif
		}
		//post_deletion
		if (!d_m)
		{
			del_node = removeIndirection((*it3).cells[0].get_node());
			CHECKP(del_node);
			delete_node(del_node);
		}
/*
	#ifdef SE_ENABLE_TRIGGERS
			CHECKP(old_node);
			scm_node = GETSCHEMENODEX(old_node);
			parent=removeIndirection(((n_dsc*)XADDR(old_node))->pdsc);
			CHECKP(old_node);
			tmp_node = prepare_old_node(old_node, scm_node, TRIGGER_REPLACE_EVENT);
	#endif

			//1.insert

			while(*sit!=XNULL)
			{
				node_child=*sit;
	#ifdef SE_ENABLE_TRIGGERS
				repl_node_child = apply_per_node_triggers(removeIndirection(node_child), old_node, XNULL, scm_node, TRIGGER_BEFORE, TRIGGER_REPLACE_EVENT);
				if(repl_node_child==XNULL) goto next_replacement;
				CHECKP(repl_node_child);
				node_child = ((n_dsc*)XADDR(repl_node_child))->indir;
	#endif
				CHECKP(node);
				if ( is_node_attribute(removeIndirection(node_child)))
				{
					parent=removeIndirection(GETPARENTPOINTER(node));
					if (is_node_persistent(node_child))
						node=deep_pers_copy(XNULL, XNULL, parent, removeIndirection(node_child),true);
					else
						node=deep_temp_copy(XNULL, XNULL, parent, removeIndirection(node_child),ins_swiz);
				}
				else
				{
					if (is_node_persistent(node_child))
						node=deep_pers_copy(node, XNULL, XNULL, removeIndirection(node_child),true);
					else
						node=deep_temp_copy(node, XNULL, XNULL, removeIndirection(node_child),ins_swiz);
				}
				sit++;
			}

			//delete node
			del_node = removeIndirection((*it3).cells[0].get_node());
			CHECKP(del_node);
			delete_node(del_node);

	#ifdef SE_ENABLE_TRIGGERS
			apply_per_node_triggers(node, tmp_node, parent, scm_node, TRIGGER_AFTER, TRIGGER_REPLACE_EVENT);
	#endif
		}
		if (border!=XNULL)
		{
			delete_node(removeIndirection(border));
			border=XNULL;
		}
*/
next_replacement:;
	}
	while (it3!=arg4seq.begin());
	//3.delete
/*	arg2seq.clear();
	it=arg1seq.begin();
	while (it!=arg1seq.end())
	{
		arg2seq.add(removeIndirection(*it));
		++it;
	}
	arg2seq.sort();
	it=arg2seq.end();
	do
	{
		--it;
		delete_node(*it);
		if (it==arg2seq.begin()) break;
	}
	while (true);
*/
	if (ins_swiz!=NULL)
	{
//		checkSwiizleTab(ins_swiz);
		delete ins_swiz;
	}
	clear_temp();
#ifdef SE_ENABLE_FTSEARCH
	execute_modifications();
#endif
#ifdef SE_ENABLE_TRIGGERS
	apply_per_statement_triggers(NULL, false, NULL, false, TRIGGER_AFTER, TRIGGER_REPLACE_EVENT);
#endif
}<|endoftext|>


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

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

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

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

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

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

#include "wizard.h"
#include "wizardpage.h"
#include "kleo-assuan.h"

#include <KLocale>
#include <KPushButton>

#include <QDialogButtonBox>
#include <QFrame>
#include <QLabel>
#include <QStackedWidget>
#include <QVBoxLayout>
#include <QWizard>

#include <map>

#include <cassert>

using namespace Kleo;

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

    void updateButtonStates();
    bool isLastPage( int id ) const;
    int previousPage() const;

private:
    std::vector<int> pageOrder;
    std::map<int, WizardPage*> idToPage;
    int currentId;
    QStackedWidget* stack;
    QPushButton* nextButton;
    QPushButton* backButton;
    QString finishItem;
    QString nextItem;
    QFrame* titleFrame;
    QLabel* titleLabel;
    QLabel* subTitleLabel;
};

Wizard::Private::Private( Wizard * qq )
    : q( qq ), currentId( -1 ), stack( new QStackedWidget )
{
    const QWizard wiz;
    nextItem = wiz.buttonText( QWizard::NextButton );
    finishItem = wiz.buttonText( QWizard::FinishButton );
    QVBoxLayout * const top = new QVBoxLayout( q );
    top->setMargin( 0 );
    titleFrame = new QFrame;
    titleFrame->setFrameShape( QFrame::StyledPanel );
    titleFrame->setAutoFillBackground( true );
    titleFrame->setBackgroundRole( QPalette::Base );
    QVBoxLayout* const titleLayout = new QVBoxLayout( titleFrame );
    titleLabel = new QLabel;
    titleLayout->addWidget( titleLabel );
    subTitleLabel = new QLabel;
    subTitleLabel->setWordWrap( true );
    titleLayout->addWidget( subTitleLabel );
    top->addWidget( titleFrame );
    titleFrame->setVisible( false );
    QWidget* const contentWidget = new QWidget;
    QVBoxLayout* const contentLayout = new QVBoxLayout( contentWidget );
    contentLayout->addWidget( stack );
    QDialogButtonBox * const box = new QDialogButtonBox;
    QAbstractButton* const cancelButton = box->addButton( QDialogButtonBox::Cancel );
    q->connect( cancelButton, SIGNAL( clicked() ), q, SLOT( reject() ) );

    backButton = new QPushButton;
    backButton->setText( wiz.buttonText( QWizard::BackButton ) );
    q->connect( backButton, SIGNAL( clicked() ), q, SLOT( back() ) );
    box->addButton( backButton, QDialogButtonBox::ActionRole );

    nextButton = new QPushButton;
    nextButton->setText( nextItem );
    q->connect( nextButton, SIGNAL( clicked() ), q, SLOT( next() ) );
    box->addButton( nextButton, QDialogButtonBox::ActionRole );

    contentLayout->addWidget( box );
    top->addWidget( contentWidget );

    q->connect( q, SIGNAL( rejected() ), q, SIGNAL( canceled() ) );
    q->resize( QSize( 640, 480 ).expandedTo( q->sizeHint() ) );
}

Wizard::Private::~Private() {}

bool Wizard::Private::isLastPage( int id ) const
{
    return !pageOrder.empty() ? pageOrder.back() == id : false;
}

void Wizard::Private::updateButtonStates()
{
    const bool isLast = isLastPage( currentId );
    nextButton->setText( isLast ? finishItem : nextItem );
    nextButton->setEnabled( q->canGoToNextPage() );
    backButton->setEnabled( q->canGoToPreviousPage() );
}

Wizard::Wizard( QWidget * parent, Qt::WFlags f )
  : QDialog( parent, f ), d( new Private( this ) )
{

}

Wizard::~Wizard() {}

void Wizard::setPage( int id, WizardPage* widget )
{
    assuan_assert( id != InvalidPage );
    assuan_assert( d->idToPage.find( id ) == d->idToPage.end() );
    d->idToPage[id] = widget;
    d->stack->addWidget( widget );
    connect( widget, SIGNAL( completeChanged() ), this, SLOT( updateButtonStates() ) );

}

void Wizard::setPageOrder( const std::vector<int>& pageOrder )
{
    d->pageOrder = pageOrder;
    if ( pageOrder.empty() )
        return;
    setCurrentPage( pageOrder.front() );
}

void Wizard::setCurrentPage( int id )
{
    d->currentId = id;
    if ( id == InvalidPage )
        return;
    WizardPage * const widget = page( id );
    assert( widget && d->stack->indexOf( widget ) != -1 );
    d->stack->setCurrentWidget( widget );
    const QString title = widget->title();
    const QString subTitle = widget->subTitle();
    d->titleFrame->setVisible( !title.isEmpty() || !subTitle.isEmpty() );
    d->titleLabel->setText( title );
    d->subTitleLabel->setText( subTitle );
    d->updateButtonStates();
}

void Wizard::skipPage( int id )
{
    const std::vector<int>::iterator it = qBinaryFind( d->pageOrder.begin(), d->pageOrder.end(), id );
    if ( it == d->pageOrder.end() )
        return;

    if ( currentPage() == id )
        next();

    d->pageOrder.erase( it );

}

int Wizard::currentPage() const
{
    return d->currentId;
}

bool Wizard::canGoToNextPage() const
{
    const WizardPage * const current = currentPageWidget();
    return current ? current->isComplete() : false;
}

bool Wizard::canGoToPreviousPage() const
{
    const int prev = d->previousPage();
    if ( prev == InvalidPage )
        return false;
    const WizardPage * const prevPage = page( prev );
    assert( prevPage );
    return !prevPage->isCommitPage();
}

void Wizard::next()
{
    std::vector<int>::const_iterator it = qBinaryFind( d->pageOrder.begin(), d->pageOrder.end(), d->currentId );
    assert( it != d->pageOrder.end() );
    ++it;
    if ( it == d->pageOrder.end() ) // "Finish"
    {
        d->currentId = InvalidPage;
        close();
    }
    else // "next"
    {
        setCurrentPage( *it );
    }
}

int Wizard::Private::previousPage() const
{
   if ( pageOrder.empty() )
        return InvalidPage;

    std::vector<int>::const_iterator it = qBinaryFind( pageOrder.begin(), pageOrder.end(), currentId );
    if ( it == pageOrder.begin() || it == pageOrder.end() )
        return InvalidPage;

    --it;
    return *it;
}

void Wizard::back()
{
    const int prev = d->previousPage();
    if ( prev == InvalidPage )
        return;
    setCurrentPage( prev );
}

const WizardPage* Wizard::page( int id ) const
{
    if ( id == InvalidPage )
        return 0;

    const std::map<int, WizardPage*>::const_iterator it = d->idToPage.find( id );
    assuan_assert( it != d->idToPage.end() );
    return (*it).second;
}

const WizardPage* Wizard::currentPageWidget() const
{
    return page( d->currentId );
}

WizardPage* Wizard::currentPageWidget()
{
    return page( d->currentId );
}

void Wizard::onNext( int currentId )
{
    Q_UNUSED( currentId )
}

void Wizard::onBack( int currentId )
{
    Q_UNUSED( currentId )
}

WizardPage* Wizard::page( int id )
{
    if ( id == InvalidPage )
        return 0;

    const std::map<int, WizardPage*>::const_iterator it = d->idToPage.find( id );
    assuan_assert( it != d->idToPage.end() );
    return (*it).second;
}

#include "moc_wizard.cpp"
<commit_msg>call onNext/onBack<commit_after>/* -*- mode: c++; c-basic-offset:4 -*-
    wizard.cpp

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

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

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

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

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

#include "wizard.h"
#include "wizardpage.h"
#include "kleo-assuan.h"

#include <KLocale>
#include <KPushButton>

#include <QDialogButtonBox>
#include <QFrame>
#include <QLabel>
#include <QStackedWidget>
#include <QVBoxLayout>
#include <QWizard>

#include <map>

#include <cassert>

using namespace Kleo;

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

    void updateButtonStates();
    bool isLastPage( int id ) const;
    int previousPage() const;

private:
    std::vector<int> pageOrder;
    std::map<int, WizardPage*> idToPage;
    int currentId;
    QStackedWidget* stack;
    QPushButton* nextButton;
    QPushButton* backButton;
    QString finishItem;
    QString nextItem;
    QFrame* titleFrame;
    QLabel* titleLabel;
    QLabel* subTitleLabel;
};

Wizard::Private::Private( Wizard * qq )
    : q( qq ), currentId( -1 ), stack( new QStackedWidget )
{
    const QWizard wiz;
    nextItem = wiz.buttonText( QWizard::NextButton );
    finishItem = wiz.buttonText( QWizard::FinishButton );
    QVBoxLayout * const top = new QVBoxLayout( q );
    top->setMargin( 0 );
    titleFrame = new QFrame;
    titleFrame->setFrameShape( QFrame::StyledPanel );
    titleFrame->setAutoFillBackground( true );
    titleFrame->setBackgroundRole( QPalette::Base );
    QVBoxLayout* const titleLayout = new QVBoxLayout( titleFrame );
    titleLabel = new QLabel;
    titleLayout->addWidget( titleLabel );
    subTitleLabel = new QLabel;
    subTitleLabel->setWordWrap( true );
    titleLayout->addWidget( subTitleLabel );
    top->addWidget( titleFrame );
    titleFrame->setVisible( false );
    QWidget* const contentWidget = new QWidget;
    QVBoxLayout* const contentLayout = new QVBoxLayout( contentWidget );
    contentLayout->addWidget( stack );
    QDialogButtonBox * const box = new QDialogButtonBox;
    QAbstractButton* const cancelButton = box->addButton( QDialogButtonBox::Cancel );
    q->connect( cancelButton, SIGNAL( clicked() ), q, SLOT( reject() ) );

    backButton = new QPushButton;
    backButton->setText( wiz.buttonText( QWizard::BackButton ) );
    q->connect( backButton, SIGNAL( clicked() ), q, SLOT( back() ) );
    box->addButton( backButton, QDialogButtonBox::ActionRole );

    nextButton = new QPushButton;
    nextButton->setText( nextItem );
    q->connect( nextButton, SIGNAL( clicked() ), q, SLOT( next() ) );
    box->addButton( nextButton, QDialogButtonBox::ActionRole );

    contentLayout->addWidget( box );
    top->addWidget( contentWidget );

    q->connect( q, SIGNAL( rejected() ), q, SIGNAL( canceled() ) );
    q->resize( QSize( 640, 480 ).expandedTo( q->sizeHint() ) );
}

Wizard::Private::~Private() {}

bool Wizard::Private::isLastPage( int id ) const
{
    return !pageOrder.empty() ? pageOrder.back() == id : false;
}

void Wizard::Private::updateButtonStates()
{
    const bool isLast = isLastPage( currentId );
    nextButton->setText( isLast ? finishItem : nextItem );
    nextButton->setEnabled( q->canGoToNextPage() );
    backButton->setEnabled( q->canGoToPreviousPage() );
}

Wizard::Wizard( QWidget * parent, Qt::WFlags f )
  : QDialog( parent, f ), d( new Private( this ) )
{

}

Wizard::~Wizard() {}

void Wizard::setPage( int id, WizardPage* widget )
{
    assuan_assert( id != InvalidPage );
    assuan_assert( d->idToPage.find( id ) == d->idToPage.end() );
    d->idToPage[id] = widget;
    d->stack->addWidget( widget );
    connect( widget, SIGNAL( completeChanged() ), this, SLOT( updateButtonStates() ) );

}

void Wizard::setPageOrder( const std::vector<int>& pageOrder )
{
    d->pageOrder = pageOrder;
    if ( pageOrder.empty() )
        return;
    setCurrentPage( pageOrder.front() );
}

void Wizard::setCurrentPage( int id )
{
    d->currentId = id;
    if ( id == InvalidPage )
        return;
    WizardPage * const widget = page( id );
    assert( widget && d->stack->indexOf( widget ) != -1 );
    d->stack->setCurrentWidget( widget );
    const QString title = widget->title();
    const QString subTitle = widget->subTitle();
    d->titleFrame->setVisible( !title.isEmpty() || !subTitle.isEmpty() );
    d->titleLabel->setText( title );
    d->subTitleLabel->setText( subTitle );
    d->updateButtonStates();
}

void Wizard::skipPage( int id )
{
    const std::vector<int>::iterator it = qBinaryFind( d->pageOrder.begin(), d->pageOrder.end(), id );
    if ( it == d->pageOrder.end() )
        return;

    if ( currentPage() == id )
        next();

    d->pageOrder.erase( it );

}

int Wizard::currentPage() const
{
    return d->currentId;
}

bool Wizard::canGoToNextPage() const
{
    const WizardPage * const current = currentPageWidget();
    return current ? current->isComplete() : false;
}

bool Wizard::canGoToPreviousPage() const
{
    const int prev = d->previousPage();
    if ( prev == InvalidPage )
        return false;
    const WizardPage * const prevPage = page( prev );
    assert( prevPage );
    return !prevPage->isCommitPage();
}

void Wizard::next()
{
    onNext( d->currentId );
    std::vector<int>::const_iterator it = qBinaryFind( d->pageOrder.begin(), d->pageOrder.end(), d->currentId );
    assert( it != d->pageOrder.end() );
    ++it;
    if ( it == d->pageOrder.end() ) // "Finish"
    {
        d->currentId = InvalidPage;
        close();
    }
    else // "next"
    {
        setCurrentPage( *it );
    }
}

int Wizard::Private::previousPage() const
{
   if ( pageOrder.empty() )
        return InvalidPage;

    std::vector<int>::const_iterator it = qBinaryFind( pageOrder.begin(), pageOrder.end(), currentId );
    if ( it == pageOrder.begin() || it == pageOrder.end() )
        return InvalidPage;

    --it;
    return *it;
}

void Wizard::back()
{
    onBack( d->currentId );
    const int prev = d->previousPage();
    if ( prev == InvalidPage )
        return;
    setCurrentPage( prev );
}

const WizardPage* Wizard::page( int id ) const
{
    if ( id == InvalidPage )
        return 0;

    const std::map<int, WizardPage*>::const_iterator it = d->idToPage.find( id );
    assuan_assert( it != d->idToPage.end() );
    return (*it).second;
}

const WizardPage* Wizard::currentPageWidget() const
{
    return page( d->currentId );
}

WizardPage* Wizard::currentPageWidget()
{
    return page( d->currentId );
}

void Wizard::onNext( int currentId )
{
    Q_UNUSED( currentId )
}

void Wizard::onBack( int currentId )
{
    Q_UNUSED( currentId )
}

WizardPage* Wizard::page( int id )
{
    if ( id == InvalidPage )
        return 0;

    const std::map<int, WizardPage*>::const_iterator it = d->idToPage.find( id );
    assuan_assert( it != d->idToPage.end() );
    return (*it).second;
}

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


<commit_before>/* Copyright 2009 Klarälvdalens Datakonsult AB

   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) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

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

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "archivefolderdialog.h"

#include "backupjob.h"
#include "kmkernel.h"
#include "kmfolder.h"
#include "kmmainwidget.h"
#include "folderrequester.h"
#include "util.h"

#include <klocale.h>
#include <kcombobox.h>
#include <kurlrequester.h>
#include <kmessagebox.h>

#include <qlabel.h>
#include <qcheckbox.h>
#include <qlayout.h>

using namespace KMail;

static QString standardArchivePath( const QString &folderName )
{
  return KGlobalSettings::documentPath() + '/' +
    i18nc( "Start of the filename for a mail archive file" , "Archive" ) + '_' + folderName + '_' + QDate::currentDate().toString( Qt::ISODate ) + ".zip";
}

ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent )
  : KDialog( parent ), mParentWidget( parent )
{
  setObjectName( "archive_folder_dialog" );
  setCaption( i18n( "Archive Folder" ) );
  setButtons( Ok|Cancel );
  setDefaultButton( Ok );
  setModal( true );
  QWidget *mainWidget = new QWidget( this );
  QGridLayout *mainLayout = new QGridLayout( mainWidget );
  mainLayout->setSpacing( KDialog::spacingHint() );
  mainLayout->setMargin( KDialog::marginHint() );
  setMainWidget( mainWidget );

  int row = 0;

  // TODO: better label for "Ok" button
  // TODO: Explaination label
  // TODO: Use QFormLayout in KDE4

  QLabel *folderLabel = new QLabel( i18n( "&Folder:" ), mainWidget );
  mainLayout->addWidget( folderLabel, row, 0 );
  mFolderRequester = new FolderRequester( mainWidget );
  mFolderRequester->setMustBeReadWrite( false );
  mFolderRequester->setFolderTree( kmkernel->getKMMainWidget()->mainFolderView() );
  connect( mFolderRequester, SIGNAL( folderChanged( KMFolder* ) ), SLOT( slotFolderChanged( KMFolder* ) ) );
  folderLabel->setBuddy( mFolderRequester );
  mainLayout->addWidget( mFolderRequester, row, 1 );
  row++;

  QLabel *formatLabel = new QLabel( i18n( "F&ormat:" ), mainWidget );
  mainLayout->addWidget( formatLabel, row, 0 );
  mFormatComboBox = new KComboBox( mainWidget );
  formatLabel->setBuddy( mFormatComboBox );

  // These combobox values have to stay in sync with the ArchiveType enum from BackupJob!
  mFormatComboBox->addItem( i18n( "Compressed Zip Archive (.zip)" ) );
  mFormatComboBox->addItem( i18n( "Uncompressed Archive (.tar)" ) );
  mFormatComboBox->addItem( i18n( "BZ2-Compressed Tar Archive (.tar.bz2)" ) );
  mFormatComboBox->addItem( i18n( "GZ-Compressed Tar Archive (.tar.gz)" ) );
  mFormatComboBox->setCurrentIndex( 0 );
  connect( mFormatComboBox, SIGNAL(activated(int)),
           this, SLOT(slotFixFileExtension()) );
  mainLayout->addWidget( mFormatComboBox, row, 1 );
  row++;

  QLabel *fileNameLabel = new QLabel( i18n( "&Archive File:" ), mainWidget );
  mainLayout->addWidget( fileNameLabel, row, 0 );
  mUrlRequester = new KUrlRequester( mainWidget );
  mUrlRequester->setMode( KFile::LocalOnly | KFile::File );
  mUrlRequester->setFilter( "*.tar *.zip *.tar.gz *.tar.bz2" );
  fileNameLabel->setBuddy( mUrlRequester );
  connect( mUrlRequester->lineEdit(), SIGNAL(textChanged(const QString &)), SLOT( slotUrlChanged(const QString&)));
  connect( mUrlRequester, SIGNAL(urlSelected(const KUrl&)),
           this, SLOT(slotFixFileExtension()) );
  mainLayout->addWidget( mUrlRequester, row, 1 );
  row++;

  // TODO: Make this appear more dangerous!
  mDeleteCheckBox = new QCheckBox( i18n( "&Delete folders after completion" ), mainWidget );
  mainLayout->addWidget( mDeleteCheckBox, row, 0, 1, 2, Qt::AlignLeft );
  row++;

  // TODO: what's this, tooltips

  // TODO: Warn that user should do mail check for online IMAP and possibly cached IMAP as well

  mainLayout->setColumnStretch( 1, 1 );
  mainLayout->addItem( new QSpacerItem( 1, 1, QSizePolicy::Expanding, QSizePolicy::Expanding ), row, 0 );

  // Make it a bit bigger, else the folder requester cuts off the text too early
  resize( 500, minimumSize().height() );
}

void ArchiveFolderDialog::slotUrlChanged( const QString & text)
{
  enableButtonOk( !text.isEmpty() );
}

void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder )
{
  mDeleteCheckBox->setEnabled( folder->canDeleteMessages() );
}

void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder )
{
  mFolderRequester->setFolder( defaultFolder );
  // TODO: what if the file already exists?
  mUrlRequester->setUrl( standardArchivePath( defaultFolder->name() ) );
  mDeleteCheckBox->setEnabled( defaultFolder->canDeleteMessages() );
}

void ArchiveFolderDialog::slotButtonClicked( int button )
{
  if ( button == KDialog::Cancel ) {
    reject();
    return;
  }
  Q_ASSERT( button == KDialog::Ok );

  if ( !Util::checkOverwrite( mUrlRequester->url(), this ) ) {
    return;
  }

  if ( !mFolderRequester->folder() ) {
    KMessageBox::information( this, i18n( "Please select the folder that should be archived." ),
                              i18n( "No folder selected" ) );
    return;
  }

  // TODO: check if url is empty. or better yet, disable ok button until file is chosen
  KMail::BackupJob *backupJob = new KMail::BackupJob( mParentWidget );
  backupJob->setRootFolder( mFolderRequester->folder() );
  backupJob->setSaveLocation( mUrlRequester->url() );
  backupJob->setArchiveType( static_cast<BackupJob::ArchiveType>( mFormatComboBox->currentIndex() ) );
  backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isChecked() && mFolderRequester->folder()->canDeleteMessages());
  backupJob->start();
  accept();
}

void ArchiveFolderDialog::slotFixFileExtension()
{
  // KDE4: use KMimeType::extractKnownExtension() here
  const int numExtensions = 4;

  // These extensions are sorted differently, .tar has to come last, or it will match before giving
  // the more specific ones time to match.
  const char *sortedExtensions[numExtensions] = { ".zip", ".tar.bz2", ".tar.gz", ".tar" };

  // The extensions here are also sorted, like the enum order of BackupJob::ArchiveType
  const char *extensions[numExtensions] = { ".zip", ".tar", ".tar.bz2", ".tar.gz" };

  QString fileName = mUrlRequester->url().path();

  // First, try to find the extension of the file name and remove it
  for( int i = 0; i < numExtensions; i++ ) {
    int index = fileName.toLower().lastIndexOf( sortedExtensions[i] );
    if ( index != -1 ) {
      fileName = fileName.left( fileName.length() - QString( sortedExtensions[i] ).length() );
      break;
    }
  }

  // Now, we've got a filename without an extension, simply append the correct one
  fileName += extensions[mFormatComboBox->currentIndex()];
  mUrlRequester->setUrl( fileName );
}

#include "archivefolderdialog.moc"
<commit_msg>Fix crash when we select an nul folder (LocalFolder) and don't select folder which can't have content (as top level in imap account) MERGE: in trunk/e4/e5 and other if necessary (don't know)<commit_after>/* Copyright 2009 Klarälvdalens Datakonsult AB

   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) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

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

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "archivefolderdialog.h"

#include "backupjob.h"
#include "kmkernel.h"
#include "kmfolder.h"
#include "kmmainwidget.h"
#include "folderrequester.h"
#include "util.h"

#include <klocale.h>
#include <kcombobox.h>
#include <kurlrequester.h>
#include <kmessagebox.h>

#include <qlabel.h>
#include <qcheckbox.h>
#include <qlayout.h>

using namespace KMail;

static QString standardArchivePath( const QString &folderName )
{
  return KGlobalSettings::documentPath() + '/' +
    i18nc( "Start of the filename for a mail archive file" , "Archive" ) + '_' + folderName + '_' + QDate::currentDate().toString( Qt::ISODate ) + ".zip";
}

ArchiveFolderDialog::ArchiveFolderDialog( QWidget *parent )
  : KDialog( parent ), mParentWidget( parent )
{
  setObjectName( "archive_folder_dialog" );
  setCaption( i18n( "Archive Folder" ) );
  setButtons( Ok|Cancel );
  setDefaultButton( Ok );
  setModal( true );
  QWidget *mainWidget = new QWidget( this );
  QGridLayout *mainLayout = new QGridLayout( mainWidget );
  mainLayout->setSpacing( KDialog::spacingHint() );
  mainLayout->setMargin( KDialog::marginHint() );
  setMainWidget( mainWidget );

  int row = 0;

  // TODO: better label for "Ok" button
  // TODO: Explaination label
  // TODO: Use QFormLayout in KDE4

  QLabel *folderLabel = new QLabel( i18n( "&Folder:" ), mainWidget );
  mainLayout->addWidget( folderLabel, row, 0 );
  mFolderRequester = new FolderRequester( mainWidget );
  mFolderRequester->setMustBeReadWrite( false );
  mFolderRequester->setFolderTree( kmkernel->getKMMainWidget()->mainFolderView() );
  connect( mFolderRequester, SIGNAL( folderChanged( KMFolder* ) ), SLOT( slotFolderChanged( KMFolder* ) ) );
  folderLabel->setBuddy( mFolderRequester );
  mainLayout->addWidget( mFolderRequester, row, 1 );
  row++;

  QLabel *formatLabel = new QLabel( i18n( "F&ormat:" ), mainWidget );
  mainLayout->addWidget( formatLabel, row, 0 );
  mFormatComboBox = new KComboBox( mainWidget );
  formatLabel->setBuddy( mFormatComboBox );

  // These combobox values have to stay in sync with the ArchiveType enum from BackupJob!
  mFormatComboBox->addItem( i18n( "Compressed Zip Archive (.zip)" ) );
  mFormatComboBox->addItem( i18n( "Uncompressed Archive (.tar)" ) );
  mFormatComboBox->addItem( i18n( "BZ2-Compressed Tar Archive (.tar.bz2)" ) );
  mFormatComboBox->addItem( i18n( "GZ-Compressed Tar Archive (.tar.gz)" ) );
  mFormatComboBox->setCurrentIndex( 0 );
  connect( mFormatComboBox, SIGNAL(activated(int)),
           this, SLOT(slotFixFileExtension()) );
  mainLayout->addWidget( mFormatComboBox, row, 1 );
  row++;

  QLabel *fileNameLabel = new QLabel( i18n( "&Archive File:" ), mainWidget );
  mainLayout->addWidget( fileNameLabel, row, 0 );
  mUrlRequester = new KUrlRequester( mainWidget );
  mUrlRequester->setMode( KFile::LocalOnly | KFile::File );
  mUrlRequester->setFilter( "*.tar *.zip *.tar.gz *.tar.bz2" );
  fileNameLabel->setBuddy( mUrlRequester );
  connect( mUrlRequester->lineEdit(), SIGNAL(textChanged(const QString &)), SLOT( slotUrlChanged(const QString&)));
  connect( mUrlRequester, SIGNAL(urlSelected(const KUrl&)),
           this, SLOT(slotFixFileExtension()) );
  mainLayout->addWidget( mUrlRequester, row, 1 );
  row++;

  // TODO: Make this appear more dangerous!
  mDeleteCheckBox = new QCheckBox( i18n( "&Delete folders after completion" ), mainWidget );
  mainLayout->addWidget( mDeleteCheckBox, row, 0, 1, 2, Qt::AlignLeft );
  row++;

  // TODO: what's this, tooltips

  // TODO: Warn that user should do mail check for online IMAP and possibly cached IMAP as well

  mainLayout->setColumnStretch( 1, 1 );
  mainLayout->addItem( new QSpacerItem( 1, 1, QSizePolicy::Expanding, QSizePolicy::Expanding ), row, 0 );

  // Make it a bit bigger, else the folder requester cuts off the text too early
  resize( 500, minimumSize().height() );
}

void ArchiveFolderDialog::slotUrlChanged( const QString & text)
{
  enableButtonOk( !text.isEmpty() );
}

void ArchiveFolderDialog::slotFolderChanged( KMFolder *folder )
{
  mDeleteCheckBox->setEnabled( folder && folder->canDeleteMessages() && !folder->noContent());
  enableButtonOk( folder && !folder->noContent());
}

void ArchiveFolderDialog::setFolder( KMFolder *defaultFolder )
{
  mFolderRequester->setFolder( defaultFolder );
  // TODO: what if the file already exists?
  mUrlRequester->setUrl( standardArchivePath( defaultFolder->name() ) );
  mDeleteCheckBox->setEnabled( defaultFolder->canDeleteMessages() );
}

void ArchiveFolderDialog::slotButtonClicked( int button )
{
  if ( button == KDialog::Cancel ) {
    reject();
    return;
  }
  Q_ASSERT( button == KDialog::Ok );

  if ( !Util::checkOverwrite( mUrlRequester->url(), this ) ) {
    return;
  }

  if ( !mFolderRequester->folder() ) {
    KMessageBox::information( this, i18n( "Please select the folder that should be archived." ),
                              i18n( "No folder selected" ) );
    return;
  }

  // TODO: check if url is empty. or better yet, disable ok button until file is chosen
  KMail::BackupJob *backupJob = new KMail::BackupJob( mParentWidget );
  backupJob->setRootFolder( mFolderRequester->folder() );
  backupJob->setSaveLocation( mUrlRequester->url() );
  backupJob->setArchiveType( static_cast<BackupJob::ArchiveType>( mFormatComboBox->currentIndex() ) );
  backupJob->setDeleteFoldersAfterCompletion( mDeleteCheckBox->isChecked() && mFolderRequester->folder()->canDeleteMessages());
  backupJob->start();
  accept();
}

void ArchiveFolderDialog::slotFixFileExtension()
{
  // KDE4: use KMimeType::extractKnownExtension() here
  const int numExtensions = 4;

  // These extensions are sorted differently, .tar has to come last, or it will match before giving
  // the more specific ones time to match.
  const char *sortedExtensions[numExtensions] = { ".zip", ".tar.bz2", ".tar.gz", ".tar" };

  // The extensions here are also sorted, like the enum order of BackupJob::ArchiveType
  const char *extensions[numExtensions] = { ".zip", ".tar", ".tar.bz2", ".tar.gz" };

  QString fileName = mUrlRequester->url().path();

  // First, try to find the extension of the file name and remove it
  for( int i = 0; i < numExtensions; i++ ) {
    int index = fileName.toLower().lastIndexOf( sortedExtensions[i] );
    if ( index != -1 ) {
      fileName = fileName.left( fileName.length() - QString( sortedExtensions[i] ).length() );
      break;
    }
  }

  // Now, we've got a filename without an extension, simply append the correct one
  fileName += extensions[mFormatComboBox->currentIndex()];
  mUrlRequester->setUrl( fileName );
}

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


<commit_before>/* kpilotConfig.cc			KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
**
** This is all of KPilot's config-handling stuff.
*/

/*
** 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.
**
** 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

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

#include "options.h"

#include <stdlib.h>

#include <qlineedit.h>
#include <qcombobox.h>
#include <qcheckbox.h>

#include <kstddirs.h>
#include <kconfig.h>
#include <ksimpleconfig.h>
#include <kcmdlineargs.h>
#include <kmessagebox.h>
#include <kglobalsettings.h>

#include "kpilotSettings.h"
#include "kpilotConfig.h"

static const char kpilotconfig_id[] =
	"$Id$";

// This is a number indicating what configuration version
// we're dealing with. Whenever new configuration options are
// added that make it imperative for the user to take a
// look at the configuration of KPilot (for example the
// skipDB setting really needs user attention) we can change
// (increase) this number.
//
//
/* static */ const uint KPilotConfig::ConfigurationVersion = 443;

/* static */ int KPilotConfig::getConfigVersion()
{
	FUNCTIONSETUP;

	uint version = KPilotSettings::configVersion();

	if (version < ConfigurationVersion)
	{
		kdWarning() << k_funcinfo <<
			": Config file has old version " << version << endl;
	}
	else
	{
#ifdef DEBUG
		DEBUGDB << fname
			<< ": Config file has version " << version << endl;
#endif
	}

	return version;
}

/* static */ void KPilotConfig::updateConfigVersion()
{
	FUNCTIONSETUP;
	KPilotSettings::setConfigVersion( ConfigurationVersion );
}

/* static */ QString KPilotConfig::getDefaultDBPath()
{
	FUNCTIONSETUP;
	QString lastUser = KPilotSettings::userName();
	QString dbsubpath = CSL1("kpilot/DBBackup/");
	QString defaultDBPath = KGlobal::dirs()->
		saveLocation("data", dbsubpath + lastUser + CSL1("/"));
	return defaultDBPath;
}

/* static */ int KPilotConfig::getDebugLevel(KCmdLineArgs *p)
{
	FUNCTIONSETUP;

	if (p)
	{
		if (p->isSet("debug"))
		{
			debug_level = p->getOption("debug").toInt();
		}
	}

	return debug_level;
}

static QFont *thefont = 0L;

/* static */ const QFont & KPilotConfig::fixed()
{
	FUNCTIONSETUP;

	if (!thefont)
		thefont = new QFont(KGlobalSettings::fixedFont());

	return *thefont;
}

void KPilotConfig::addDirtyDatabase(QString db)
{
	FUNCTIONSETUP;
	QStringList l(KPilotSettings::dirtyDatabases());
	if (!l.contains(db))
	{
		l.append(db);
		KPilotSettings::setDirtyDatabases(l);
	}
}

void KPilotConfig::addAppBlockChangedDatabase(QString db)
{
	QStringList l(KPilotSettings::appBlockChangedDatabases());
	if (!l.contains(db))
	{
		l.append(db);
		KPilotSettings::setAppBlockChangedDatabases(l);
	}
}

void KPilotConfig::addFlagsChangedDatabase(QString db)
{
	QStringList l(KPilotSettings::flagsChangedDatabases());
	if (!l.contains(db))
	{
		l.append(db);
		KPilotSettings::setFlagsChangedDatabases(l);
	}
}

/* static */ QString KPilotConfig::versionDetails(int fileversion, bool run)
{
	FUNCTIONSETUP;
	QString s = CSL1("<qt>
");
	s += i18n("The configuration file is outdated.");
	s += ' ';
	s += i18n("The configuration file has version %1, while KPilot "
		"needs version %2.").arg(fileversion).arg(ConfigurationVersion);
	if (run)
	{
		s += ' ';
		s += i18n("Please run KPilot and check the configuration carefully "
			"to update the file.");
	}
	s += CSL1("

");
	s += i18n("Important changes to watch for are:");
	s += ' ';
	if (fileversion < 440)
	{
		s += i18n("Renamed conduits, Kroupware and file installer have "
			"been made conduits as well.");
		s += ' ';
		s += i18n("Conflict resolution is now a global setting.");
		s += ' ';
	}
	if (fileversion < 443)
	{
		s += i18n("Changed format of no-backup databases.");
		s += ' ';
	}
	// Insert more recent additions here

	return s;
}

/* static */ void KPilotConfig::sorryVersionOutdated(int fileversion)
{
	FUNCTIONSETUP;
	KMessageBox::detailedSorry(0L,
		i18n("The configuration file for KPilot is out-of "
			"date. Please run KPilot to update it."),
		KPilotConfig::versionDetails(fileversion,true),
		i18n("Configuration File Out-of Date"));
}

static void update440()
{
	// Try to update conduit list
	{
	QStringList conduits( KPilotSettings::installedConduits() );
	KConfig*c = KPilotSettings::self()->config();
///	c->resetGroup();
	c->setGroup( QString::null );
	bool useKroupware = c->readBoolEntry("SyncWithKMail",false);
	bool installFiles = c->readBoolEntry("SyncFiles",true);
	if (useKroupware) conduits.append( CSL1("internal_kroupware") );
	if (installFiles) conduits.append( CSL1("internal_fileinstall") );
	c->deleteEntry("SyncWithKMail");
	c->deleteEntry("SyncFiles");
	KPilotSettings::setInstalledConduits(conduits);
	c->sync();
	if (useKroupware || installFiles)
		KMessageBox::information(0L,
			i18n("The settings for Kroupware syncing with KMail "
				"and the file installer have been moved to the "
				"conduits configuration. Check the installed "
				"conduits list."),
			i18n("Settings Updated"));

	}

	// Check if individual conduits have conflict settings?

	// Search for old conduit libraries.
	{
	QStringList foundlibs ;
	static const char *oldconduits[] = { "null", "address", "doc",
		"knotes", "sysinfo", "time", "todo", "vcal", 0L } ;
	const char **s = oldconduits;
	while (*s)
	{
		QString libname = CSL1("kde3/lib%1conduit.so").arg(*s);
		QString foundlib = ::locate("lib",libname);
		if (!foundlib.isEmpty())
		{
			foundlibs.append(foundlib);
		}
		s++;
	}

	if (!foundlibs.isEmpty())
		KMessageBox::informationList(0L,
			i18n("<qt>The following old conduits were found on "
				"your system. It is a good idea to remove "
				"them and the associated <tt>.la</tt> "
				"and <tt>.so.0</tt> files.</qt>"),
			foundlibs,
			i18n("Old Conduits Found"));
	}
}

static void update443()
{
	FUNCTIONSETUP;

	QStringList skip = KPilotSettings::skipBackupDB();
	QStringList fixSkip;
	bool fixedSome = false;
#ifdef DEBUG
	DEBUGKPILOT << fname << ": Skip databases are: "
		<< skip.join(",") << endl;
#endif

	for (QStringList::const_iterator i = skip.begin(); i!=skip.end(); ++i)
	{
		if ((*i).length()==4)
		{
			fixSkip.append(CSL1("[%1]").arg(*i));
			fixedSome = true;
		}
		else
		{
			fixSkip.append(*i);
		}
	}

	if (fixedSome)
	{
		KMessageBox::informationList(0L,
			i18n("<qt>The no backup databases listed in your configuration file "
				"have been adjusted to the new format. Database creator IDs "
				"have been changed to use square brackets []."),
			fixSkip,
			i18n("No Backup Databases Updated"));
	}
}

/* static */ KPilotConfig::RunMode KPilotConfig::interactiveUpdate()
{
	FUNCTIONSETUP;

	int res = 0;
	unsigned int fileVersion = KPilotSettings::configVersion();
	// FIXME better config handling -> Move the config entries using kconf_update

	// It's OK if we're already at the required level.
	if (fileVersion >= KPilotConfig::ConfigurationVersion)
	{
		return Normal;
	}

	if (0 == fileVersion) // No config file at all
	{
		res = KMessageBox::questionYesNoCancel(0L,
			i18n("KPilot is not configured for use. You may use "
				"the configuration wizard or the normal configure dialog "
				"to configure KPilot."),
			i18n("Not Configured"),
			i18n("Use &Wizard"),
			i18n("Use &Dialog"));
		if (res == KMessageBox::Yes) return WizardAndContinue;
		if (res == KMessageBox::No) return ConfigureAndContinue;

		return Cancel;
	}

	res = KMessageBox::warningContinueCancel(0L,
		i18n("The configuration file for KPilot is out-of "
			"date. KPilot can update some parts of the "
			"configuration automatically. Do you wish to "
			"continue?"),
		i18n("Configuration File Out-of Date"));
	if (res!=KMessageBox::Continue) return Cancel;

#ifdef DEBUG
	DEBUGKPILOT << fname << ": Updating from "
		<< fileVersion << " to " << ConfigurationVersion << endl;
#endif

	if (fileVersion < 440) update440();
	if (fileVersion < 443) update443();

	KPilotConfig::updateConfigVersion();
	KPilotSettings::writeConfig();
	return ConfigureAndContinue;
}

void KPilotConfig::sync()
{
	KPilotSettings::self()->config()->sync();
}<commit_msg>CVS_SILENT: Fix compiler warning about missing newline at end of file<commit_after>/* kpilotConfig.cc			KPilot
**
** Copyright (C) 1998-2001 by Dan Pilone
**
** This is all of KPilot's config-handling stuff.
*/

/*
** 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.
**
** 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

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

#include "options.h"

#include <stdlib.h>

#include <qlineedit.h>
#include <qcombobox.h>
#include <qcheckbox.h>

#include <kstddirs.h>
#include <kconfig.h>
#include <ksimpleconfig.h>
#include <kcmdlineargs.h>
#include <kmessagebox.h>
#include <kglobalsettings.h>

#include "kpilotSettings.h"
#include "kpilotConfig.h"

static const char kpilotconfig_id[] =
	"$Id$";

// This is a number indicating what configuration version
// we're dealing with. Whenever new configuration options are
// added that make it imperative for the user to take a
// look at the configuration of KPilot (for example the
// skipDB setting really needs user attention) we can change
// (increase) this number.
//
//
/* static */ const uint KPilotConfig::ConfigurationVersion = 443;

/* static */ int KPilotConfig::getConfigVersion()
{
	FUNCTIONSETUP;

	uint version = KPilotSettings::configVersion();

	if (version < ConfigurationVersion)
	{
		kdWarning() << k_funcinfo <<
			": Config file has old version " << version << endl;
	}
	else
	{
#ifdef DEBUG
		DEBUGDB << fname
			<< ": Config file has version " << version << endl;
#endif
	}

	return version;
}

/* static */ void KPilotConfig::updateConfigVersion()
{
	FUNCTIONSETUP;
	KPilotSettings::setConfigVersion( ConfigurationVersion );
}

/* static */ QString KPilotConfig::getDefaultDBPath()
{
	FUNCTIONSETUP;
	QString lastUser = KPilotSettings::userName();
	QString dbsubpath = CSL1("kpilot/DBBackup/");
	QString defaultDBPath = KGlobal::dirs()->
		saveLocation("data", dbsubpath + lastUser + CSL1("/"));
	return defaultDBPath;
}

/* static */ int KPilotConfig::getDebugLevel(KCmdLineArgs *p)
{
	FUNCTIONSETUP;

	if (p)
	{
		if (p->isSet("debug"))
		{
			debug_level = p->getOption("debug").toInt();
		}
	}

	return debug_level;
}

static QFont *thefont = 0L;

/* static */ const QFont & KPilotConfig::fixed()
{
	FUNCTIONSETUP;

	if (!thefont)
		thefont = new QFont(KGlobalSettings::fixedFont());

	return *thefont;
}

void KPilotConfig::addDirtyDatabase(QString db)
{
	FUNCTIONSETUP;
	QStringList l(KPilotSettings::dirtyDatabases());
	if (!l.contains(db))
	{
		l.append(db);
		KPilotSettings::setDirtyDatabases(l);
	}
}

void KPilotConfig::addAppBlockChangedDatabase(QString db)
{
	QStringList l(KPilotSettings::appBlockChangedDatabases());
	if (!l.contains(db))
	{
		l.append(db);
		KPilotSettings::setAppBlockChangedDatabases(l);
	}
}

void KPilotConfig::addFlagsChangedDatabase(QString db)
{
	QStringList l(KPilotSettings::flagsChangedDatabases());
	if (!l.contains(db))
	{
		l.append(db);
		KPilotSettings::setFlagsChangedDatabases(l);
	}
}

/* static */ QString KPilotConfig::versionDetails(int fileversion, bool run)
{
	FUNCTIONSETUP;
	QString s = CSL1("<qt>
");
	s += i18n("The configuration file is outdated.");
	s += ' ';
	s += i18n("The configuration file has version %1, while KPilot "
		"needs version %2.").arg(fileversion).arg(ConfigurationVersion);
	if (run)
	{
		s += ' ';
		s += i18n("Please run KPilot and check the configuration carefully "
			"to update the file.");
	}
	s += CSL1("

");
	s += i18n("Important changes to watch for are:");
	s += ' ';
	if (fileversion < 440)
	{
		s += i18n("Renamed conduits, Kroupware and file installer have "
			"been made conduits as well.");
		s += ' ';
		s += i18n("Conflict resolution is now a global setting.");
		s += ' ';
	}
	if (fileversion < 443)
	{
		s += i18n("Changed format of no-backup databases.");
		s += ' ';
	}
	// Insert more recent additions here

	return s;
}

/* static */ void KPilotConfig::sorryVersionOutdated(int fileversion)
{
	FUNCTIONSETUP;
	KMessageBox::detailedSorry(0L,
		i18n("The configuration file for KPilot is out-of "
			"date. Please run KPilot to update it."),
		KPilotConfig::versionDetails(fileversion,true),
		i18n("Configuration File Out-of Date"));
}

static void update440()
{
	// Try to update conduit list
	{
	QStringList conduits( KPilotSettings::installedConduits() );
	KConfig*c = KPilotSettings::self()->config();
///	c->resetGroup();
	c->setGroup( QString::null );
	bool useKroupware = c->readBoolEntry("SyncWithKMail",false);
	bool installFiles = c->readBoolEntry("SyncFiles",true);
	if (useKroupware) conduits.append( CSL1("internal_kroupware") );
	if (installFiles) conduits.append( CSL1("internal_fileinstall") );
	c->deleteEntry("SyncWithKMail");
	c->deleteEntry("SyncFiles");
	KPilotSettings::setInstalledConduits(conduits);
	c->sync();
	if (useKroupware || installFiles)
		KMessageBox::information(0L,
			i18n("The settings for Kroupware syncing with KMail "
				"and the file installer have been moved to the "
				"conduits configuration. Check the installed "
				"conduits list."),
			i18n("Settings Updated"));

	}

	// Check if individual conduits have conflict settings?

	// Search for old conduit libraries.
	{
	QStringList foundlibs ;
	static const char *oldconduits[] = { "null", "address", "doc",
		"knotes", "sysinfo", "time", "todo", "vcal", 0L } ;
	const char **s = oldconduits;
	while (*s)
	{
		QString libname = CSL1("kde3/lib%1conduit.so").arg(*s);
		QString foundlib = ::locate("lib",libname);
		if (!foundlib.isEmpty())
		{
			foundlibs.append(foundlib);
		}
		s++;
	}

	if (!foundlibs.isEmpty())
		KMessageBox::informationList(0L,
			i18n("<qt>The following old conduits were found on "
				"your system. It is a good idea to remove "
				"them and the associated <tt>.la</tt> "
				"and <tt>.so.0</tt> files.</qt>"),
			foundlibs,
			i18n("Old Conduits Found"));
	}
}

static void update443()
{
	FUNCTIONSETUP;

	QStringList skip = KPilotSettings::skipBackupDB();
	QStringList fixSkip;
	bool fixedSome = false;
#ifdef DEBUG
	DEBUGKPILOT << fname << ": Skip databases are: "
		<< skip.join(",") << endl;
#endif

	for (QStringList::const_iterator i = skip.begin(); i!=skip.end(); ++i)
	{
		if ((*i).length()==4)
		{
			fixSkip.append(CSL1("[%1]").arg(*i));
			fixedSome = true;
		}
		else
		{
			fixSkip.append(*i);
		}
	}

	if (fixedSome)
	{
		KMessageBox::informationList(0L,
			i18n("<qt>The no backup databases listed in your configuration file "
				"have been adjusted to the new format. Database creator IDs "
				"have been changed to use square brackets []."),
			fixSkip,
			i18n("No Backup Databases Updated"));
	}
}

/* static */ KPilotConfig::RunMode KPilotConfig::interactiveUpdate()
{
	FUNCTIONSETUP;

	int res = 0;
	unsigned int fileVersion = KPilotSettings::configVersion();
	// FIXME better config handling -> Move the config entries using kconf_update

	// It's OK if we're already at the required level.
	if (fileVersion >= KPilotConfig::ConfigurationVersion)
	{
		return Normal;
	}

	if (0 == fileVersion) // No config file at all
	{
		res = KMessageBox::questionYesNoCancel(0L,
			i18n("KPilot is not configured for use. You may use "
				"the configuration wizard or the normal configure dialog "
				"to configure KPilot."),
			i18n("Not Configured"),
			i18n("Use &Wizard"),
			i18n("Use &Dialog"));
		if (res == KMessageBox::Yes) return WizardAndContinue;
		if (res == KMessageBox::No) return ConfigureAndContinue;

		return Cancel;
	}

	res = KMessageBox::warningContinueCancel(0L,
		i18n("The configuration file for KPilot is out-of "
			"date. KPilot can update some parts of the "
			"configuration automatically. Do you wish to "
			"continue?"),
		i18n("Configuration File Out-of Date"));
	if (res!=KMessageBox::Continue) return Cancel;

#ifdef DEBUG
	DEBUGKPILOT << fname << ": Updating from "
		<< fileVersion << " to " << ConfigurationVersion << endl;
#endif

	if (fileVersion < 440) update440();
	if (fileVersion < 443) update443();

	KPilotConfig::updateConfigVersion();
	KPilotSettings::writeConfig();
	return ConfigureAndContinue;
}

void KPilotConfig::sync()
{
	KPilotSettings::self()->config()->sync();
}
<|endoftext|>


<commit_before>// Copyright (C) 2010 - 2015 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

#include "CQRDFTreeView.h"
#include "CQRDFTreeViewItem.h"

#include "UI/CQMessageBox.h"
#include "UI/qtUtilities.h"

#include "MIRIAM/CRDFGraph.h"
#include "MIRIAM/CRDFParser.h"
// #include "MIRIAM/CRDFWriter.h"
#include "MIRIAM/CRDFSubject.h"

// #include "CopasiDataModel/CCopasiDataModel.h"
// #include "report/CKeyFactory.h"
// #include "model/CModel.h"
#include "model/CModelValue.h"
#include "model/CEvent.h"
#include "model/CReaction.h"
#include "function/CFunction.h"
// #include "utilities/CCopasiMessage.h"
#include "copasi/report/CCopasiRootContainer.h"

#define COL_SUBJECT    0
#define COL_PREDICATE  1
#define COL_OBJECT     2

CQRDFTreeView::CQRDFTreeView(QWidget* parent, const char* name) :
  CopasiWidget(parent, name),
  mNode2Item(),
  mpGraph(NULL)
{
  setupUi(this);
}

CQRDFTreeView::~CQRDFTreeView()
{
  clear();
}

bool CQRDFTreeView::update(ListViews::ObjectType /* objectType */,
                           ListViews::Action /* action */,
                           const std::string & /* key */)
{
  return true;
}

bool CQRDFTreeView::enterProtected()
{
  clear();

  CCopasiObject *pObject = dynamic_cast< CCopasiObject * >(CCopasiRootContainer::getKeyFactory()->get(mKey));

  if (pObject != NULL)
    {
      CModelEntity * pEntity = NULL;
      CEvent * pEvent = NULL;
      CReaction * pReaction = NULL;
      CFunction * pFunction = NULL;
      const std::string * pMiriamAnnotation = NULL;

      if ((pEntity = dynamic_cast< CModelEntity * >(pObject)) != NULL)
        pMiriamAnnotation = &pEntity->getMiriamAnnotation();
      else if ((pEvent = dynamic_cast< CEvent * >(pObject)) != NULL)
        pMiriamAnnotation = &pEvent->getMiriamAnnotation();
      else if ((pReaction = dynamic_cast< CReaction * >(pObject)) != NULL)
        pMiriamAnnotation = &pReaction->getMiriamAnnotation();
      else if ((pFunction = dynamic_cast< CFunction * >(pObject)) != NULL)
        pMiriamAnnotation = &pFunction->getMiriamAnnotation();

      if (pMiriamAnnotation && *pMiriamAnnotation != "")
        mpGraph = CRDFParser::graphFromXml(*pMiriamAnnotation);
    }

  CCopasiMessage::clearDeque();

  if (CCopasiMessage::size() != 0)
    {
      QString Message = FROM_UTF8(CCopasiMessage::getAllMessageText());
      CQMessageBox::warning(this, QString("RDF Warning"), Message,
                            QMessageBox::Ok, QMessageBox::Ok);
    }

  if (mpGraph == NULL)
    mpGraph = new CRDFGraph;

  // We make sure that we always have an about node.
  mpGraph->createAboutNode(mKey);

  // We iterate of all triplets
  std::set< CRDFTriplet >::const_iterator it = mpGraph->getTriplets().begin();
  std::set< CRDFTriplet >::const_iterator end = mpGraph->getTriplets().end();

  for (; it != end; ++it)
    {
      CQRDFTreeViewItem * pSubjectItem = find(it->pSubject);

      if (pSubjectItem == NULL)
        {
          pSubjectItem = new CQRDFTreeViewItem(mpTreeWidget, NULL);
          insert(it->pSubject, pSubjectItem);
          // Display the subject information

          const CRDFSubject & Subject = it->pSubject->getSubject();

          switch (Subject.getType())
            {
              case CRDFSubject::RESOURCE:
                pSubjectItem->setText(COL_SUBJECT, FROM_UTF8(Subject.getResource()));
                break;

              case CRDFSubject::BLANK_NODE:
                pSubjectItem->setText(COL_SUBJECT, FROM_UTF8(Subject.getBlankNodeID()));
                break;
            }
        }

      CQRDFTreeViewItem * pObjectItem = NULL;

      if (it->Predicate.getURI() == "http://www.w3.org/1999/02/22-rdf-syntax-ns#subject")
        {
          pObjectItem = new CQRDFTreeViewItem(pSubjectItem, NULL);
          insert(it->pObject, pObjectItem);
        }
      else
        pObjectItem = find(it->pObject);

      if (pObjectItem == NULL)
        {
          pObjectItem = new CQRDFTreeViewItem(pSubjectItem, NULL);
          insert(it->pObject, pObjectItem);
        }
      else
        {
          QTreeWidgetItem * pParent = pObjectItem->parent();

          if (pParent == NULL)
            {
              mpTreeWidget->invisibleRootItem()->removeChild(pObjectItem);
              pSubjectItem->addChild(pObjectItem);
            }
          else
            {
              pParent->removeChild(pObjectItem);
              pSubjectItem->addChild(pObjectItem);
            }
        }

      pObjectItem->setTriplet(*it);
    }

  mpTreeWidget->setFocus();

  return true;
}

void CQRDFTreeView::clear()
{
  mNode2Item.clear();
  pdelete(mpGraph);
  mpTreeWidget->clear();
}

CQRDFTreeViewItem * CQRDFTreeView::find(const CRDFNode * pNode)
{
  std::map< const CRDFNode *, CQRDFTreeViewItem * >::iterator it = mNode2Item.find(pNode);

  if (it != mNode2Item.end())
    return it->second;

  return NULL;
}

void CQRDFTreeView::insert(const CRDFNode * pNode, CQRDFTreeViewItem * pItem)
{
  mNode2Item[pNode] = pItem;
}
<commit_msg>- issue 2456: found the focus stealing code<commit_after>// Copyright (C) 2010 - 2015 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

#include "CQRDFTreeView.h"
#include "CQRDFTreeViewItem.h"

#include "UI/CQMessageBox.h"
#include "UI/qtUtilities.h"

#include "MIRIAM/CRDFGraph.h"
#include "MIRIAM/CRDFParser.h"
// #include "MIRIAM/CRDFWriter.h"
#include "MIRIAM/CRDFSubject.h"

// #include "CopasiDataModel/CCopasiDataModel.h"
// #include "report/CKeyFactory.h"
// #include "model/CModel.h"
#include "model/CModelValue.h"
#include "model/CEvent.h"
#include "model/CReaction.h"
#include "function/CFunction.h"
// #include "utilities/CCopasiMessage.h"
#include "copasi/report/CCopasiRootContainer.h"

#define COL_SUBJECT    0
#define COL_PREDICATE  1
#define COL_OBJECT     2

CQRDFTreeView::CQRDFTreeView(QWidget* parent, const char* name) :
  CopasiWidget(parent, name),
  mNode2Item(),
  mpGraph(NULL)
{
  setupUi(this);
}

CQRDFTreeView::~CQRDFTreeView()
{
  clear();
}

bool CQRDFTreeView::update(ListViews::ObjectType /* objectType */,
                           ListViews::Action /* action */,
                           const std::string & /* key */)
{
  return true;
}

bool CQRDFTreeView::enterProtected()
{
  clear();

  CCopasiObject *pObject = dynamic_cast< CCopasiObject * >(CCopasiRootContainer::getKeyFactory()->get(mKey));

  if (pObject != NULL)
    {
      CModelEntity * pEntity = NULL;
      CEvent * pEvent = NULL;
      CReaction * pReaction = NULL;
      CFunction * pFunction = NULL;
      const std::string * pMiriamAnnotation = NULL;

      if ((pEntity = dynamic_cast< CModelEntity * >(pObject)) != NULL)
        pMiriamAnnotation = &pEntity->getMiriamAnnotation();
      else if ((pEvent = dynamic_cast< CEvent * >(pObject)) != NULL)
        pMiriamAnnotation = &pEvent->getMiriamAnnotation();
      else if ((pReaction = dynamic_cast< CReaction * >(pObject)) != NULL)
        pMiriamAnnotation = &pReaction->getMiriamAnnotation();
      else if ((pFunction = dynamic_cast< CFunction * >(pObject)) != NULL)
        pMiriamAnnotation = &pFunction->getMiriamAnnotation();

      if (pMiriamAnnotation && *pMiriamAnnotation != "")
        mpGraph = CRDFParser::graphFromXml(*pMiriamAnnotation);
    }

  CCopasiMessage::clearDeque();

  if (CCopasiMessage::size() != 0)
    {
      QString Message = FROM_UTF8(CCopasiMessage::getAllMessageText());
      CQMessageBox::warning(this, QString("RDF Warning"), Message,
                            QMessageBox::Ok, QMessageBox::Ok);
    }

  if (mpGraph == NULL)
    mpGraph = new CRDFGraph;

  // We make sure that we always have an about node.
  mpGraph->createAboutNode(mKey);

  // We iterate of all triplets
  std::set< CRDFTriplet >::const_iterator it = mpGraph->getTriplets().begin();
  std::set< CRDFTriplet >::const_iterator end = mpGraph->getTriplets().end();

  for (; it != end; ++it)
    {
      CQRDFTreeViewItem * pSubjectItem = find(it->pSubject);

      if (pSubjectItem == NULL)
        {
          pSubjectItem = new CQRDFTreeViewItem(mpTreeWidget, NULL);
          insert(it->pSubject, pSubjectItem);
          // Display the subject information

          const CRDFSubject & Subject = it->pSubject->getSubject();

          switch (Subject.getType())
            {
              case CRDFSubject::RESOURCE:
                pSubjectItem->setText(COL_SUBJECT, FROM_UTF8(Subject.getResource()));
                break;

              case CRDFSubject::BLANK_NODE:
                pSubjectItem->setText(COL_SUBJECT, FROM_UTF8(Subject.getBlankNodeID()));
                break;
            }
        }

      CQRDFTreeViewItem * pObjectItem = NULL;

      if (it->Predicate.getURI() == "http://www.w3.org/1999/02/22-rdf-syntax-ns#subject")
        {
          pObjectItem = new CQRDFTreeViewItem(pSubjectItem, NULL);
          insert(it->pObject, pObjectItem);
        }
      else
        pObjectItem = find(it->pObject);

      if (pObjectItem == NULL)
        {
          pObjectItem = new CQRDFTreeViewItem(pSubjectItem, NULL);
          insert(it->pObject, pObjectItem);
        }
      else
        {
          QTreeWidgetItem * pParent = pObjectItem->parent();

          if (pParent == NULL)
            {
              mpTreeWidget->invisibleRootItem()->removeChild(pObjectItem);
              pSubjectItem->addChild(pObjectItem);
            }
          else
            {
              pParent->removeChild(pObjectItem);
              pSubjectItem->addChild(pObjectItem);
            }
        }

      pObjectItem->setTriplet(*it);
    }

  //mpTreeWidget->setFocus();

  return true;
}

void CQRDFTreeView::clear()
{
  mNode2Item.clear();
  pdelete(mpGraph);
  mpTreeWidget->clear();
}

CQRDFTreeViewItem * CQRDFTreeView::find(const CRDFNode * pNode)
{
  std::map< const CRDFNode *, CQRDFTreeViewItem * >::iterator it = mNode2Item.find(pNode);

  if (it != mNode2Item.end())
    return it->second;

  return NULL;
}

void CQRDFTreeView::insert(const CRDFNode * pNode, CQRDFTreeViewItem * pItem)
{
  mNode2Item[pNode] = pItem;
}
<|endoftext|>


<commit_before>/// \file ROOT/TLogger.h
/// \ingroup Base ROOT7
/// \author Axel Naumann <axel@cern.ch>
/// \date 2015-03-29
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_TLog
#define ROOT7_TLog

#include <array>
#include <memory>
#include <sstream>
#include "RStringView.h"
#include <vector>

namespace ROOT {
namespace Experimental {

/**
 Kinds of diagnostics.
 */
enum class ELogLevel {
   kDebug,   ///< Debug information; only useful for developers
   kInfo,    ///< Informational messages; used for instance for tracing
   kWarning, ///< Warnings about likely unexpected behavior
   kError,
   kFatal
};

class TLogEntry;

/**
 Abstract TLogHandler base class. ROOT logs everything from info to error
 to entities of this class.
 */
class TLogHandler {
public:
   virtual ~TLogHandler();
   // Returns false if further emission of this Log should be suppressed.
   virtual bool Emit(const TLogEntry &entry) = 0;
};

class TLogManager: public TLogHandler {
private:
   std::vector<std::unique_ptr<TLogHandler>> fHandlers;

   /// Initialize taking a TLogHandlerDefault.
   TLogManager(std::unique_ptr<TLogHandler> &&lh) { fHandlers.emplace_back(std::move(lh)); }

public:
   static TLogManager &Get();

   /// Add a TLogHandler in the front - to be called before all others.
   void PushFront(std::unique_ptr<TLogHandler> handler) { fHandlers.insert(fHandlers.begin(), std::move(handler)); }

   /// Add a TLogHandler in the back - to be called after all others.
   void PushBack(std::unique_ptr<TLogHandler> handler) { fHandlers.emplace_back(std::move(handler)); }

   // Emit a `TLogEntry` to the TLogHandlers.
   // Returns false if further emission of this Log should be suppressed.
   bool Emit(const TLogEntry &entry) override
   {
      for (auto &&handler: fHandlers)
         if (!handler->Emit(entry))
            return false;
      return true;
   }
};

class TLogEntry: public std::ostringstream {
public:
   std::string fGroup;
   std::string fFile;
   std::string fFuncName;
   int fLine = 0;
   ELogLevel fLevel;

public:
   TLogEntry() = default;
   TLogEntry(ELogLevel level, std::string_view group): fGroup(group), fLevel(level) {}
   TLogEntry(ELogLevel level, std::string_view group, std::string_view filename, int line, std::string_view funcname)
      : fGroup(group), fFile(filename), fFuncName(funcname), fLine(line), fLevel(level)
   {}

   TLogEntry &SetFile(const std::string &file)
   {
      fFile = file;
      return *this;
   }
   TLogEntry &SetFunction(const std::string &func)
   {
      fFuncName = func;
      return *this;
   }
   TLogEntry &SetLine(int line)
   {
      fLine = line;
      return *this;
   }

   ~TLogEntry() { TLogManager::Get().Emit(*this); }
};

} // namespace Experimental
} // namespace ROOT

#if defined(_MSC_VER)
#define LOG_PRETTY_FUNCTION __FUNCSIG__
#elif defined(__GNUC__) || defined(__clang__)
#define LOG_PRETTY_FUNCTION __PRETTY_FUNCTION__
#else
#define LOG_PRETTY_FUNCTION __func__
#endif

#define R__LOG_HERE(LEVEL, GROUP) \
   ROOT::Experimental::TLogEntry(LEVEL, GROUP).SetFile(__FILE__).SetLine(__LINE__).SetFunction(__PRETTY_FUNCTION__)

#define R__FATAL_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kFatal, GROUP)
#define R__ERROR_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kError, GROUP)
#define R__WARNING_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kWarning, GROUP)
#define R__INFO_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kInfo, GROUP)
#define R__DEBUG_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kDebug, GROUP)

#endif
<commit_msg>Add forgotten variable<commit_after>/// \file ROOT/TLogger.h
/// \ingroup Base ROOT7
/// \author Axel Naumann <axel@cern.ch>
/// \date 2015-03-29
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_TLog
#define ROOT7_TLog

#include <array>
#include <memory>
#include <sstream>
#include "RStringView.h"
#include <vector>

namespace ROOT {
namespace Experimental {

/**
 Kinds of diagnostics.
 */
enum class ELogLevel {
   kDebug,   ///< Debug information; only useful for developers
   kInfo,    ///< Informational messages; used for instance for tracing
   kWarning, ///< Warnings about likely unexpected behavior
   kError,
   kFatal
};

class TLogEntry;

/**
 Abstract TLogHandler base class. ROOT logs everything from info to error
 to entities of this class.
 */
class TLogHandler {
public:
   virtual ~TLogHandler();
   // Returns false if further emission of this Log should be suppressed.
   virtual bool Emit(const TLogEntry &entry) = 0;
};

class TLogManager: public TLogHandler {
private:
   std::vector<std::unique_ptr<TLogHandler>> fHandlers;

   /// Initialize taking a TLogHandlerDefault.
   TLogManager(std::unique_ptr<TLogHandler> &&lh) { fHandlers.emplace_back(std::move(lh)); }

public:
   static TLogManager &Get();

   /// Add a TLogHandler in the front - to be called before all others.
   void PushFront(std::unique_ptr<TLogHandler> handler) { fHandlers.insert(fHandlers.begin(), std::move(handler)); }

   /// Add a TLogHandler in the back - to be called after all others.
   void PushBack(std::unique_ptr<TLogHandler> handler) { fHandlers.emplace_back(std::move(handler)); }

   // Emit a `TLogEntry` to the TLogHandlers.
   // Returns false if further emission of this Log should be suppressed.
   bool Emit(const TLogEntry &entry) override
   {
      for (auto &&handler: fHandlers)
         if (!handler->Emit(entry))
            return false;
      return true;
   }
};

class TLogEntry: public std::ostringstream {
public:
   std::string fGroup;
   std::string fFile;
   std::string fFuncName;
   int fLine = 0;
   ELogLevel fLevel;

public:
   TLogEntry() = default;
   TLogEntry(ELogLevel level, std::string_view group): fGroup(group), fLevel(level) {}
   TLogEntry(ELogLevel level, std::string_view group, std::string_view filename, int line, std::string_view funcname)
      : fGroup(group), fFile(filename), fFuncName(funcname), fLine(line), fLevel(level)
   {}

   TLogEntry &SetFile(const std::string &file)
   {
      fFile = file;
      return *this;
   }
   TLogEntry &SetFunction(const std::string &func)
   {
      fFuncName = func;
      return *this;
   }
   TLogEntry &SetLine(int line)
   {
      fLine = line;
      return *this;
   }

   ~TLogEntry() { TLogManager::Get().Emit(*this); }
};

} // namespace Experimental
} // namespace ROOT

#if defined(_MSC_VER)
#define LOG_PRETTY_FUNCTION __FUNCSIG__
#elif defined(__GNUC__) || defined(__clang__)
#define LOG_PRETTY_FUNCTION __PRETTY_FUNCTION__
#else
#define LOG_PRETTY_FUNCTION __func__
#endif

#define R__LOG_HERE(LEVEL, GROUP) \
   ROOT::Experimental::TLogEntry(LEVEL, GROUP).SetFile(__FILE__).SetLine(__LINE__).SetFunction(LOG_PRETTY_FUNCTION)

#define R__FATAL_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kFatal, GROUP)
#define R__ERROR_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kError, GROUP)
#define R__WARNING_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kWarning, GROUP)
#define R__INFO_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kInfo, GROUP)
#define R__DEBUG_HERE(GROUP) R__LOG_HERE(ROOT::Experimental::ELogLevel::kDebug, GROUP)

#endif
<|endoftext|>