<commit_before>#include "stdafx.h"
#include "exceptiondispatcher.h"

void RaiseILGLAccessViolation(BYTE* ptr, BYTE save, BOOLEAN on)
{
	DWORD OldProtect;
	switch (on)
	{
	case FALSE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = save;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	case TRUE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = 0xFF;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	}
}

void RaisePageAccessViolation(BYTE* ptr, DWORD save, BOOLEAN on)
{
	DWORD OldProtect;
	switch (on)
	{
	case FALSE:
		VirtualProtect(ptr, 1, save, &OldProtect);
		return;
	case TRUE:
		VirtualProtect(ptr, 1, PAGE_READONLY, &OldProtect);
		return;
	}
}

void RaiseBreakpointException(BYTE* ptr, BYTE save, BOOLEAN on)
{
	DWORD OldProtect;
	switch (on)
	{
	case FALSE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = save;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	case TRUE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = 0xCC;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	}
}

void RaisePrivilegedCodeException(BYTE* ptr, BYTE save, BOOLEAN on)
{
	DWORD OldProtect;
	switch (on)
	{
	case FALSE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = save;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	case TRUE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = 0xF4;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	}
}

PVOID HandleException(PoolSect segment, const char* ModuleName)
{
	switch (segment.ExceptionCode)
	{
	case STATUS_ACCESS_VIOLATION:
		RaiseILGLAccessViolation((BYTE*)segment.ExceptionAddress, segment.SaveCode, FALSE);
		if (segment.UseModule)
			return (PVOID)((DWORD)GetModuleHandleA(ModuleName) + segment.ExceptionOffset);
		return (PVOID)segment.ExceptionAddress;
	case STATUS_BREAKPOINT:
		RaiseBreakpointException((BYTE*)segment.ExceptionAddress, segment.SaveCode, FALSE);
		if (segment.UseModule)
			return (PVOID)((DWORD)GetModuleHandleA(ModuleName) + segment.ExceptionOffset);
		return (PVOID)segment.ExceptionAddress;
	case STATUS_PRIVILEGED_INSTRUCTION:
		RaisePrivilegedCodeException((BYTE*)segment.ExceptionAddress, segment.SaveCode, FALSE);
		if (segment.UseModule)
			return (PVOID)((DWORD)GetModuleHandleA(ModuleName) + segment.ExceptionOffset);
		return (PVOID)segment.ExceptionAddress;
	}
	return NULL;
}

size_t CheckSector(PoolSect sector[], size_t size)
{
	for (size_t iterator = 0; iterator < size; iterator++)
	{
		if (sector[iterator].Used == FALSE)
			return iterator;
	}
	return (size + 1);
}

size_t SearchSector(PoolSect sector[], size_t size, DWORD address)
{
	for (size_t iterator = 0; iterator < size; iterator++)
	{
		if (sector[iterator].Used == TRUE && sector[iterator].IsAEHPresent == FALSE
			&& sector[iterator].ExceptionAddress == address)
			return iterator;
	}
	return (size + 1);
}

void UnlockSector(PoolSect sector[], size_t index)
{
	sector[index].IsAEHPresent = FALSE;
	sector[index].Used = FALSE;
	sector[index].ExceptionAddress = NULL;
}

void LockSector(PoolSect sector[], size_t index)
{
	sector[index].Used = TRUE;
	sector[index].IsAEHPresent = FALSE;
}

DWORD SwapAccess(DWORD AccessException, DWORD Test)
{
	MEMORY_BASIC_INFORMATION Query;
	VirtualQuery((LPCVOID)Test, &Query, sizeof(Query));

	if (AccessException >= (DWORD)Query.BaseAddress && AccessException <= ((DWORD)Query.BaseAddress + Query.RegionSize))
	{
		DWORD OldProtect;
		void* SwapMemory = calloc(1, 32);
		VirtualProtect((LPVOID)AccessException, 1, PAGE_READONLY, &OldProtect);
		memcpy(SwapMemory, (void*)AccessException, 32);
		VirtualProtect((LPVOID)AccessException, 1, OldProtect, &OldProtect);
		return (DWORD)SwapMemory;
	}
	else
		return NULL;
}

void AddException(PoolSect sector[], size_t index, BOOLEAN Type, DWORD ExceptionAddress)
{
	sector[index].ExceptionAddress = ExceptionAddress;
	sector[index].SaveCode = *(DWORD*)ExceptionAddress;
	sector[index].ExceptionType = Type;
	sector[index].Index = index;
	LockSector(sector, index);

	switch (Type)
	{
	case 0:
		RaisePrivilegedCodeException((BYTE*)sector[index].ExceptionAddress, 0, TRUE);
		return;
	case 1:
		RaisePageAccessViolation((BYTE*)sector[index].ExceptionAddress, 0, TRUE);
		return;
	}

}
<commit_msg>Update exceptiondispatcher.cpp<commit_after>// Programmed by jasonfish4
#include "stdafx.h"
#include "exceptiondispatcher.h"

void Dispatcher::RaiseILGLAccessViolation(BYTE* ptr, BYTE save, BOOLEAN on)
{
	DWORD OldProtect;
	switch (on)
	{
	case FALSE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = save;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	case TRUE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = 0xFF;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	}
}

void Dispatcher::RaisePageAccessViolation(BYTE* ptr, DWORD save, BOOLEAN on)
{
	DWORD OldProtect;
	switch (on)
	{
	case FALSE:
		VirtualProtect(ptr, 1, save, &OldProtect);
		return;
	case TRUE:
		VirtualProtect(ptr, 1, PAGE_READONLY, &OldProtect);
		return;
	}
}

void Dispatcher::RaiseBreakpointException(BYTE* ptr, BYTE save, BOOLEAN on)
{
	DWORD OldProtect;
	switch (on)
	{
	case FALSE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = save;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	case TRUE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = 0xCC;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	}
}

void Dispatcher::RaisePrivilegedCodeException(BYTE* ptr, BYTE save, BOOLEAN on)
{
	DWORD OldProtect;
	switch (on)
	{
	case FALSE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = save;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	case TRUE:
		VirtualProtect(ptr, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
		*(BYTE*)ptr = 0xF4;
		VirtualProtect(ptr, 1, OldProtect, &OldProtect);
		return;
	}
}

PVOID Dispatcher::HandleException(Dispatcher::PoolSect segment, const char* ModuleName)
{
	switch (segment.ExceptionCode)
	{
	case STATUS_ACCESS_VIOLATION:
		Dispatcher::RaiseILGLAccessViolation((BYTE*)segment.ExceptionAddress, segment.SaveCode, FALSE);
		if (segment.UseModule)
			return (PVOID)((DWORD)GetModuleHandleA(ModuleName) + segment.ExceptionOffset);
		return (PVOID)segment.ExceptionAddress;
	case STATUS_BREAKPOINT:
		Dispatcher::RaiseBreakpointException((BYTE*)segment.ExceptionAddress, segment.SaveCode, FALSE);
		if (segment.UseModule)
			return (PVOID)((DWORD)GetModuleHandleA(ModuleName) + segment.ExceptionOffset);
		return (PVOID)segment.ExceptionAddress;
	case STATUS_PRIVILEGED_INSTRUCTION:
		Dispatcher::RaisePrivilegedCodeException((BYTE*)segment.ExceptionAddress, segment.SaveCode, FALSE);
		if (segment.UseModule)
			return (PVOID)((DWORD)GetModuleHandleA(ModuleName) + segment.ExceptionOffset);
		return (PVOID)segment.ExceptionAddress;
	}
	return NULL;
}

size_t Dispatcher::CheckSector(Dispatcher::PoolSect sector[], size_t size)
{
	for (size_t iterator = 0; iterator < size; iterator++)
	{
		if (sector[iterator].Used == FALSE)
			return iterator;
	}
	return (size + 1);
}

size_t Dispatcher::SearchSector(Dispatcher::PoolSect sector[], size_t size, DWORD address)
{
	for (size_t iterator = 0; iterator < size; iterator++)
	{
		if (sector[iterator].Used == TRUE && sector[iterator].IsAEHPresent == FALSE
			&& sector[iterator].ExceptionAddress == address)
			return iterator;
	}
	return (size + 1);
}

void Dispatcher::UnlockSector(Dispatcher::PoolSect sector[], size_t index)
{
	sector[index].IsAEHPresent = FALSE;
	sector[index].Used = FALSE;
	sector[index].ExceptionAddress = NULL;
}

void Dispatcher::LockSector(Dispatcher::PoolSect sector[], size_t index)
{
	sector[index].Used = TRUE;
	sector[index].IsAEHPresent = FALSE;
}

DWORD Dispatcher::SwapAccess(DWORD AccessException, DWORD Test)
{
	MEMORY_BASIC_INFORMATION Query;
	VirtualQuery((LPCVOID)Test, &Query, sizeof(Query));

	if (AccessException >= (DWORD)Query.BaseAddress && AccessException <= ((DWORD)Query.BaseAddress + Query.RegionSize))
	{
		DWORD OldProtect;
		void* SwapMemory = calloc(1, 32);
		VirtualProtect((LPVOID)AccessException, 1, PAGE_READONLY, &OldProtect);
		memcpy(SwapMemory, (void*)AccessException, 32);
		VirtualProtect((LPVOID)AccessException, 1, OldProtect, &OldProtect);
		return (DWORD)SwapMemory;
	}
	else
		return NULL;
}

void Dispatcher::AddException(Dispatcher::PoolSect sector[], size_t index, BOOLEAN Type, DWORD ExceptionAddress)
{
	sector[index].ExceptionAddress = ExceptionAddress;
	sector[index].SaveCode = *(DWORD*)ExceptionAddress;
	sector[index].ExceptionType = Type;
	sector[index].Index = index;
	Dispatcher::LockSector(sector, index);

	switch (Type)
	{
	case 0:
		Dispatcher::RaisePrivilegedCodeException((BYTE*)sector[index].ExceptionAddress, 0, TRUE);
		return;
	case 1:
		Dispatcher::RaisePageAccessViolation((BYTE*)sector[index].ExceptionAddress, 0, TRUE);
		return;
	}

}
<|endoftext|>


<commit_before>#ifndef COMPONENTREGISTRY_HPP
#define COMPONENTREGISTRY_HPP

#include <unordered_map>

#include "Component.hpp"
#include "Components/Drawable.hpp"
#include "Components/Movable.hpp"
#include "Components/Physical.hpp"

namespace swift
{
	class ComponentRegistry
	{
		public:
			static Component* get(const std::string& c)
			{
				if(c == "Drawable")
					return new Drawable;
				else if(c == "Movable")
					return new Movable;
				else if(c == "Physical")
					return new Physical;
				else
					return nullptr;
			}
	};
}

#endif // COMPONENTREGISTRY_HPP
<commit_msg>Removed unneeded header (unordered_map)<commit_after>#ifndef COMPONENTREGISTRY_HPP
#define COMPONENTREGISTRY_HPP

#include "Component.hpp"
#include "Components/Drawable.hpp"
#include "Components/Movable.hpp"
#include "Components/Physical.hpp"

namespace swift
{
	class ComponentRegistry
	{
		public:
			static Component* get(const std::string& c)
			{
				if(c == "Drawable")
					return new Drawable;
				else if(c == "Movable")
					return new Movable;
				else if(c == "Physical")
					return new Physical;
				else
					return nullptr;
			}
	};
}

#endif // COMPONENTREGISTRY_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (c) [2014-2015] Novell, Inc.
 * Copyright (c) 2016 SUSE LLC
 *
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as published
 * by the Free Software Foundation.
 *
 * 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, contact Novell, Inc.
 *
 * To contact Novell about this file by physical or electronic mail, you may
 * find current contact information at www.novell.com.
 */

#include <boost/graph/copy.hpp>
#include <boost/graph/topological_sort.hpp>
#include <boost/graph/transitive_reduction.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/graphviz.hpp>

#include "config.h"
#include "storage/Devices/DeviceImpl.h"
#include "storage/Devices/BlkDevice.h"
#include "storage/Filesystems/FilesystemImpl.h"
#include "storage/Devicegraph.h"
#include "storage/Utils/GraphUtils.h"
#include "storage/Action.h"
#include "storage/Actiongraph.h"
#include "storage/Storage.h"
#include "storage/Utils/StorageTmpl.h"

namespace storage
{

    Actiongraph::Impl::Impl(const Storage& storage, const Devicegraph* lhs, const Devicegraph* rhs)
	: storage(storage), lhs(lhs), rhs(rhs)
    {
	cout << "lhs graph" << endl
	     << *lhs << endl;
	lhs->check();

	cout << "rhs graph" << endl
	     << *rhs << endl;
	rhs->check();

	get_actions();
	set_special_actions();
	add_dependencies();
	remove_only_syncs();

	cout << "action graph" << endl;
	print_graph();

	calculate_order();
    }

    bool
    Actiongraph::Impl::empty() const
    {
	return boost::num_vertices(graph) == 0;
    }

    size_t
    Actiongraph::Impl::num_actions() const
    {
	return boost::num_vertices(graph);
    }

    Actiongraph::Impl::vertex_descriptor
    Actiongraph::Impl::add_vertex(Action::Base* action)
    {
	return boost::add_vertex(shared_ptr<Action::Base>(action), graph);
    }

    Actiongraph::Impl::edge_descriptor
    Actiongraph::Impl::add_edge(vertex_descriptor a, vertex_descriptor b)
    {
	pair<edge_descriptor, bool> tmp = boost::add_edge(a, b, graph);

	return tmp.first;
    }

    void
    Actiongraph::Impl::add_chain(const vector<Action::Base*>& actions)
    {
	vertex_descriptor v1 = 0;

	for (vector<Action::Base*>::const_iterator it = actions.begin(); it != actions.end(); ++it)
	{
	    (*it)->first = it == actions.begin();
	    (*it)->last = it == --actions.end();

	    vertex_descriptor v2 = add_vertex(*it);

	    if (it != actions.begin())
		add_edge(v1, v2);

	    v1 = v2;
	}
    }

    void
    Actiongraph::Impl::add_chain(const vector<vertex_descriptor>& actions)
    {
	if (actions.size() > 1)
	{
	    Actiongraph::Impl::vertex_descriptor vertex = actions[0];
	    for (size_t i = 1; i < actions.size(); ++i)
	    {
		add_edge(vertex, actions[i]);
		vertex = actions[i];
	    }
	}
    }

    vector<Actiongraph::Impl::vertex_descriptor>
    Actiongraph::Impl::actions_with_sid(sid_t sid, ActionsFilter actions_filter) const
    {
	vector<vertex_descriptor> ret;

	for (vertex_descriptor tmp : vertices())
	{
	    if (graph[tmp]->sid == sid)
	    {
		if (actions_filter == ONLY_FIRST && !graph[tmp]->first)
		    continue;

		if (actions_filter == ONLY_LAST && !graph[tmp]->last)
		    continue;

		ret.push_back(tmp);
	    }
	}

	return ret;
    }

    boost::iterator_range<Actiongraph::Impl::vertex_iterator>
    Actiongraph::Impl::vertices() const
    {
	return boost::make_iterator_range(boost::vertices(graph));
    }

    boost::iterator_range<Actiongraph::Impl::adjacency_iterator>
    Actiongraph::Impl::children(vertex_descriptor vertex) const
    {
	return boost::make_iterator_range(boost::adjacent_vertices(vertex, graph));
    }

    boost::iterator_range<Actiongraph::Impl::inv_adjacency_iterator>
    Actiongraph::Impl::parents(vertex_descriptor vertex) const
    {
	return boost::make_iterator_range(boost::inv_adjacent_vertices(vertex, graph));
    }

    void
    Actiongraph::Impl::get_actions()
    {
	const set<sid_t> lhs_sids = lhs->get_impl().get_device_sids();
	const set<sid_t> rhs_sids = rhs->get_impl().get_device_sids();

	vector<sid_t> created_sids;
	set_difference(rhs_sids.begin(), rhs_sids.end(), lhs_sids.begin(), lhs_sids.end(),
		       back_inserter(created_sids));

	vector<sid_t> common_sids;
	set_intersection(lhs_sids.begin(), lhs_sids.end(), rhs_sids.begin(), rhs_sids.end(),
			 back_inserter(common_sids));

	vector<sid_t> deleted_sids;
	set_difference(lhs_sids.begin(), lhs_sids.end(), rhs_sids.begin(), rhs_sids.end(),
		       back_inserter(deleted_sids));

	for (sid_t sid : created_sids)
	{
	    Devicegraph::Impl::vertex_descriptor v_rhs = rhs->get_impl().find_vertex(sid);
	    const Device* d_rhs = rhs->get_impl()[v_rhs];

	    d_rhs->get_impl().add_create_actions(*this);
	}

	for (sid_t sid : common_sids)
	{
	    Devicegraph::Impl::vertex_descriptor v_lhs = lhs->get_impl().find_vertex(sid);
	    const Device* d_lhs = lhs->get_impl()[v_lhs];

	    Devicegraph::Impl::vertex_descriptor v_rhs = rhs->get_impl().find_vertex(sid);
	    const Device* d_rhs = rhs->get_impl()[v_rhs];

	    d_rhs->get_impl().add_modify_actions(*this, d_lhs);
	}

	for (sid_t sid : deleted_sids)
	{
	    Devicegraph::Impl::vertex_descriptor v_lhs = lhs->get_impl().find_vertex(sid);
	    const Device* d_lhs = lhs->get_impl()[v_lhs];

	    d_lhs->get_impl().add_delete_actions(*this);
	}
    }

    void
    Actiongraph::Impl::set_special_actions()
    {
	boost::iterator_range<vertex_iterator> range = vertices();

	mount_root_filesystem = range.end();

	for (vertex_iterator it = range.begin(); it != range.end(); ++it)
	{
	    const Action::Base* action = graph[*it].get();

	    const Action::Mount* mount = dynamic_cast<const Action::Mount*>(action);
	    if (mount && mount->mountpoint == "/")
		mount_root_filesystem = it;
	}
    }

    void
    Actiongraph::Impl::add_dependencies()
    {
	vector<vertex_descriptor> mounts;

	for (vertex_descriptor v : vertices())
	{
	    graph[v]->add_dependencies(v, *this);

	    const Action::Mount* mount = dynamic_cast<const Action::Mount*>(graph[v].get());
	    if (mount && mount->mountpoint != "swap")
		mounts.push_back(v);
	}

	if (mounts.size() > 1)
	{
	    // TODO correct sort
	    sort(mounts.begin(), mounts.end(), [this, &mounts](vertex_descriptor l, vertex_descriptor r) {
		const Action::Mount* ml = dynamic_cast<const Action::Mount*>(graph[l].get());
		const Action::Mount* mr = dynamic_cast<const Action::Mount*>(graph[r].get());
		return ml->mountpoint <= mr->mountpoint;
	    });

	    add_chain(mounts);
	}
    }

    void
    Actiongraph::Impl::remove_only_syncs()
    {
	// TODO vertices are invalidated my remove_vertex, use listS?

	// TODO code below only works with vecS and is maybe not so clean

	for (size_t vertex = 0; vertex < num_actions(); ++vertex)
	{
	    if (!(*this)[vertex]->only_sync)
		continue;

	    for (vertex_descriptor parent : parents(vertex))
		for (vertex_descriptor child : children(vertex))
		    add_edge(parent, child);

	    clear_vertex(vertex, graph);
	    remove_vertex(vertex--, graph);
	}
    }

    void
    Actiongraph::Impl::calculate_order()
    {
	try
	{
	    boost::topological_sort(graph, front_inserter(order));
	}
	catch (const boost::not_a_dag&)
	{
	    cerr << "action graph not a DAG" << endl;
	}

	cout << "order" << endl;

	for (const vertex_descriptor& vertex : order)
	{
	    const Action::Base* action = graph[vertex].get();
	    cout << vertex << " " << action->text(*this, Tense::SIMPLE_PRESENT).native << endl;
	}

	cout << endl;
    }

    vector<const Action::Base*>
    Actiongraph::Impl::get_commit_actions() const
    {
	vector<const Action::Base*> commit_actions;

	for (const vertex_descriptor& vertex : order)
	{
	    const Action::Base* action = graph[vertex].get();

	    commit_actions.push_back(action);
	}

	return commit_actions;
    }

    void
    Actiongraph::Impl::commit(const CommitCallbacks* commit_callbacks) const
    {
	for (const vertex_descriptor& vertex : order)
	{
	    const Action::Base* action = graph[vertex].get();

	    string text = action->text(*this, Tense::PRESENT_CONTINUOUS).text;

	    y2mil("Commit Action " << text);
	    cout << text << endl;

	    if (commit_callbacks)
	    {
		commit_callbacks->message(text);
		commit_callbacks->pre(action);
	    }

	    try
	    {
		action->commit(*this);
	    }
	    catch (const Exception& e)
	    {
		ST_CAUGHT(e);

		if (!commit_callbacks || !commit_callbacks->error(text, e.what()))
		    ST_RETHROW(e);

		y2mil("user decides to continue after error");
	    }

	    if (commit_callbacks)
	    {
		commit_callbacks->post(action);
	    }
	}
    }

    void
    Actiongraph::Impl::print_graph() const
    {
	typedef map<vertex_descriptor, string> vertex_name_map_t;
	vertex_name_map_t vertex_name_map;
	boost::associative_property_map<vertex_name_map_t> my_vertex_name_map(vertex_name_map);

	for (vertex_descriptor v : vertices())
	{
	    int i = v;
	    string text = graph[v]->text(*this, Tense::SIMPLE_PRESENT).text;

	    ostringstream tmp;
	    tmp << i << " [ " << text << " ]";

	    boost::put(my_vertex_name_map, v, tmp.str());
	}

	boost::print_graph(graph, my_vertex_name_map);

	cout << endl;
    }

    namespace
    {

	struct write_graph
	{
	    write_graph(const Actiongraph::Impl&) {}

	    void operator()(ostream& out) const
	    {
		out << "node [ shape=rectangle, style=filled, fontname=\"Arial\" ];" << endl;
	    }
	};

	struct write_vertex
	{
	    write_vertex(const Actiongraph::Impl& actiongraph, GraphvizFlags graphviz_flags)
		: actiongraph(actiongraph), graphviz_flags(graphviz_flags) {}

	    const Actiongraph::Impl& actiongraph;
	    const GraphvizFlags graphviz_flags;

	    void operator()(ostream& out, const Actiongraph::Impl::vertex_descriptor& vertex) const
	    {
		const Action::Base* action = actiongraph[vertex];

		string label = action->text(actiongraph, Tense::SIMPLE_PRESENT).text;
		string tooltip = action->text(actiongraph, Tense::SIMPLE_PRESENT).text;

		string& extra = (graphviz_flags && GraphvizFlags::TOOLTIP) ? tooltip : label;

		if (graphviz_flags && GraphvizFlags::SID)
		{
		    extra += "\\n" "sid:" + to_string(action->sid);

		    extra += " [";
		    if (action->first)
			extra += "f";
		    if (action->last)
			extra += "l";
		    if (action->only_sync)
			extra += "s";
		    extra += "]";
		}

		out << "[ label=" << boost::escape_dot_string(label);

		if (is_create(action))
		    out << ", color=\"#00ff00\", fillcolor=\"#ccffcc\"";
		else if (is_modify(action))
		    out << ", color=\"#0000ff\", fillcolor=\"#ccccff\"";
		else if (is_delete(action))
		    out << ", color=\"#ff0000\", fillcolor=\"#ffcccc\"";
		else
		    ST_THROW(LogicException("unknown Action::Base subclass"));

		if (graphviz_flags && GraphvizFlags::TOOLTIP)
		{
		    out << ", tooltip=" << boost::escape_dot_string(tooltip);
		}

		out << " ]";
	    }
	};

    }

    void
    Actiongraph::Impl::write_graphviz(const string& filename, GraphvizFlags graphviz_flags) const
    {
	ofstream fout(filename);

	fout << "// generated by libstorage-ng version " VERSION << endl;
	fout << endl;

	boost::write_graphviz(fout, graph, write_vertex(*this, graphviz_flags),
			      boost::default_writer(), write_graph(*this));

	fout.close();
    }

}
<commit_msg>- renamed variable<commit_after>/*
 * Copyright (c) [2014-2015] Novell, Inc.
 * Copyright (c) 2016 SUSE LLC
 *
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as published
 * by the Free Software Foundation.
 *
 * 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, contact Novell, Inc.
 *
 * To contact Novell about this file by physical or electronic mail, you may
 * find current contact information at www.novell.com.
 */

#include <boost/graph/copy.hpp>
#include <boost/graph/topological_sort.hpp>
#include <boost/graph/transitive_reduction.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/graphviz.hpp>

#include "config.h"
#include "storage/Devices/DeviceImpl.h"
#include "storage/Devices/BlkDevice.h"
#include "storage/Filesystems/FilesystemImpl.h"
#include "storage/Devicegraph.h"
#include "storage/Utils/GraphUtils.h"
#include "storage/Action.h"
#include "storage/Actiongraph.h"
#include "storage/Storage.h"
#include "storage/Utils/StorageTmpl.h"

namespace storage
{

    Actiongraph::Impl::Impl(const Storage& storage, const Devicegraph* lhs, const Devicegraph* rhs)
	: storage(storage), lhs(lhs), rhs(rhs)
    {
	cout << "lhs graph" << endl
	     << *lhs << endl;
	lhs->check();

	cout << "rhs graph" << endl
	     << *rhs << endl;
	rhs->check();

	get_actions();
	set_special_actions();
	add_dependencies();
	remove_only_syncs();

	cout << "action graph" << endl;
	print_graph();

	calculate_order();
    }

    bool
    Actiongraph::Impl::empty() const
    {
	return boost::num_vertices(graph) == 0;
    }

    size_t
    Actiongraph::Impl::num_actions() const
    {
	return boost::num_vertices(graph);
    }

    Actiongraph::Impl::vertex_descriptor
    Actiongraph::Impl::add_vertex(Action::Base* action)
    {
	return boost::add_vertex(shared_ptr<Action::Base>(action), graph);
    }

    Actiongraph::Impl::edge_descriptor
    Actiongraph::Impl::add_edge(vertex_descriptor a, vertex_descriptor b)
    {
	pair<edge_descriptor, bool> tmp = boost::add_edge(a, b, graph);

	return tmp.first;
    }

    void
    Actiongraph::Impl::add_chain(const vector<Action::Base*>& actions)
    {
	vertex_descriptor v1 = 0;

	for (vector<Action::Base*>::const_iterator it = actions.begin(); it != actions.end(); ++it)
	{
	    (*it)->first = it == actions.begin();
	    (*it)->last = it == --actions.end();

	    vertex_descriptor v2 = add_vertex(*it);

	    if (it != actions.begin())
		add_edge(v1, v2);

	    v1 = v2;
	}
    }

    void
    Actiongraph::Impl::add_chain(const vector<vertex_descriptor>& actions)
    {
	if (actions.size() > 1)
	{
	    Actiongraph::Impl::vertex_descriptor vertex = actions[0];
	    for (size_t i = 1; i < actions.size(); ++i)
	    {
		add_edge(vertex, actions[i]);
		vertex = actions[i];
	    }
	}
    }

    vector<Actiongraph::Impl::vertex_descriptor>
    Actiongraph::Impl::actions_with_sid(sid_t sid, ActionsFilter actions_filter) const
    {
	vector<vertex_descriptor> ret;

	for (vertex_descriptor tmp : vertices())
	{
	    if (graph[tmp]->sid == sid)
	    {
		if (actions_filter == ONLY_FIRST && !graph[tmp]->first)
		    continue;

		if (actions_filter == ONLY_LAST && !graph[tmp]->last)
		    continue;

		ret.push_back(tmp);
	    }
	}

	return ret;
    }

    boost::iterator_range<Actiongraph::Impl::vertex_iterator>
    Actiongraph::Impl::vertices() const
    {
	return boost::make_iterator_range(boost::vertices(graph));
    }

    boost::iterator_range<Actiongraph::Impl::adjacency_iterator>
    Actiongraph::Impl::children(vertex_descriptor vertex) const
    {
	return boost::make_iterator_range(boost::adjacent_vertices(vertex, graph));
    }

    boost::iterator_range<Actiongraph::Impl::inv_adjacency_iterator>
    Actiongraph::Impl::parents(vertex_descriptor vertex) const
    {
	return boost::make_iterator_range(boost::inv_adjacent_vertices(vertex, graph));
    }

    void
    Actiongraph::Impl::get_actions()
    {
	const set<sid_t> lhs_sids = lhs->get_impl().get_device_sids();
	const set<sid_t> rhs_sids = rhs->get_impl().get_device_sids();

	vector<sid_t> created_sids;
	set_difference(rhs_sids.begin(), rhs_sids.end(), lhs_sids.begin(), lhs_sids.end(),
		       back_inserter(created_sids));

	vector<sid_t> common_sids;
	set_intersection(lhs_sids.begin(), lhs_sids.end(), rhs_sids.begin(), rhs_sids.end(),
			 back_inserter(common_sids));

	vector<sid_t> deleted_sids;
	set_difference(lhs_sids.begin(), lhs_sids.end(), rhs_sids.begin(), rhs_sids.end(),
		       back_inserter(deleted_sids));

	for (sid_t sid : created_sids)
	{
	    Devicegraph::Impl::vertex_descriptor v_rhs = rhs->get_impl().find_vertex(sid);
	    const Device* d_rhs = rhs->get_impl()[v_rhs];

	    d_rhs->get_impl().add_create_actions(*this);
	}

	for (sid_t sid : common_sids)
	{
	    Devicegraph::Impl::vertex_descriptor v_lhs = lhs->get_impl().find_vertex(sid);
	    const Device* d_lhs = lhs->get_impl()[v_lhs];

	    Devicegraph::Impl::vertex_descriptor v_rhs = rhs->get_impl().find_vertex(sid);
	    const Device* d_rhs = rhs->get_impl()[v_rhs];

	    d_rhs->get_impl().add_modify_actions(*this, d_lhs);
	}

	for (sid_t sid : deleted_sids)
	{
	    Devicegraph::Impl::vertex_descriptor v_lhs = lhs->get_impl().find_vertex(sid);
	    const Device* d_lhs = lhs->get_impl()[v_lhs];

	    d_lhs->get_impl().add_delete_actions(*this);
	}
    }

    void
    Actiongraph::Impl::set_special_actions()
    {
	boost::iterator_range<vertex_iterator> range = vertices();

	mount_root_filesystem = range.end();

	for (vertex_iterator it = range.begin(); it != range.end(); ++it)
	{
	    const Action::Base* action = graph[*it].get();

	    const Action::Mount* mount = dynamic_cast<const Action::Mount*>(action);
	    if (mount && mount->mountpoint == "/")
		mount_root_filesystem = it;
	}
    }

    void
    Actiongraph::Impl::add_dependencies()
    {
	vector<vertex_descriptor> mounts;

	for (vertex_descriptor vertex : vertices())
	{
	    graph[vertex]->add_dependencies(vertex, *this);

	    const Action::Mount* mount = dynamic_cast<const Action::Mount*>(graph[vertex].get());
	    if (mount && mount->mountpoint != "swap")
		mounts.push_back(vertex);
	}

	if (mounts.size() > 1)
	{
	    // TODO correct sort
	    sort(mounts.begin(), mounts.end(), [this, &mounts](vertex_descriptor l, vertex_descriptor r) {
		const Action::Mount* ml = dynamic_cast<const Action::Mount*>(graph[l].get());
		const Action::Mount* mr = dynamic_cast<const Action::Mount*>(graph[r].get());
		return ml->mountpoint <= mr->mountpoint;
	    });

	    add_chain(mounts);
	}
    }

    void
    Actiongraph::Impl::remove_only_syncs()
    {
	// TODO vertices are invalidated my remove_vertex, use listS?

	// TODO code below only works with vecS and is maybe not so clean

	for (size_t vertex = 0; vertex < num_actions(); ++vertex)
	{
	    if (!(*this)[vertex]->only_sync)
		continue;

	    for (vertex_descriptor parent : parents(vertex))
		for (vertex_descriptor child : children(vertex))
		    add_edge(parent, child);

	    clear_vertex(vertex, graph);
	    remove_vertex(vertex--, graph);
	}
    }

    void
    Actiongraph::Impl::calculate_order()
    {
	try
	{
	    boost::topological_sort(graph, front_inserter(order));
	}
	catch (const boost::not_a_dag&)
	{
	    cerr << "action graph not a DAG" << endl;
	}

	cout << "order" << endl;

	for (const vertex_descriptor& vertex : order)
	{
	    const Action::Base* action = graph[vertex].get();
	    cout << vertex << " " << action->text(*this, Tense::SIMPLE_PRESENT).native << endl;
	}

	cout << endl;
    }

    vector<const Action::Base*>
    Actiongraph::Impl::get_commit_actions() const
    {
	vector<const Action::Base*> commit_actions;

	for (const vertex_descriptor& vertex : order)
	{
	    const Action::Base* action = graph[vertex].get();

	    commit_actions.push_back(action);
	}

	return commit_actions;
    }

    void
    Actiongraph::Impl::commit(const CommitCallbacks* commit_callbacks) const
    {
	for (const vertex_descriptor& vertex : order)
	{
	    const Action::Base* action = graph[vertex].get();

	    string text = action->text(*this, Tense::PRESENT_CONTINUOUS).text;

	    y2mil("Commit Action " << text);
	    cout << text << endl;

	    if (commit_callbacks)
	    {
		commit_callbacks->message(text);
		commit_callbacks->pre(action);
	    }

	    try
	    {
		action->commit(*this);
	    }
	    catch (const Exception& e)
	    {
		ST_CAUGHT(e);

		if (!commit_callbacks || !commit_callbacks->error(text, e.what()))
		    ST_RETHROW(e);

		y2mil("user decides to continue after error");
	    }

	    if (commit_callbacks)
	    {
		commit_callbacks->post(action);
	    }
	}
    }

    void
    Actiongraph::Impl::print_graph() const
    {
	typedef map<vertex_descriptor, string> vertex_name_map_t;
	vertex_name_map_t vertex_name_map;
	boost::associative_property_map<vertex_name_map_t> my_vertex_name_map(vertex_name_map);

	for (vertex_descriptor v : vertices())
	{
	    int i = v;
	    string text = graph[v]->text(*this, Tense::SIMPLE_PRESENT).text;

	    ostringstream tmp;
	    tmp << i << " [ " << text << " ]";

	    boost::put(my_vertex_name_map, v, tmp.str());
	}

	boost::print_graph(graph, my_vertex_name_map);

	cout << endl;
    }

    namespace
    {

	struct write_graph
	{
	    write_graph(const Actiongraph::Impl&) {}

	    void operator()(ostream& out) const
	    {
		out << "node [ shape=rectangle, style=filled, fontname=\"Arial\" ];" << endl;
	    }
	};

	struct write_vertex
	{
	    write_vertex(const Actiongraph::Impl& actiongraph, GraphvizFlags graphviz_flags)
		: actiongraph(actiongraph), graphviz_flags(graphviz_flags) {}

	    const Actiongraph::Impl& actiongraph;
	    const GraphvizFlags graphviz_flags;

	    void operator()(ostream& out, const Actiongraph::Impl::vertex_descriptor& vertex) const
	    {
		const Action::Base* action = actiongraph[vertex];

		string label = action->text(actiongraph, Tense::SIMPLE_PRESENT).text;
		string tooltip = action->text(actiongraph, Tense::SIMPLE_PRESENT).text;

		string& extra = (graphviz_flags && GraphvizFlags::TOOLTIP) ? tooltip : label;

		if (graphviz_flags && GraphvizFlags::SID)
		{
		    extra += "\\n" "sid:" + to_string(action->sid);

		    extra += " [";
		    if (action->first)
			extra += "f";
		    if (action->last)
			extra += "l";
		    if (action->only_sync)
			extra += "s";
		    extra += "]";
		}

		out << "[ label=" << boost::escape_dot_string(label);

		if (is_create(action))
		    out << ", color=\"#00ff00\", fillcolor=\"#ccffcc\"";
		else if (is_modify(action))
		    out << ", color=\"#0000ff\", fillcolor=\"#ccccff\"";
		else if (is_delete(action))
		    out << ", color=\"#ff0000\", fillcolor=\"#ffcccc\"";
		else
		    ST_THROW(LogicException("unknown Action::Base subclass"));

		if (graphviz_flags && GraphvizFlags::TOOLTIP)
		{
		    out << ", tooltip=" << boost::escape_dot_string(tooltip);
		}

		out << " ]";
	    }
	};

    }

    void
    Actiongraph::Impl::write_graphviz(const string& filename, GraphvizFlags graphviz_flags) const
    {
	ofstream fout(filename);

	fout << "// generated by libstorage-ng version " VERSION << endl;
	fout << endl;

	boost::write_graphviz(fout, graph, write_vertex(*this, graphviz_flags),
			      boost::default_writer(), write_graph(*this));

	fout.close();
    }

}
<|endoftext|>


<commit_before>#ifndef SPARSEVECTOR_HPP_
#define SPARSEVECTOR_HPP_

#include "../DoubleVector.hpp"
#include <random>
#include <time.h>
#include <stdlib.h>
#include <map>

class DoubleVector;

class SparseVector: public DoubleVector{

private:
	std::map<int, double> _values;
	typedef std::map<int, double>::iterator values_iter;

public:

	SparseVector(): DoubleVector(DEFAULT_SIZE), _values(){};

	SparseVector(int size): DoubleVector(size), _values(){
		_size = size;
	};

	~SparseVector(){};

	void random();

	int size() const;

	double get(int index) const;

	void set(int index, double value);

	void scale(double alpha);

	void minus(const DoubleVector& x);

};

#endif
<commit_msg>SparseVector: Remove include random. Cause problems with compiler<commit_after>#ifndef SPARSEVECTOR_HPP_
#define SPARSEVECTOR_HPP_

#include "../DoubleVector.hpp"
#include <time.h>
#include <stdlib.h>
#include <map>

class DoubleVector;

class SparseVector: public DoubleVector{

private:
	std::map<int, double> _values;
	typedef std::map<int, double>::iterator values_iter;

public:

	SparseVector(): DoubleVector(DEFAULT_SIZE), _values(){};

	SparseVector(int size): DoubleVector(size), _values(){
		_size = size;
	};

	~SparseVector(){};

	void random();

	int size() const;

	double get(int index) const;

	void set(int index, double value);

	void scale(double alpha);

	void minus(const DoubleVector& x);

};

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>
#include <algorithm>
#include <sstream>
#include <vector>

struct SvoRow {
   std::string s;
   std::string v;
   std::string o;
   int n;
};

struct hashPair {
   template <class T1, class T2>
   std::size_t operator () (const std::pair<T1, T2> &p) const {
      auto value = 0x345678;
      auto h1 = std::hash<T1>{}(p.first);
      auto h2 = std::hash<T2>{}(p.second);
      value = (100003 * value) ^ h1;
      value = (100003 * value) ^ h2;
      return value;
   }
};

bool compareTuples(std::tuple<std::string, std::string, int> a,
                     std::tuple<std::string, std::string, int> b) {
   return std::get<2>(a) > std::get<2>(b);
}

int main(int argc, char** argv) {
   if (argc < 2) {
      std::cout << "Unspecified N value" << std::endl;
      return -1;
   }

   int n = std::stoi(argv[1]);
   SvoRow row;
   std::unordered_map<std::pair<std::string, std::string>, int, hashPair> pairs;
   std::vector<std::tuple<std::string, std::string, int> > ordered;
   std::string tempString;

   while (std::cin.peek() != std::char_traits<char>::eof()) {
      std::getline(std::cin, row.s, '\t');
      std::getline(std::cin, row.v, '\t');
      std::getline(std::cin, row.o, '\t');
      std::getline(std::cin, tempString);
      row.n = std::stoi(tempString);
      pairs[std::make_pair(row.s, row.o)] += row.n;
   }

   for (const auto &data : pairs) {
      ordered.push_back(std::make_tuple(data.first.first,
                                          data.first.second, data.second));
   }

   n = std::min(n, (int)ordered.size());

   std::partial_sort(ordered.begin(), ordered.begin() + n,
                     ordered.end(), compareTuples);

   for (auto it = ordered.begin(); it != ordered.begin() + n; ++it) {
      std::cout << "(" << std::get<0>(*it) << ", " << std::get<1>(*it)
                  << ") = " << std::get<2>(*it) << "\n";
   }
}
<commit_msg>No longer copies entire map into new vector<commit_after>#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>
#include <algorithm>
#include <sstream>
#include <vector>

typedef std::pair<std::string, std::string> TKey;
typedef std::pair<TKey, int> TPair;

struct SvoRow {
   std::string s;
   std::string v;
   std::string o;
   int n;
};

struct hashPair {
   template <class T1, class T2>
   std::size_t operator () (const std::pair<T1, T2> &p) const {
      auto value = 0x345678;
      auto h1 = std::hash<T1>{}(p.first);
      auto h2 = std::hash<T2>{}(p.second);
      value = (100003 * value) ^ h1;
      value = (100003 * value) ^ h2;
      return value;
   }
};

bool compareTuples(TPair a, TPair b) {
   return a.second > b.second;
}

int main(int argc, char** argv) {
   if (argc < 2) {
      std::cout << "Unspecified N value" << std::endl;
      return -1;
   }

   std::unordered_map<TKey, int, hashPair> pairs;

   while (std::cin.peek() != std::char_traits<char>::eof()) {
      SvoRow row;
      std::getline(std::cin, row.s, '\t');
      std::getline(std::cin, row.v, '\t');
      std::getline(std::cin, row.o, '\t');
      std::string tempString;
      std::getline(std::cin, tempString);
      row.n = std::stoi(tempString);
      pairs[std::make_pair(row.s, row.o)] += row.n;
   }

   int n = std::stoi(argv[1]);
   n = std::min(n, (int)pairs.size());
   std::vector<TPair> ordered;
   ordered.resize(n);

   std::partial_sort_copy(pairs.begin(), pairs.end(),
                     ordered.begin(), ordered.end(), compareTuples);

   for (auto &elem : ordered) {
      std::cout << "(" << elem.first.first << ", " << elem.first.second
                  << ") = " << elem.second << "\n";
   }
}
<|endoftext|>


<commit_before>/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
 *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
 *                           www.openmesh.org                                *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenMesh.                                           *
 *                                                                           *
 *  OpenMesh is free software: you can redistribute it and/or modify         *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenMesh is distributed in the hope that it will be useful,              *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenMesh.  If not,                                    *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision: 362 $                                                         *
 *   $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $                   *
 *                                                                           *
\*===========================================================================*/

#define OPENMESH_ARRAY_KERNEL_C

//== INCLUDES =================================================================

#include <OpenMesh/Core/Mesh/ArrayKernel.hh>
//#include <vector>

//== NAMESPACES ===============================================================

namespace OpenMesh
{

//== IMPLEMENTATION ==========================================================

template<typename std_API_Container_VHandlePointer,
         typename std_API_Container_HHandlePointer,
         typename std_API_Container_FHandlePointer>
void ArrayKernel::garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
                                     std_API_Container_HHandlePointer& hh_to_update,
                                     std_API_Container_FHandlePointer& fh_to_update,
                                     bool _v, bool _e, bool _f)
{

  int i, i0, i1, nV(n_vertices()), nE(n_edges()), nH(2*n_edges()), nF(n_faces());

  std::vector<VertexHandle>    vh_map;
  std::vector<HalfedgeHandle>  hh_map;
  std::vector<FaceHandle>      fh_map;

  // setup handle mapping:
  vh_map.reserve(nV);
  for (i=0; i<nV; ++i) vh_map.push_back(VertexHandle(i));

  hh_map.reserve(nH);
  for (i=0; i<nH; ++i) hh_map.push_back(HalfedgeHandle(i));

  fh_map.reserve(nF);
  for (i=0; i<nF; ++i) fh_map.push_back(FaceHandle(i));

  // remove deleted vertices
  if (_v && n_vertices() > 0 && this->has_vertex_status() )
  {
    i0=0;  i1=nV-1;

    while (1)
    {
      // find 1st deleted and last un-deleted
      while (!status(VertexHandle(i0)).deleted() && i0 < i1)  ++i0;
      while ( status(VertexHandle(i1)).deleted() && i0 < i1)  --i1;
      if (i0 >= i1) break;

      // swap
      std::swap(vertices_[i0], vertices_[i1]);
      std::swap(vh_map[i0],  vh_map[i1]);
      vprops_swap(i0, i1);
    };

    vertices_.resize(status(VertexHandle(i0)).deleted() ? i0 : i0+1);
    vprops_resize(n_vertices());
  }

  // remove deleted edges
  if (_e && n_edges() > 0 && this->has_edge_status() )
  {
    i0=0;  i1=nE-1;

    while (1)
    {
      // find 1st deleted and last un-deleted
      while (!status(EdgeHandle(i0)).deleted() && i0 < i1)  ++i0;
      while ( status(EdgeHandle(i1)).deleted() && i0 < i1)  --i1;
      if (i0 >= i1) break;

      // swap
      std::swap(edges_[i0], edges_[i1]);
      std::swap(hh_map[2*i0], hh_map[2*i1]);
      std::swap(hh_map[2*i0+1], hh_map[2*i1+1]);
      eprops_swap(i0, i1);
      hprops_swap(2*i0,   2*i1);
      hprops_swap(2*i0+1, 2*i1+1);
    };

    edges_.resize(status(EdgeHandle(i0)).deleted() ? i0 : i0+1);
    eprops_resize(n_edges());
    hprops_resize(n_halfedges());
  }

  // remove deleted faces
  if (_f && n_faces() > 0 && this->has_face_status() )
  {
    i0=0;  i1=nF-1;

    while (1)
    {
      // find 1st deleted and last un-deleted
      while (!status(FaceHandle(i0)).deleted() && i0 < i1)  ++i0;
      while ( status(FaceHandle(i1)).deleted() && i0 < i1)  --i1;
      if (i0 >= i1) break;

      // swap
      std::swap(faces_[i0], faces_[i1]);
      std::swap(fh_map[i0], fh_map[i1]);
      fprops_swap(i0, i1);
    };

    faces_.resize(status(FaceHandle(i0)).deleted() ? i0 : i0+1);
    fprops_resize(n_faces());
  }

  // update handles of vertices
  if (_e)
  {
    KernelVertexIter v_it(vertices_begin()), v_end(vertices_end());
    VertexHandle     vh;

    for (; v_it!=v_end; ++v_it)
    {
      vh = handle(*v_it);
      if (!is_isolated(vh))
      {
        set_halfedge_handle(vh, hh_map[halfedge_handle(vh).idx()]);
      }
    }
  }

  HalfedgeHandle hh;
  // update handles of halfedges
  for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
  {//in the first pass update the (half)edges vertices
    hh = halfedge_handle(handle(*e_it), 0);
    set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
    hh = halfedge_handle(handle(*e_it), 1);
    set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
  }
  for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
  {//in the second pass update the connectivity of the (half)edges
    hh = halfedge_handle(handle(*e_it), 0);
    set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
    if (!is_boundary(hh))
    {
      set_face_handle(hh, fh_map[face_handle(hh).idx()]);
    }
    hh = halfedge_handle(handle(*e_it), 1);
    set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
    if (!is_boundary(hh))
    {
      set_face_handle(hh, fh_map[face_handle(hh).idx()]);
    }
  }

  // update handles of faces
  if (_e)
  {
    KernelFaceIter  f_it(faces_begin()), f_end(faces_end());
    FaceHandle      fh;

    for (; f_it!=f_end; ++f_it)
    {
      fh = handle(*f_it);
      set_halfedge_handle(fh, hh_map[halfedge_handle(fh).idx()]);
    }
  }

  const int vertexCount   = vertices_.size();
  const int halfedgeCount = edges_.size() * 2;
  const int faceCount     = faces_.size();

  // Update the vertex handles in the vertex handle vector
  typename std_API_Container_VHandlePointer::iterator v_it(vh_to_update.begin()), v_it_end(vh_to_update.end());
  for(; v_it != v_it_end; ++v_it)
  {
    if ( (*v_it)->idx() >=  vertexCount )
      (*v_it)->invalidate();
    else
      *(*v_it) = vh_map[(*v_it)->idx()];
  }

  // Update the halfedge handles in the halfedge handle vector
  typename std_API_Container_HHandlePointer::iterator hh_it(hh_to_update.begin()), hh_it_end(hh_to_update.end());
  for(; hh_it != hh_it_end; ++hh_it)
  {
    if ( (*hh_it)->idx() >=  halfedgeCount )
      (*hh_it)->invalidate();
    else
      *(*hh_it) = hh_map[(*hh_it)->idx()];
  }
  // Update the face handles in the face handle vector
  typename std_API_Container_FHandlePointer::iterator fh_it(fh_to_update.begin()), fh_it_end(fh_to_update.end());
  for(; fh_it != fh_it_end; ++fh_it)
  {
    if ( (*fh_it)->idx() >=  faceCount )
      (*fh_it)->invalidate();
    else
      *(*fh_it) = fh_map[(*fh_it)->idx()];
  }
}

}

<commit_msg>In debug mode write a warning message in garbage collection, if the status flags are missing for one of the primitives.<commit_after>/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
 *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
 *                           www.openmesh.org                                *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenMesh.                                           *
 *                                                                           *
 *  OpenMesh is free software: you can redistribute it and/or modify         *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenMesh is distributed in the hope that it will be useful,              *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenMesh.  If not,                                    *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision: 362 $                                                         *
 *   $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $                   *
 *                                                                           *
\*===========================================================================*/

#define OPENMESH_ARRAY_KERNEL_C

//== INCLUDES =================================================================

#include <OpenMesh/Core/Mesh/ArrayKernel.hh>

//== NAMESPACES ===============================================================

namespace OpenMesh
{

//== IMPLEMENTATION ==========================================================

template<typename std_API_Container_VHandlePointer,
         typename std_API_Container_HHandlePointer,
         typename std_API_Container_FHandlePointer>
void ArrayKernel::garbage_collection(std_API_Container_VHandlePointer& vh_to_update,
                                     std_API_Container_HHandlePointer& hh_to_update,
                                     std_API_Container_FHandlePointer& fh_to_update,
                                     bool _v, bool _e, bool _f)
{

#ifdef DEBUG
  #ifndef OM_GARBAGE_NO_STATUS_WARNING
    if ( !this->has_vertex_status() )
      omerr() << "garbage_collection: No vertex status available. You can request it: mesh.request_vertex_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl;
    if ( !this->has_edge_status() )
      omerr() << "garbage_collection: No edge status available. You can request it: mesh.request_edge_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl;
    if ( !this->has_face_status() )
      omerr() << "garbage_collection: No face status available. You can request it: mesh.request_face_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl;
  #endif
#endif

  int i, i0, i1, nV(n_vertices()), nE(n_edges()), nH(2*n_edges()), nF(n_faces());

  std::vector<VertexHandle>    vh_map;
  std::vector<HalfedgeHandle>  hh_map;
  std::vector<FaceHandle>      fh_map;

  // setup handle mapping:
  vh_map.reserve(nV);
  for (i=0; i<nV; ++i) vh_map.push_back(VertexHandle(i));

  hh_map.reserve(nH);
  for (i=0; i<nH; ++i) hh_map.push_back(HalfedgeHandle(i));

  fh_map.reserve(nF);
  for (i=0; i<nF; ++i) fh_map.push_back(FaceHandle(i));

  // remove deleted vertices
  if (_v && n_vertices() > 0 && this->has_vertex_status() )
  {
    i0=0;  i1=nV-1;

    while (1)
    {
      // find 1st deleted and last un-deleted
      while (!status(VertexHandle(i0)).deleted() && i0 < i1)  ++i0;
      while ( status(VertexHandle(i1)).deleted() && i0 < i1)  --i1;
      if (i0 >= i1) break;

      // swap
      std::swap(vertices_[i0], vertices_[i1]);
      std::swap(vh_map[i0],  vh_map[i1]);
      vprops_swap(i0, i1);
    };

    vertices_.resize(status(VertexHandle(i0)).deleted() ? i0 : i0+1);
    vprops_resize(n_vertices());
  }

  // remove deleted edges
  if (_e && n_edges() > 0 && this->has_edge_status() )
  {
    i0=0;  i1=nE-1;

    while (1)
    {
      // find 1st deleted and last un-deleted
      while (!status(EdgeHandle(i0)).deleted() && i0 < i1)  ++i0;
      while ( status(EdgeHandle(i1)).deleted() && i0 < i1)  --i1;
      if (i0 >= i1) break;

      // swap
      std::swap(edges_[i0], edges_[i1]);
      std::swap(hh_map[2*i0], hh_map[2*i1]);
      std::swap(hh_map[2*i0+1], hh_map[2*i1+1]);
      eprops_swap(i0, i1);
      hprops_swap(2*i0,   2*i1);
      hprops_swap(2*i0+1, 2*i1+1);
    };

    edges_.resize(status(EdgeHandle(i0)).deleted() ? i0 : i0+1);
    eprops_resize(n_edges());
    hprops_resize(n_halfedges());
  }

  // remove deleted faces
  if (_f && n_faces() > 0 && this->has_face_status() )
  {
    i0=0;  i1=nF-1;

    while (1)
    {
      // find 1st deleted and last un-deleted
      while (!status(FaceHandle(i0)).deleted() && i0 < i1)  ++i0;
      while ( status(FaceHandle(i1)).deleted() && i0 < i1)  --i1;
      if (i0 >= i1) break;

      // swap
      std::swap(faces_[i0], faces_[i1]);
      std::swap(fh_map[i0], fh_map[i1]);
      fprops_swap(i0, i1);
    };

    faces_.resize(status(FaceHandle(i0)).deleted() ? i0 : i0+1);
    fprops_resize(n_faces());
  }

  // update handles of vertices
  if (_e)
  {
    KernelVertexIter v_it(vertices_begin()), v_end(vertices_end());
    VertexHandle     vh;

    for (; v_it!=v_end; ++v_it)
    {
      vh = handle(*v_it);
      if (!is_isolated(vh))
      {
        set_halfedge_handle(vh, hh_map[halfedge_handle(vh).idx()]);
      }
    }
  }

  HalfedgeHandle hh;
  // update handles of halfedges
  for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
  {//in the first pass update the (half)edges vertices
    hh = halfedge_handle(handle(*e_it), 0);
    set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
    hh = halfedge_handle(handle(*e_it), 1);
    set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
  }
  for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
  {//in the second pass update the connectivity of the (half)edges
    hh = halfedge_handle(handle(*e_it), 0);
    set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
    if (!is_boundary(hh))
    {
      set_face_handle(hh, fh_map[face_handle(hh).idx()]);
    }
    hh = halfedge_handle(handle(*e_it), 1);
    set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
    if (!is_boundary(hh))
    {
      set_face_handle(hh, fh_map[face_handle(hh).idx()]);
    }
  }

  // update handles of faces
  if (_e)
  {
    KernelFaceIter  f_it(faces_begin()), f_end(faces_end());
    FaceHandle      fh;

    for (; f_it!=f_end; ++f_it)
    {
      fh = handle(*f_it);
      set_halfedge_handle(fh, hh_map[halfedge_handle(fh).idx()]);
    }
  }

  const int vertexCount   = vertices_.size();
  const int halfedgeCount = edges_.size() * 2;
  const int faceCount     = faces_.size();

  // Update the vertex handles in the vertex handle vector
  typename std_API_Container_VHandlePointer::iterator v_it(vh_to_update.begin()), v_it_end(vh_to_update.end());
  for(; v_it != v_it_end; ++v_it)
  {
    if ( (*v_it)->idx() >=  vertexCount )
      (*v_it)->invalidate();
    else
      *(*v_it) = vh_map[(*v_it)->idx()];
  }

  // Update the halfedge handles in the halfedge handle vector
  typename std_API_Container_HHandlePointer::iterator hh_it(hh_to_update.begin()), hh_it_end(hh_to_update.end());
  for(; hh_it != hh_it_end; ++hh_it)
  {
    if ( (*hh_it)->idx() >=  halfedgeCount )
      (*hh_it)->invalidate();
    else
      *(*hh_it) = hh_map[(*hh_it)->idx()];
  }
  // Update the face handles in the face handle vector
  typename std_API_Container_FHandlePointer::iterator fh_it(fh_to_update.begin()), fh_it_end(fh_to_update.end());
  for(; fh_it != fh_it_end; ++fh_it)
  {
    if ( (*fh_it)->idx() >=  faceCount )
      (*fh_it)->invalidate();
    else
      *(*fh_it) = fh_map[(*fh_it)->idx()];
  }
}

}

<|endoftext|>


<commit_before>/*************************************************************************
*    UrBackup - Client/Server backup system
*    Copyright (C) 2011  Martin Raiber
*
*    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 3 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.  If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/

#include "../vld.h"
#include "file.h"
#include "types.h"
#include "stringtools.h"
#ifdef _DEBUG
#include "Server.h"
#endif

#ifdef MODE_WIN

File::File()
	: hfile(INVALID_HANDLE_VALUE)
{

}

bool File::Open(std::wstring pfn, int mode)
{
	fn=pfn;
	DWORD dwCreationDisposition;
	DWORD dwDesiredAccess;
	if( mode==MODE_READ )
	{
		dwCreationDisposition=OPEN_EXISTING;
		dwDesiredAccess=GENERIC_READ;
	}
	else if( mode==MODE_WRITE )
	{
		DeleteFileInt(pfn);
		dwCreationDisposition=CREATE_NEW;
		dwDesiredAccess=GENERIC_WRITE;
	}
	else if( mode==MODE_APPEND|| mode==MODE_TEMP )
	{
		dwCreationDisposition=OPEN_EXISTING;
		dwDesiredAccess=GENERIC_WRITE | GENERIC_READ;
	}
	else if( mode==MODE_RW || mode==MODE_RW_CREATE)
	{
		if(mode==MODE_RW)
		{
			dwCreationDisposition=OPEN_EXISTING;
		}
		else
		{
			dwCreationDisposition=CREATE_NEW;
		}
		dwDesiredAccess=GENERIC_WRITE | GENERIC_READ;
	}

	hfile=CreateFileW( fn.c_str(), dwDesiredAccess, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL );

	if( hfile!=INVALID_HANDLE_VALUE )
	{
		if( mode==MODE_APPEND )
		{
			Seek( Size() );
		}
		return true;
	}
	else
	{
#ifdef _DEBUG
		Server->Log("EC: "+nconvert((int)GetLastError()));
#endif
		hfile=NULL;
		return false;
	}
}

bool File::OpenTemporaryFile(const std::wstring &tmpdir)
{
	if(tmpdir.empty())
	{
		wchar_t tmpp[MAX_PATH];
		DWORD l;
		if((l=GetTempPathW(MAX_PATH, tmpp))==0 || l>MAX_PATH )
		{
			wcscpy_s(tmpp,L"C:\\");
		}

		wchar_t filename[MAX_PATH];
		if( GetTempFileNameW(tmpp, L"urbackup.t", 0, filename)==0 )
		{
			hfile=NULL;
			int err=GetLastError();
			return false;
		}

		return Open(filename, MODE_TEMP);
	}
	else
	{
		wchar_t filename[MAX_PATH];
		if( GetTempFileNameW(tmpdir.c_str(), L"urbackup.t", 0, filename)==0 )
		{
			hfile=NULL;
			int err=GetLastError();
			return false;
		}

		return Open(filename, MODE_TEMP);
	}
}

bool File::Open(void *handle)
{
	hfile=(HANDLE)handle;
	if( hfile!=INVALID_HANDLE_VALUE )
	{
		return true;
	}
	else
	{
		return false;
	}
}

std::string File::Read(_u32 tr)
{
	std::string ret;
	ret.resize(tr);
	_u32 gc=Read((char*)ret.c_str(), tr);
	if( gc<tr )
		ret.resize( gc );

	return ret;
}

_u32 File::Read(char* buffer, _u32 bsize)
{
	DWORD read;
	BOOL b=ReadFile(hfile, buffer, bsize, &read, NULL );
#ifdef _DEBUG
	if(b==FALSE)
	{
		int err=GetLastError();
		Server->Log("Read error: "+nconvert(err));
	}
	/*if(read!=bsize)
	{
		int err=GetLastError();
		Server->Log("Read error: "+nconvert(err));
	}*/
#endif
	return (_u32)read;
}

_u32 File::Write(const std::string &tw)
{
	return Write( tw.c_str(), (_u32)tw.size() );
}

_u32 File::Write(const char* buffer, _u32 bsize)
{
	DWORD written;
	WriteFile(hfile, buffer, bsize, &written, NULL);
	return written;
}

bool File::Seek(_i64 spos)
{
	LARGE_INTEGER tmp;
	tmp.QuadPart=spos;
	if( SetFilePointerEx(hfile, tmp, NULL, FILE_BEGIN) == FALSE )
	{
		int err=GetLastError();
		return false;
	}
	else
		return true;
}

_i64 File::Size(void)
{
	LARGE_INTEGER fs;
	GetFileSizeEx(hfile, &fs);

	return fs.QuadPart;
}

void File::Close()
{
	if( hfile!=NULL )
	{
		BOOL b=CloseHandle( hfile );
		hfile=NULL;
	}
}

#endif
<commit_msg>Don't allow other applications to open files in Windows<commit_after>/*************************************************************************
*    UrBackup - Client/Server backup system
*    Copyright (C) 2011  Martin Raiber
*
*    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 3 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.  If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/

#include "../vld.h"
#include "file.h"
#include "types.h"
#include "stringtools.h"
#ifdef _DEBUG
#include "Server.h"
#endif

#ifdef MODE_WIN

File::File()
	: hfile(INVALID_HANDLE_VALUE)
{

}

bool File::Open(std::wstring pfn, int mode)
{
	fn=pfn;
	DWORD dwCreationDisposition;
	DWORD dwDesiredAccess;
	if( mode==MODE_READ )
	{
		dwCreationDisposition=OPEN_EXISTING;
		dwDesiredAccess=GENERIC_READ;
	}
	else if( mode==MODE_WRITE )
	{
		DeleteFileInt(pfn);
		dwCreationDisposition=CREATE_NEW;
		dwDesiredAccess=GENERIC_WRITE;
	}
	else if( mode==MODE_APPEND|| mode==MODE_TEMP )
	{
		dwCreationDisposition=OPEN_EXISTING;
		dwDesiredAccess=GENERIC_WRITE | GENERIC_READ;
	}
	else if( mode==MODE_RW || mode==MODE_RW_CREATE)
	{
		if(mode==MODE_RW)
		{
			dwCreationDisposition=OPEN_EXISTING;
		}
		else
		{
			dwCreationDisposition=CREATE_NEW;
		}
		dwDesiredAccess=GENERIC_WRITE | GENERIC_READ;
	}

	hfile=CreateFileW( fn.c_str(), dwDesiredAccess, FILE_SHARE_READ, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL );

	if( hfile!=INVALID_HANDLE_VALUE )
	{
		if( mode==MODE_APPEND )
		{
			Seek( Size() );
		}
		return true;
	}
	else
	{
#ifdef _DEBUG
		Server->Log("EC: "+nconvert((int)GetLastError()));
#endif
		hfile=NULL;
		return false;
	}
}

bool File::OpenTemporaryFile(const std::wstring &tmpdir)
{
	if(tmpdir.empty())
	{
		wchar_t tmpp[MAX_PATH];
		DWORD l;
		if((l=GetTempPathW(MAX_PATH, tmpp))==0 || l>MAX_PATH )
		{
			wcscpy_s(tmpp,L"C:\\");
		}

		wchar_t filename[MAX_PATH];
		if( GetTempFileNameW(tmpp, L"urbackup.t", 0, filename)==0 )
		{
			hfile=NULL;
			int err=GetLastError();
			return false;
		}

		return Open(filename, MODE_TEMP);
	}
	else
	{
		wchar_t filename[MAX_PATH];
		if( GetTempFileNameW(tmpdir.c_str(), L"urbackup.t", 0, filename)==0 )
		{
			hfile=NULL;
			int err=GetLastError();
			return false;
		}

		return Open(filename, MODE_TEMP);
	}
}

bool File::Open(void *handle)
{
	hfile=(HANDLE)handle;
	if( hfile!=INVALID_HANDLE_VALUE )
	{
		return true;
	}
	else
	{
		return false;
	}
}

std::string File::Read(_u32 tr)
{
	std::string ret;
	ret.resize(tr);
	_u32 gc=Read((char*)ret.c_str(), tr);
	if( gc<tr )
		ret.resize( gc );

	return ret;
}

_u32 File::Read(char* buffer, _u32 bsize)
{
	DWORD read;
	BOOL b=ReadFile(hfile, buffer, bsize, &read, NULL );
#ifdef _DEBUG
	if(b==FALSE)
	{
		int err=GetLastError();
		Server->Log("Read error: "+nconvert(err));
	}
	/*if(read!=bsize)
	{
		int err=GetLastError();
		Server->Log("Read error: "+nconvert(err));
	}*/
#endif
	return (_u32)read;
}

_u32 File::Write(const std::string &tw)
{
	return Write( tw.c_str(), (_u32)tw.size() );
}

_u32 File::Write(const char* buffer, _u32 bsize)
{
	DWORD written;
	WriteFile(hfile, buffer, bsize, &written, NULL);
	return written;
}

bool File::Seek(_i64 spos)
{
	LARGE_INTEGER tmp;
	tmp.QuadPart=spos;
	if( SetFilePointerEx(hfile, tmp, NULL, FILE_BEGIN) == FALSE )
	{
		int err=GetLastError();
		return false;
	}
	else
		return true;
}

_i64 File::Size(void)
{
	LARGE_INTEGER fs;
	GetFileSizeEx(hfile, &fs);

	return fs.QuadPart;
}

void File::Close()
{
	if( hfile!=NULL )
	{
		BOOL b=CloseHandle( hfile );
		hfile=NULL;
	}
}

#endif
<|endoftext|>


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

/* Test the SfxUShortRanges class */

#ifndef _SFXITEMS_HXX
#include <sfxitems.hxx>
#endif

USHORT nValues1[] = {340,472,482,4288,4374,4890,5026,5356,5724,6130,6186,6666,9222,9764,9908,
                        10110,11302,11748,11946,12298,12344,12642,12958,13076,13410,13496,14462,
                        14480,14592,16292,16788,17102,17792,17844,18182,18396,18522,18974,19292,
                        19630,20336,21808,21972,22382,23568,25156,26978,27158,27730,28014,28280,
                        28774,29258,30920,30938,31356,31582,32194,32734,32893,33757,33911,34013,
                        34565,35283,38895,40273,41281,42157,44429,44553,45825,46367,48163,48417,
                        49501,50499,52105,53035,53715,53899,54015,54131,54865,55155,55507,56325,
                        57045,59243,59833,59859,59951,60361,61387,62453,62703,63155,63517,63621,
                        63895,0};

USHORT nValues2[] = {2362,3100,3286,3548,4056,4224,5058,5198,5398,5990,6910,7034,7046,8574,8762,
                    9360,9494,9720,11432,12900,12946,13626,13844,14344,15028,16306,16494,16972,
                    17340,17504,17610,18270,18506,19832,19962,20356,20792,21146,21270,21722,
                    22486,22752,23554,24148,24210,24910,25006,25500,26464,26952,27216,28394,
                    28398,29602,31130,31642,31894,33343,34191,34593,34931,36221,36637,37287,
                    37765,39853,41231,41711,41799,44213,44863,46491,47459,48707,48911,49353,
                    49923,49997,50117,51357,51519,52043,52563,52727,53781,54065,54249,55333,
                    56549,57361,57777,58165,58507,59229,59719,60379,60845,62697,63123,65169,0};

#include <sv.hxx>

SfxUShortRanges aRanges1a( nValues1 );
SfxUShortRanges aRanges1b( nValues1 );
SfxUShortRanges aRanges1c( nValues1 );
SfxUShortRanges aRanges2( nValues2 );

String aStr1;
String aStr2;
String aStr3;

static String MakeString_Impl( SfxUShortRanges& aRanges )
{
    String aStr;

    USHORT nPos = 0;
    const USHORT* pRanges = ( const USHORT*)aRanges;

    while( pRanges[ nPos ] != 0 )
    {
        aStr += pRanges[ nPos ];
        aStr += " - ";
        aStr += pRanges[ nPos+1 ];
        aStr += ", ";
        nPos += 2;
    }

    return aStr;
}

// -------------------------------------------------------------------------

class MyApp : public Application
{
public:
  void Main( int, char* [] );
};

// -------------------------------------------------------------------------

class MyDialog : public ModalDialog
{
private:
    GroupBox aGroup1;
    MultiLineEdit aEdit1;
    GroupBox aGroup2;
    MultiLineEdit aEdit2;
    GroupBox aGroup3;
    MultiLineEdit aEdit3;
    OKButton      aBtn1;
    CancelButton  aBtn2;

public:
  MyDialog( Window* pParent );

  void MouseButtonDown( const MouseEvent& rMEvt );
};

// -------------------------------------------------------------------------

MyDialog::MyDialog( Window* pParent ) :
    ModalDialog( pParent, WB_STDMODAL | WB_SVLOOK ),
    aGroup1( this ),
    aEdit1( this, WB_BORDER | WB_READONLY ),
    aGroup2( this ),
    aEdit2( this, WB_BORDER | WB_READONLY ),
    aGroup3( this ),
    aEdit3( this, WB_BORDER | WB_READONLY ),
    aBtn1( this, WB_DEFBUTTON ),
    aBtn2( this )
{
    aGroup1.SetText( "Union" );
    aGroup1.SetPosSizePixel( Point( 5, 5 ), Size( 330, 80 ) );
    aGroup1.Show();

    aEdit1.SetPosSizePixel( Point ( 10, 20 ), Size( 320, 60 ) );
    aEdit1.SetText( aStr1 );
    aEdit1.Show();

    aGroup2.SetText( "Difference" );
    aGroup2.SetPosSizePixel( Point( 5, 90 ), Size( 330, 80 ) );
    aGroup2.Show();

    aEdit2.SetPosSizePixel( Point( 10, 105 ), Size( 320, 60 ) );
    aEdit2.SetText( aStr2 );
    aEdit2.Show();

    aGroup3.SetText( "Intersection" );
    aGroup3.SetPosSizePixel( Point( 5, 175 ), Size( 330, 80 ) );
    aGroup3.Show();

    aEdit3.SetPosSizePixel( Point( 10, 190 ), Size( 320, 60 ) );
    aEdit3.SetText( aStr3 );
    aEdit3.Show();

    aBtn1.SetPosSizePixel( Point( 10, 310 ), Size( 100, 25 ) );
    aBtn1.Show();

    aBtn2.SetPosSizePixel( Point( 120, 310 ), Size( 100, 25 ) );
    aBtn2.Show();

    SetOutputSizePixel( Size( 340, 345 ) );
    SetText( "SfxUShortRanges Test" );
}

// -------------------------------------------------------------------------

void MyDialog::MouseButtonDown( const MouseEvent& rMEvt )
{
}

// -------------------------------------------------------------------------

class MyWin : public WorkWindow
{
public:
  MyWin( Window* pParent, WinBits aWinStyle ) :
    WorkWindow( pParent, aWinStyle )
  {}

  void MouseButtonDown( const MouseEvent& );
};

// -------------------------------------------------------------------------

MyApp aMyApp;

void MyApp::Main( int, char* [] )
{
    EnableSVLook();
    SetAppFont( System::GetStandardFont( STDFONT_APP ) );

    MyWin aMainWin( NULL, WB_APP | WB_STDWORK );
    aMainWin.SetText( "SfxUShortRanges - Test" );
    aMainWin.Show();

    aRanges1a += aRanges2;
    aRanges1b -= aRanges2;
    aRanges1c /= aRanges2;

    aStr1 = MakeString_Impl( aRanges1a );
    aStr2 = MakeString_Impl( aRanges1b );
    aStr3 = MakeString_Impl( aRanges1c );

    Execute();
}

// -------------------------------------------------------------------------

void MyWin::MouseButtonDown( const MouseEvent& rMEvt )
{
  if( rMEvt.IsLeft() )
    {
      MyDialog* pDialog = new MyDialog( this );
      pDialog->Execute();
      delete pDialog;
    }
}

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

/* Test the SfxUShortRanges class */

#ifndef _SFXITEMS_HXX
#include <sfxitems.hxx>
#endif

USHORT nValues1[] = {340,472,482,4288,4374,4890,5026,5356,5724,6130,6186,6666,9222,9764,9908,
                        10110,11302,11748,11946,12298,12344,12642,12958,13076,13410,13496,14462,
                        14480,14592,16292,16788,17102,17792,17844,18182,18396,18522,18974,19292,
                        19630,20336,21808,21972,22382,23568,25156,26978,27158,27730,28014,28280,
                        28774,29258,30920,30938,31356,31582,32194,32734,32893,33757,33911,34013,
                        34565,35283,38895,40273,41281,42157,44429,44553,45825,46367,48163,48417,
                        49501,50499,52105,53035,53715,53899,54015,54131,54865,55155,55507,56325,
                        57045,59243,59833,59859,59951,60361,61387,62453,62703,63155,63517,63621,
                        63895,0};

USHORT nValues2[] = {2362,3100,3286,3548,4056,4224,5058,5198,5398,5990,6910,7034,7046,8574,8762,
                    9360,9494,9720,11432,12900,12946,13626,13844,14344,15028,16306,16494,16972,
                    17340,17504,17610,18270,18506,19832,19962,20356,20792,21146,21270,21722,
                    22486,22752,23554,24148,24210,24910,25006,25500,26464,26952,27216,28394,
                    28398,29602,31130,31642,31894,33343,34191,34593,34931,36221,36637,37287,
                    37765,39853,41231,41711,41799,44213,44863,46491,47459,48707,48911,49353,
                    49923,49997,50117,51357,51519,52043,52563,52727,53781,54065,54249,55333,
                    56549,57361,57777,58165,58507,59229,59719,60379,60845,62697,63123,65169,0};

#include <sv.hxx>

SfxUShortRanges aRanges1a( nValues1 );
SfxUShortRanges aRanges1b( nValues1 );
SfxUShortRanges aRanges1c( nValues1 );
SfxUShortRanges aRanges2( nValues2 );

String aStr1;
String aStr2;
String aStr3;

static String MakeString_Impl( SfxUShortRanges& aRanges )
{
    String aStr;

    USHORT nPos = 0;
    const USHORT* pRanges = ( const USHORT*)aRanges;

    while( pRanges[ nPos ] != 0 )
    {
        aStr += pRanges[ nPos ];
        aStr += " - ";
        aStr += pRanges[ nPos+1 ];
        aStr += ", ";
        nPos += 2;
    }

    return aStr;
}

// -------------------------------------------------------------------------

class MyApp : public Application
{
public:
  void Main( int, char* [] );
};

// -------------------------------------------------------------------------

class MyDialog : public ModalDialog
{
private:
    GroupBox aGroup1;
    MultiLineEdit aEdit1;
    GroupBox aGroup2;
    MultiLineEdit aEdit2;
    GroupBox aGroup3;
    MultiLineEdit aEdit3;
    OKButton      aBtn1;
    CancelButton  aBtn2;

public:
  MyDialog( Window* pParent );

  void MouseButtonDown( const MouseEvent& rMEvt );
};

// -------------------------------------------------------------------------

MyDialog::MyDialog( Window* pParent ) :
    ModalDialog( pParent, WB_STDMODAL | WB_3DLOOK ),
    aGroup1( this ),
    aEdit1( this, WB_BORDER | WB_READONLY ),
    aGroup2( this ),
    aEdit2( this, WB_BORDER | WB_READONLY ),
    aGroup3( this ),
    aEdit3( this, WB_BORDER | WB_READONLY ),
    aBtn1( this, WB_DEFBUTTON ),
    aBtn2( this )
{
    aGroup1.SetText( "Union" );
    aGroup1.SetPosSizePixel( Point( 5, 5 ), Size( 330, 80 ) );
    aGroup1.Show();

    aEdit1.SetPosSizePixel( Point ( 10, 20 ), Size( 320, 60 ) );
    aEdit1.SetText( aStr1 );
    aEdit1.Show();

    aGroup2.SetText( "Difference" );
    aGroup2.SetPosSizePixel( Point( 5, 90 ), Size( 330, 80 ) );
    aGroup2.Show();

    aEdit2.SetPosSizePixel( Point( 10, 105 ), Size( 320, 60 ) );
    aEdit2.SetText( aStr2 );
    aEdit2.Show();

    aGroup3.SetText( "Intersection" );
    aGroup3.SetPosSizePixel( Point( 5, 175 ), Size( 330, 80 ) );
    aGroup3.Show();

    aEdit3.SetPosSizePixel( Point( 10, 190 ), Size( 320, 60 ) );
    aEdit3.SetText( aStr3 );
    aEdit3.Show();

    aBtn1.SetPosSizePixel( Point( 10, 310 ), Size( 100, 25 ) );
    aBtn1.Show();

    aBtn2.SetPosSizePixel( Point( 120, 310 ), Size( 100, 25 ) );
    aBtn2.Show();

    SetOutputSizePixel( Size( 340, 345 ) );
    SetText( "SfxUShortRanges Test" );
}

// -------------------------------------------------------------------------

void MyDialog::MouseButtonDown( const MouseEvent& rMEvt )
{
}

// -------------------------------------------------------------------------

class MyWin : public WorkWindow
{
public:
  MyWin( Window* pParent, WinBits aWinStyle ) :
    WorkWindow( pParent, aWinStyle )
  {}

  void MouseButtonDown( const MouseEvent& );
};

// -------------------------------------------------------------------------

MyApp aMyApp;

void MyApp::Main( int, char* [] )
{
    EnableSVLook();
    SetAppFont( System::GetStandardFont( STDFONT_APP ) );

    MyWin aMainWin( NULL, WB_APP | WB_STDWORK );
    aMainWin.SetText( "SfxUShortRanges - Test" );
    aMainWin.Show();

    aRanges1a += aRanges2;
    aRanges1b -= aRanges2;
    aRanges1c /= aRanges2;

    aStr1 = MakeString_Impl( aRanges1a );
    aStr2 = MakeString_Impl( aRanges1b );
    aStr3 = MakeString_Impl( aRanges1c );

    Execute();
}

// -------------------------------------------------------------------------

void MyWin::MouseButtonDown( const MouseEvent& rMEvt )
{
  if( rMEvt.IsLeft() )
    {
      MyDialog* pDialog = new MyDialog( this );
      pDialog->Execute();
      delete pDialog;
    }
}

<|endoftext|>


<commit_before>/*
 * Qumulus UML editor
 * Author: Randy Thiemann
 *
 */

#include "MainWindow.h"
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QMenu>
#include <Gui/Widgets/SideBar.h>
#include <Gui/Widgets/ToolBar.h>
#include <Gui/Widgets/StyleType.h>
#include <Gui/Widgets/StatusBar.h>
#include <Gui/Widgets/EditorView.h>
#include <Gui/Core/QumulusApplication.h>
#include <QtWidgets/QSplitter>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QAction>
#include <QtWidgets/QMessageBox>

QUML_BEGIN_NAMESPACE_GW

MainWindow::MainWindow() :
        mToolBar(new ToolBar(this)),
        mSideBar(new SideBar(this)),
        mSplitter(new QSplitter(this)),
        mStatusBar(new StatusBar(this)),
        mEditorView(new EditorView(this)) {
    constexpr unsigned kWidth = 700, kHeight = 480, kSideWidth = 220;

    // Size constraints
    setMinimumSize(400, 300);
    resize(kWidth, kHeight);

    // Title
    setWindowTitle("Qumulus");

    // Add toolbar
    mToolBar->showInWindow(this);

    // Add toolbar item
    // TODO separate this and store classItem?
    ToolBarItem* classItem = new ToolBarItem(mToolBar);
    classItem->setIcon(QIcon(":/data/img/toolbar/class.png"));
    classItem->setText("Class");
    mToolBar->addWidget(classItem);

    // Create main view.
    setCentralWidget(mSplitter);

#ifdef Q_OS_MAC
    mSplitter->setHandleWidth(0);
#endif

    mSplitter->setChildrenCollapsible(false);

    // Add the treeview.
    mSplitter->addWidget(mSideBar);

    // Add the Editor view.
    QSizePolicy editorViewPolicy = mEditorView->sizePolicy();
    editorViewPolicy.setHorizontalPolicy(QSizePolicy::Expanding);
    mEditorView->setSizePolicy(editorViewPolicy);
    mSplitter->addWidget(mEditorView);

    // Force the treeview an appropriate size.
    mSplitter->setSizes({kSideWidth, kWidth - kSideWidth});
    mSplitter->setStretchFactor(0, 0);
    mSplitter->setStretchFactor(1, 1);

    // Add the status bar.
    setStatusBar(mStatusBar);

    createMenus();

    connect(mStatusBar->slider(), &ZoomSlider::valueChanged,
            mEditorView, &EditorView::zoom);
}

void MainWindow::createMenus() {
    mFileMenu = menuBar()->addMenu(tr("&File"));
    mEditMenu = menuBar()->addMenu(tr("&Edit"));
    mInsertMenu = menuBar()->addMenu(tr("&Insert"));
    mViewMenu = menuBar()->addMenu(tr("&View"));
    mHelpMenu = menuBar()->addMenu(tr("&Help"));

    // File Menu
    mNewAction = new QAction(tr("&New"), this);
    mNewAction->setShortcuts(QKeySequence::New);

    mOpenAction = new QAction(tr("&Open..."), this);
    mOpenAction->setShortcuts(QKeySequence::Open);

    mCloseAction = new QAction(tr("Close"), this);
    mCloseAction->setShortcuts(QKeySequence::Close);

    mPrintAction = new QAction(tr("&Print..."), this);
    mPrintAction->setShortcuts(QKeySequence::Print);

    mPrefsAction = new QAction(tr("Settings"), this);
    mPrefsAction->setShortcuts(QKeySequence::Preferences);

    mQuitAction = new QAction(tr("&Quit"), this);
    mQuitAction->setShortcuts(QKeySequence::Quit);
    connect(mQuitAction, &QAction::triggered, &QApplication::exit);

    mFileMenu->addAction(mNewAction);
    mFileMenu->addAction(mOpenAction);
    mFileMenu->addSeparator();
    mFileMenu->addAction(mCloseAction);
    mFileMenu->addSeparator();
    mFileMenu->addAction(mPrintAction);
    mFileMenu->addSeparator();
    mFileMenu->addAction(mPrefsAction);
    mFileMenu->addAction(mQuitAction);

    // Edit Menu
    mUndoAction = new QAction(tr("&Undo"), this);
    mUndoAction->setShortcuts(QKeySequence::Undo);

    mRedoAction = new QAction(tr("&Redo"), this);
    mRedoAction->setShortcuts(QKeySequence::Redo);

    mCutAction = new QAction(tr("&Cut"), this);
    mCutAction->setShortcuts(QKeySequence::Cut);

    mCopyAction = new QAction(tr("C&opy"), this);
    mCopyAction->setShortcuts(QKeySequence::Copy);

    mPasteAction = new QAction(tr("&Paste"), this);
    mPasteAction->setShortcuts(QKeySequence::Paste);

    mDeleteAction = new QAction(tr("&Delete"), this);
    mDeleteAction->setShortcuts(QKeySequence::Delete);

    mDuplicateAction = new QAction(tr("D&uplicate"), this);
    mDuplicateAction->setShortcuts({QKeySequence(tr("Ctrl+D"))});

    mEditMenu->addAction(mUndoAction);
    mEditMenu->addAction(mRedoAction);
    mEditMenu->addAction(mCutAction);
    mEditMenu->addAction(mCopyAction);
    mEditMenu->addAction(mPasteAction);
    mEditMenu->addAction(mDeleteAction);
    mEditMenu->addAction(mDuplicateAction);

    // Help Menu
    mAboutAction = new QAction(tr("&About Qumulus"), this);
    connect(mAboutAction, &QAction::triggered, [&]{
            this->setWindowIcon(QIcon(":/logo/qumulus-256.png"));
            QMessageBox::about(this,
                "About Qumulus",
                "Qumulus\n"
                "Version 0.1\n\n"
                "Authors: Frank Erens & Randy Thiemann");
            this->setWindowIcon(QIcon(""));});

    mHelpMenu->addAction(mAboutAction);
}

QUML_END_NAMESPACE_GW

<commit_msg>Modify MainWindow.<commit_after>/*
 * Qumulus UML editor
 * Author: Randy Thiemann
 *
 */

#include "MainWindow.h"
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QMenu>
#include <Gui/Widgets/SideBar.h>
#include <Gui/Widgets/ToolBar.h>
#include <Gui/Widgets/StyleType.h>
#include <Gui/Widgets/StatusBar.h>
#include <Gui/Widgets/EditorView.h>
#include <Gui/Widgets/ElementItem.h>
#include <Gui/Core/QumulusApplication.h>
#include <QtWidgets/QSplitter>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QAction>
#include <QtWidgets/QMessageBox>

QUML_BEGIN_NAMESPACE_GW

MainWindow::MainWindow() :
        mToolBar(new ToolBar(this)),
        mSideBar(new SideBar(this)),
        mSplitter(new QSplitter(this)),
        mStatusBar(new StatusBar(this)),
        mEditorView(new EditorView(this)) {
    constexpr unsigned kWidth = 700, kHeight = 480, kSideWidth = 220;

    // Size constraints
    setMinimumSize(400, 300);
    resize(kWidth, kHeight);

    // Title
    setWindowTitle("Qumulus");

    // Add toolbar
    mToolBar->showInWindow(this);

    // Add toolbar item
    // TODO separate this and store classItem?
    ElementItem eli("Class", QIcon(":/data/img/toolbar/class.png"),
            QKeySequence(tr("C")));
    ToolBarItem* classItem = new ToolBarItem(eli);
    //classItem->setIcon(QIcon(":/data/img/toolbar/class.png"));
    //classItem->setText("Class");
    mToolBar->addWidget(classItem);

    // Create main view.
    setCentralWidget(mSplitter);

#ifdef Q_OS_MAC
    mSplitter->setHandleWidth(0);
#endif

    mSplitter->setChildrenCollapsible(false);

    // Add the treeview.
    mSplitter->addWidget(mSideBar);

    // Add the Editor view.
    QSizePolicy editorViewPolicy = mEditorView->sizePolicy();
    editorViewPolicy.setHorizontalPolicy(QSizePolicy::Expanding);
    mEditorView->setSizePolicy(editorViewPolicy);
    mSplitter->addWidget(mEditorView);

    // Force the treeview an appropriate size.
    mSplitter->setSizes({kSideWidth, kWidth - kSideWidth});
    mSplitter->setStretchFactor(0, 0);
    mSplitter->setStretchFactor(1, 1);

    // Add the status bar.
    setStatusBar(mStatusBar);

    createMenus();

    connect(mStatusBar->slider(), &ZoomSlider::valueChanged,
            mEditorView, &EditorView::zoom);
}

void MainWindow::createMenus() {
    mFileMenu = menuBar()->addMenu(tr("&File"));
    mEditMenu = menuBar()->addMenu(tr("&Edit"));
    mInsertMenu = menuBar()->addMenu(tr("&Insert"));
    mViewMenu = menuBar()->addMenu(tr("&View"));
    mHelpMenu = menuBar()->addMenu(tr("&Help"));

    // File Menu
    mNewAction = new QAction(tr("&New"), this);
    mNewAction->setShortcuts(QKeySequence::New);

    mOpenAction = new QAction(tr("&Open..."), this);
    mOpenAction->setShortcuts(QKeySequence::Open);

    mCloseAction = new QAction(tr("Close"), this);
    mCloseAction->setShortcuts(QKeySequence::Close);

    mPrintAction = new QAction(tr("&Print..."), this);
    mPrintAction->setShortcuts(QKeySequence::Print);

    mPrefsAction = new QAction(tr("Settings"), this);
    mPrefsAction->setShortcuts(QKeySequence::Preferences);

    mQuitAction = new QAction(tr("&Quit"), this);
    mQuitAction->setShortcuts(QKeySequence::Quit);
    connect(mQuitAction, &QAction::triggered, &QApplication::exit);

    mFileMenu->addAction(mNewAction);
    mFileMenu->addAction(mOpenAction);
    mFileMenu->addSeparator();
    mFileMenu->addAction(mCloseAction);
    mFileMenu->addSeparator();
    mFileMenu->addAction(mPrintAction);
    mFileMenu->addSeparator();
    mFileMenu->addAction(mPrefsAction);
    mFileMenu->addAction(mQuitAction);

    // Edit Menu
    mUndoAction = new QAction(tr("&Undo"), this);
    mUndoAction->setShortcuts(QKeySequence::Undo);

    mRedoAction = new QAction(tr("&Redo"), this);
    mRedoAction->setShortcuts(QKeySequence::Redo);

    mCutAction = new QAction(tr("&Cut"), this);
    mCutAction->setShortcuts(QKeySequence::Cut);

    mCopyAction = new QAction(tr("C&opy"), this);
    mCopyAction->setShortcuts(QKeySequence::Copy);

    mPasteAction = new QAction(tr("&Paste"), this);
    mPasteAction->setShortcuts(QKeySequence::Paste);

    mDeleteAction = new QAction(tr("&Delete"), this);
    mDeleteAction->setShortcuts(QKeySequence::Delete);

    mDuplicateAction = new QAction(tr("D&uplicate"), this);
    mDuplicateAction->setShortcuts({QKeySequence(tr("Ctrl+D"))});

    mEditMenu->addAction(mUndoAction);
    mEditMenu->addAction(mRedoAction);
    mEditMenu->addAction(mCutAction);
    mEditMenu->addAction(mCopyAction);
    mEditMenu->addAction(mPasteAction);
    mEditMenu->addAction(mDeleteAction);
    mEditMenu->addAction(mDuplicateAction);

    // Help Menu
    mAboutAction = new QAction(tr("&About Qumulus"), this);
    connect(mAboutAction, &QAction::triggered, [&]{
            this->setWindowIcon(QIcon(":/logo/qumulus-256.png"));
            QMessageBox::about(this,
                "About Qumulus",
                "Qumulus\n"
                "Version 0.1\n\n"
                "Authors: Frank Erens & Randy Thiemann");
            this->setWindowIcon(QIcon(""));});

    mHelpMenu->addAction(mAboutAction);
}

QUML_END_NAMESPACE_GW

<|endoftext|>