<commit_before>/* Copyright The kNet Project.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

/** @file SimpleChat.cpp
	@brief */

#include <iostream>
#include <string>

#include "kNet.h"
#include "kNet/DebugMemoryLeakCheck.h"

//#undef _MSC_VER

using namespace std;
using namespace kNet;

const unsigned long cChatMessageID = 42;

class NetworkApp : public INetworkServerListener, public IMessageHandler
{
	Network network;
	// If we are the server, this pointer will be nonzero.
	NetworkServer *server;
	// If we are the client, this pointer will be nonzero.
	Ptr(MessageConnection) connection;

	// Will contain the chat message as it is being typed on the command line.
	std::string inputText;

public:
	NetworkApp()
	:server(0)
	{
	}

	// The server must implement this message.
	bool NewConnectionAttempt(const EndPoint &/*endPoint*/, Datagram &/*datagram*/)
	{
		// Allow the client to connect.
		return true;
	}

	/// Called to notify the listener that a new connection has been established.
	void NewConnectionEstablished(MessageConnection *connection)
	{
		cout << "New connection from " << connection->ToString() << "." << endl;
		connection->RegisterInboundMessageHandler(this);
	}

	void HandleMessage(MessageConnection *source, packet_id_t /*packetId*/, message_id_t messageId, const char *data, size_t numBytes)
	{
		if (messageId == cChatMessageID)
			OnChatMessageReceived(source, data, numBytes);
	}

	void RunServer(unsigned short port, SocketTransportLayer transport)
	{
		// Start the server either in TCP or UDP mode.
		server = network.StartServer(port, transport, this, true);
		if (!server)
		{
			cout << "Unable to start server in port " << port << "!" << endl;
			return;
		}

		cout << "Server waiting for connection in port " << port << "." << endl;

		while(server->GetConnections().size() == 0)
		{
			server->Process();
			Clock::Sleep(100);
		}

		Ptr(MessageConnection) clientConnection = server->GetConnections().begin()->second;

		// Stop accepting any further connections.
//		server->SetAcceptNewConnections(false);

		RunChat(clientConnection);
	}

	void RunClient(const char *address, unsigned short port, SocketTransportLayer transport)
	{
		connection = network.Connect(address, port, transport, 0);
		if (!connection)
		{
			cout << "Unable to connect to " << address << ":" << port << "." << endl;
			return;
		}

		cout << "Waiting for connection.." << endl;
		bool success = connection->WaitToEstablishConnection();
		if (!success)
		{
			cout << "Failed to connect to server!" << endl;
			return;
		}

		cout << "Connected to " << connection->GetSocket()->ToString() << "." << endl;

		RunChat(connection);
	}

	void OnChatMessageReceived(MessageConnection *connection, const char *message, int numBytes)
	{
		char str[1025] = {};
		strncpy(str, message, numBytes-1); // '-1' to take into account the null byte in the message.
		// Note: We can't assume the sender sent the null byte in the message, it might be an ill-crafted message!
		if (inputText.length() > 0)
			cout << endl;
		cout << connection->RemoteEndPoint().ToString() << " says: " << str << endl;
		if (inputText.length() > 0)
			cout << "> " << inputText;

		// If we are the server, make the received message go to all other connected clients as well.
		if (server)
			server->BroadcastMessage(cChatMessageID, true, true, 100, 0, message, numBytes, connection);
	}

	void SendChatMessage(const char *message)
	{
		// Always remember to sanitize data at both ends.
		const unsigned long cMaxMsgSize = 1024;
		if (strlen(message) >= cMaxMsgSize)
			throw NetException("Tried to send too large chat message!");

		const size_t messageLength = strlen(message)+1; // Add one to the length to guarantee a null byte to the stream.
		if (server)
			server->BroadcastMessage(cChatMessageID, true, true, 100, 0, message, messageLength);
		else if (connection && connection->IsWriteOpen())
			connection->SendMessage(cChatMessageID, true, true, 100, 0, message, messageLength);
	}

#ifdef _MSC_VER // On windows, poll for new messages to send from the console instead of blocking.
	void Win32PeekConsoleInput()
	{
		// Get the standard input handle.
		HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
		if (hStdin == INVALID_HANDLE_VALUE)
			throw std::exception("Failed to get stdin handle!");

		// Wait for the events.
		INPUT_RECORD irInBuf[128];
		DWORD numRead = 0;
		if (!PeekConsoleInput(hStdin, irInBuf, 1, &numRead))
			throw std::exception("PeekConsoleInput failed!");
		if (numRead > 0)
		{
			if (!ReadConsoleInput(hStdin, irInBuf, 128, &numRead))
				throw std::exception("ReadConsoleInput failed!");
			for (DWORD i = 0; i < numRead; i++)
				if (irInBuf[i].EventType == KEY_EVENT && irInBuf[i].Event.KeyEvent.bKeyDown == TRUE)
					if (irInBuf[i].Event.KeyEvent.wVirtualKeyCode == VK_RETURN) // Enter key
					{
						if (inputText == "exit" || inputText == "quit" || inputText == "q")
						{
							if (connection)
								connection->Close();
							if (server)
								server->Close(500);
						}
						else if (inputText.length() > 0)
							SendChatMessage(inputText.c_str());
						inputText = "";
						cout << endl;
					}
					else
					{
						char str[2] = {};
						str[0] = irInBuf[i].Event.KeyEvent.uChar.AsciiChar;
						if (str[0] >= 32 && str[0] <= 127)
						{
							if (inputText.length() == 0)
								cout << "> ";
							cout << str[0]; // Echo the character we inputted back to console (yes, there might be a flag for this)
							inputText += std::string(str);
						}
					}
		}
	}
#endif

	void RunChat(Ptr(MessageConnection) connection)
	{
#ifdef _MSC_VER
		// Get the standard input handle.
		HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
		if (hStdin == INVALID_HANDLE_VALUE)
			throw std::exception("Failed to get stdin handle!");

		// Save the current input mode, to be restored on exit.
		DWORD oldInputMode;
		if (!GetConsoleMode(hStdin, &oldInputMode))
			throw std::exception("GetConsoleMode failed!");

		// Enable the window and mouse input events.
		if (!SetConsoleMode(hStdin, ENABLE_WINDOW_INPUT))
			throw std::exception("SetConsoleMode failed!");
#endif

		cout << "Chat running. Type messages and send them by pressing Enter. Type 'q'/'exit'/'quit' to disconnect." << endl;

		while((server && server->GetConnections().size() > 0) || (connection && connection->IsReadOpen()))
		{
			if (server)
				server->Process();

			if (!connection->IsReadOpen())
				connection->Disconnect();

			for(int i = 0; i < 100; ++i) // Process a maximum of 100 messages at one go.
			{
				NetworkMessage *msg = connection->ReceiveMessage(50);
				if (!msg)
					break;

				if (msg->id == cChatMessageID && msg->Size() > 0)
					OnChatMessageReceived(connection, &msg->data[0], msg->Size());
				connection->FreeMessage(msg);
			}

#ifdef _MSC_VER
			Win32PeekConsoleInput();
#else
			char inputText[256] = {};
			cout << "Enter a text to say: ";
			cin.getline(inputText, 255, '\n');
			if (strlen(inputText) > 0)
			{
				if (!strcmp(inputText, "quit") || !strcmp(inputText, "exit") || !strcmp(inputText, "q"))
					connection->Close();
				else
					SendChatMessage(inputText);
			}
#endif
			// Nothing in the above sleeps or blocks to wait for any events. Sleep() to keep the CPU use down.
			kNet::Clock::Sleep(1);
		}
		cout << "Disconnected." << endl;
	}
};

void PrintUsage()
{
	cout << "Usage: " << endl;
	cout << "       tcp|udp server port" << endl;
	cout << "       tcp|udp client hostname port" << endl;
}

BottomMemoryAllocator bma;

int main(int argc, char **argv)
{
	if (argc < 4)
	{
		PrintUsage();
		return 0;
	}

	kNet::SetLogChannels(LogUser | LogInfo | LogError);

	EnableMemoryLeakLoggingAtExit();

	SocketTransportLayer transport = StringToSocketTransportLayer(argv[1]);
	if (transport == InvalidTransportLayer)
	{
		cout << "The first parameter is either 'tcp' or 'udp'!" << endl;
		return 0;
	}
	NetworkApp app;
	if (!_stricmp(argv[2], "server"))
	{
		unsigned short port = (unsigned short)atoi(argv[3]);

		app.RunServer(port, transport);
	}
	else if (!_stricmp(argv[2], "client"))
	{
		if (argc < 5)
		{
			PrintUsage();
			return 0;
		}

		unsigned short port = (unsigned short)atoi(argv[4]);
		app.RunClient(argv[3], port, transport);
	}
	else
	{
		cout << "The second parameter is either 'server' or 'client'!" << endl;
		return 0;
	}
}<commit_msg>Fix bad signature in overriding virtual function in SimpleChat sample.<commit_after>/* Copyright The kNet Project.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

/** @file SimpleChat.cpp
	@brief */

#include <iostream>
#include <string>

#include "kNet.h"
#include "kNet/DebugMemoryLeakCheck.h"

//#undef _MSC_VER

using namespace std;
using namespace kNet;

const unsigned long cChatMessageID = 42;

class NetworkApp : public INetworkServerListener, public IMessageHandler
{
	Network network;
	// If we are the server, this pointer will be nonzero.
	NetworkServer *server;
	// If we are the client, this pointer will be nonzero.
	Ptr(MessageConnection) connection;

	// Will contain the chat message as it is being typed on the command line.
	std::string inputText;

public:
	NetworkApp()
	:server(0)
	{
	}

	// The server must implement this message.
	bool NewConnectionAttempt(const EndPoint & UNUSED(endPoint), const char * UNUSED(data), size_t UNUSED(numBytes))
	{
		// Allow the client to connect.
		return true;
	}

	/// Called to notify the listener that a new connection has been established.
	void NewConnectionEstablished(MessageConnection *connection)
	{
		cout << "New connection from " << connection->ToString() << "." << endl;
		connection->RegisterInboundMessageHandler(this);
	}

	void HandleMessage(MessageConnection *source, packet_id_t /*packetId*/, message_id_t messageId, const char *data, size_t numBytes)
	{
		if (messageId == cChatMessageID)
			OnChatMessageReceived(source, data, numBytes);
	}

	void RunServer(unsigned short port, SocketTransportLayer transport)
	{
		// Start the server either in TCP or UDP mode.
		server = network.StartServer(port, transport, this, true);
		if (!server)
		{
			cout << "Unable to start server in port " << port << "!" << endl;
			return;
		}

		cout << "Server waiting for connection in port " << port << "." << endl;

		while(server->GetConnections().size() == 0)
		{
			server->Process();
			Clock::Sleep(100);
		}

		Ptr(MessageConnection) clientConnection = server->GetConnections().begin()->second;

		// Stop accepting any further connections.
//		server->SetAcceptNewConnections(false);

		RunChat(clientConnection);
	}

	void RunClient(const char *address, unsigned short port, SocketTransportLayer transport)
	{
		connection = network.Connect(address, port, transport, 0);
		if (!connection)
		{
			cout << "Unable to connect to " << address << ":" << port << "." << endl;
			return;
		}

		cout << "Waiting for connection.." << endl;
		bool success = connection->WaitToEstablishConnection();
		if (!success)
		{
			cout << "Failed to connect to server!" << endl;
			return;
		}

		cout << "Connected to " << connection->GetSocket()->ToString() << "." << endl;

		RunChat(connection);
	}

	void OnChatMessageReceived(MessageConnection *connection, const char *message, int numBytes)
	{
		char str[1025] = {};
		strncpy(str, message, numBytes-1); // '-1' to take into account the null byte in the message.
		// Note: We can't assume the sender sent the null byte in the message, it might be an ill-crafted message!
		if (inputText.length() > 0)
			cout << endl;
		cout << connection->RemoteEndPoint().ToString() << " says: " << str << endl;
		if (inputText.length() > 0)
			cout << "> " << inputText;

		// If we are the server, make the received message go to all other connected clients as well.
		if (server)
			server->BroadcastMessage(cChatMessageID, true, true, 100, 0, message, numBytes, connection);
	}

	void SendChatMessage(const char *message)
	{
		// Always remember to sanitize data at both ends.
		const unsigned long cMaxMsgSize = 1024;
		if (strlen(message) >= cMaxMsgSize)
			throw NetException("Tried to send too large chat message!");

		const size_t messageLength = strlen(message)+1; // Add one to the length to guarantee a null byte to the stream.
		if (server)
			server->BroadcastMessage(cChatMessageID, true, true, 100, 0, message, messageLength);
		else if (connection && connection->IsWriteOpen())
			connection->SendMessage(cChatMessageID, true, true, 100, 0, message, messageLength);
	}

#ifdef _MSC_VER // On windows, poll for new messages to send from the console instead of blocking.
	void Win32PeekConsoleInput()
	{
		// Get the standard input handle.
		HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
		if (hStdin == INVALID_HANDLE_VALUE)
			throw std::exception("Failed to get stdin handle!");

		// Wait for the events.
		INPUT_RECORD irInBuf[128];
		DWORD numRead = 0;
		if (!PeekConsoleInput(hStdin, irInBuf, 1, &numRead))
			throw std::exception("PeekConsoleInput failed!");
		if (numRead > 0)
		{
			if (!ReadConsoleInput(hStdin, irInBuf, 128, &numRead))
				throw std::exception("ReadConsoleInput failed!");
			for (DWORD i = 0; i < numRead; i++)
				if (irInBuf[i].EventType == KEY_EVENT && irInBuf[i].Event.KeyEvent.bKeyDown == TRUE)
					if (irInBuf[i].Event.KeyEvent.wVirtualKeyCode == VK_RETURN) // Enter key
					{
						if (inputText == "exit" || inputText == "quit" || inputText == "q")
						{
							if (connection)
								connection->Close();
							if (server)
								server->Close(500);
						}
						else if (inputText.length() > 0)
							SendChatMessage(inputText.c_str());
						inputText = "";
						cout << endl;
					}
					else
					{
						char str[2] = {};
						str[0] = irInBuf[i].Event.KeyEvent.uChar.AsciiChar;
						if (str[0] >= 32 && str[0] <= 127)
						{
							if (inputText.length() == 0)
								cout << "> ";
							cout << str[0]; // Echo the character we inputted back to console (yes, there might be a flag for this)
							inputText += std::string(str);
						}
					}
		}
	}
#endif

	void RunChat(Ptr(MessageConnection) connection)
	{
#ifdef _MSC_VER
		// Get the standard input handle.
		HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
		if (hStdin == INVALID_HANDLE_VALUE)
			throw std::exception("Failed to get stdin handle!");

		// Save the current input mode, to be restored on exit.
		DWORD oldInputMode;
		if (!GetConsoleMode(hStdin, &oldInputMode))
			throw std::exception("GetConsoleMode failed!");

		// Enable the window and mouse input events.
		if (!SetConsoleMode(hStdin, ENABLE_WINDOW_INPUT))
			throw std::exception("SetConsoleMode failed!");
#endif

		cout << "Chat running. Type messages and send them by pressing Enter. Type 'q'/'exit'/'quit' to disconnect." << endl;

		while((server && server->GetConnections().size() > 0) || (connection && connection->IsReadOpen()))
		{
			if (server)
				server->Process();

			if (!connection->IsReadOpen())
				connection->Disconnect();

			for(int i = 0; i < 100; ++i) // Process a maximum of 100 messages at one go.
			{
				NetworkMessage *msg = connection->ReceiveMessage(50);
				if (!msg)
					break;

				if (msg->id == cChatMessageID && msg->Size() > 0)
					OnChatMessageReceived(connection, &msg->data[0], msg->Size());
				connection->FreeMessage(msg);
			}

#ifdef _MSC_VER
			Win32PeekConsoleInput();
#else
			char inputText[256] = {};
			cout << "Enter a text to say: ";
			cin.getline(inputText, 255, '\n');
			if (strlen(inputText) > 0)
			{
				if (!strcmp(inputText, "quit") || !strcmp(inputText, "exit") || !strcmp(inputText, "q"))
					connection->Close();
				else
					SendChatMessage(inputText);
			}
#endif
			// Nothing in the above sleeps or blocks to wait for any events. Sleep() to keep the CPU use down.
			kNet::Clock::Sleep(1);
		}
		cout << "Disconnected." << endl;
	}
};

void PrintUsage()
{
	cout << "Usage: " << endl;
	cout << "       tcp|udp server port" << endl;
	cout << "       tcp|udp client hostname port" << endl;
}

BottomMemoryAllocator bma;

int main(int argc, char **argv)
{
	if (argc < 4)
	{
		PrintUsage();
		return 0;
	}

	kNet::SetLogChannels(LogUser | LogInfo | LogError);

	EnableMemoryLeakLoggingAtExit();

	SocketTransportLayer transport = StringToSocketTransportLayer(argv[1]);
	if (transport == InvalidTransportLayer)
	{
		cout << "The first parameter is either 'tcp' or 'udp'!" << endl;
		return 0;
	}
	NetworkApp app;
	if (!_stricmp(argv[2], "server"))
	{
		unsigned short port = (unsigned short)atoi(argv[3]);

		app.RunServer(port, transport);
	}
	else if (!_stricmp(argv[2], "client"))
	{
		if (argc < 5)
		{
			PrintUsage();
			return 0;
		}

		unsigned short port = (unsigned short)atoi(argv[4]);
		app.RunClient(argv[3], port, transport);
	}
	else
	{
		cout << "The second parameter is either 'server' or 'client'!" << endl;
		return 0;
	}
}<|endoftext|>


<commit_before>// Copyright (c) 2011-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "navcoinunits.h"

#include "primitives/transaction.h"
#include "util.h"

#include <QStringList>
#include <QSettings>

NavCoinUnits::NavCoinUnits(QObject *parent):
        QAbstractListModel(parent),
        unitlist(availableUnits())
{
}

QList<NavCoinUnits::Unit> NavCoinUnits::availableUnits()
{
    QList<NavCoinUnits::Unit> unitlist;
    unitlist.append(NAV);
    unitlist.append(mNAV);
    unitlist.append(uNAV);
    unitlist.append(BTC);
    unitlist.append(EUR);
    unitlist.append(USD);
    return unitlist;
}

bool NavCoinUnits::valid(int unit)
{
    switch(unit)
    {
    case NAV:
    case mNAV:
    case uNAV:
    case BTC:
    case EUR:
    case USD:
        return true;
    default:
        return false;
    }
}

QString NavCoinUnits::name(int unit)
{
    switch(unit)
    {
    case NAV: return QString("NAV");
    case mNAV: return QString("mNAV");
    case uNAV: return QString::fromUtf8("μNAV");
    case BTC: return QString::fromUtf8("BTC");
    case EUR: return QString::fromUtf8("EUR");
    case USD: return QString::fromUtf8("USD");
    default: return QString("???");
    }
}

QString NavCoinUnits::description(int unit)
{
    switch(unit)
    {
    case NAV: return QString("NavCoins");
    case mNAV: return QString("Milli-NavCoins (1 / 1" THIN_SP_UTF8 "000)");
    case uNAV: return QString("Micro-NavCoins (1 / 1" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
    case BTC: return QString("BTC");
    case EUR: return QString("Euro");
    case USD: return QString("US Dolar");
    default: return QString("???");
    }
}

qint64 NavCoinUnits::factor(int unit)
{

    QSettings settings;

    switch(unit)
    {
    case NAV:  return 100000000;
    case mNAV: return 100000;
    case uNAV: return 100;
    case BTC:  return settings.value("btcFactor", 0).toFloat();
    case EUR:  return settings.value("eurFactor", 0).toFloat();
    case USD:  return settings.value("usdFactor", 0).toFloat();
    default:   return 100000000;
    }
}

int NavCoinUnits::decimals(int unit)
{
    switch(unit)
    {
    case NAV: return 8;
    case mNAV: return 5;
    case uNAV: return 2;
    case BTC: return 8;
    case EUR: return 2;
    case USD: return 2;
    default: return 0;
    }
}

QString NavCoinUnits::format(int unit, const CAmount& nIn, bool fPlus, SeparatorStyle separators)
{
    // Note: not using straight sprintf here because we do NOT want
    // localized number formatting.
    if(!valid(unit))
        return QString(); // Refuse to format invalid unit
    qint64 n = (qint64)nIn;
    qint64 coin = factor(unit);
    int num_decimals = decimals(unit);
    qint64 n_abs = (n > 0 ? n : -n);
    qint64 quotient;
    qint64 remainder;

    quotient = n_abs / coin;
    remainder = n_abs % coin;
    QString quotient_str = QString::number(quotient);
    QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0');

    // Use SI-style thin space separators as these are locale independent and can't be
    // confused with the decimal marker.
    QChar thin_sp(THIN_SP_CP);
    int q_size = quotient_str.size();
    if (separators == separatorAlways || (separators == separatorStandard && q_size > 4))
        for (int i = 3; i < q_size; i += 3)
            quotient_str.insert(q_size - i, thin_sp);

    if (n < 0)
        quotient_str.insert(0, '-');
    else if (fPlus && n > 0)
        quotient_str.insert(0, '+');
    return quotient_str + QString(".") + remainder_str;
}

// NOTE: Using formatWithUnit in an HTML context risks wrapping
// quantities at the thousands separator. More subtly, it also results
// in a standard space rather than a thin space, due to a bug in Qt's
// XML whitespace canonicalisation
//
// Please take care to use formatHtmlWithUnit instead, when
// appropriate.

QString NavCoinUnits::formatWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
{
    return format(unit, amount, plussign, separators) + QString(" ") + name(unit);
}

QString NavCoinUnits::formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
{
    QString str(formatWithUnit(unit, amount, plussign, separators));
    str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML));
    return QString("%1").arg(str);
}

bool NavCoinUnits::parse(int unit, const QString &value, CAmount *val_out)
{
    if(!valid(unit) || value.isEmpty())
        return false; // Refuse to parse invalid unit or empty string
    int num_decimals = decimals(unit);

    // Ignore spaces and thin spaces when parsing
    QStringList parts = removeSpaces(value).split(".");

    if(parts.size() > 2)
    {
        return false; // More than one dot
    }
    QString whole = parts[0];
    QString decimals;

    if(parts.size() > 1)
    {
        decimals = parts[1];
    }
    if(decimals.size() > num_decimals)
    {
        return false; // Exceeds max precision
    }
    bool ok = false;
    QString str = whole + decimals.leftJustified(num_decimals, '0');

    if(str.size() > 18)
    {
        return false; // Longer numbers will exceed 63 bits
    }
    CAmount retvalue(str.toLongLong(&ok));
    if(val_out)
    {
        *val_out = retvalue;
    }
    return ok;
}

QString NavCoinUnits::getAmountColumnTitle(int unit)
{
    QString amountTitle = QObject::tr("Amount");
    if (NavCoinUnits::valid(unit))
    {
        amountTitle += " ("+NavCoinUnits::name(unit) + ")";
    }
    return amountTitle;
}

int NavCoinUnits::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return unitlist.size();
}

QVariant NavCoinUnits::data(const QModelIndex &index, int role) const
{
    int row = index.row();
    if(row >= 0 && row < unitlist.size())
    {
        Unit unit = unitlist.at(row);
        switch(role)
        {
        case Qt::EditRole:
        case Qt::DisplayRole:
            return QVariant(name(unit));
        case Qt::ToolTipRole:
            return QVariant(description(unit));
        case UnitRole:
            return QVariant(static_cast<int>(unit));
        }
    }
    return QVariant();
}

CAmount NavCoinUnits::maxMoney()
{
    return MAX_MONEY;
}
<commit_msg>gui: fixed conversion to fiat for little amounts<commit_after>// Copyright (c) 2011-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "navcoinunits.h"

#include "primitives/transaction.h"
#include "util.h"

#include <math.h>

#include <QStringList>
#include <QSettings>

NavCoinUnits::NavCoinUnits(QObject *parent):
        QAbstractListModel(parent),
        unitlist(availableUnits())
{
}

QList<NavCoinUnits::Unit> NavCoinUnits::availableUnits()
{
    QList<NavCoinUnits::Unit> unitlist;
    unitlist.append(NAV);
    unitlist.append(mNAV);
    unitlist.append(uNAV);
    unitlist.append(BTC);
    unitlist.append(EUR);
    unitlist.append(USD);
    return unitlist;
}

bool NavCoinUnits::valid(int unit)
{
    switch(unit)
    {
    case NAV:
    case mNAV:
    case uNAV:
    case BTC:
    case EUR:
    case USD:
        return true;
    default:
        return false;
    }
}

QString NavCoinUnits::name(int unit)
{
    switch(unit)
    {
    case NAV: return QString("NAV");
    case mNAV: return QString("mNAV");
    case uNAV: return QString::fromUtf8("μNAV");
    case BTC: return QString::fromUtf8("BTC");
    case EUR: return QString::fromUtf8("EUR");
    case USD: return QString::fromUtf8("USD");
    default: return QString("???");
    }
}

QString NavCoinUnits::description(int unit)
{
    switch(unit)
    {
    case NAV: return QString("NavCoins");
    case mNAV: return QString("Milli-NavCoins (1 / 1" THIN_SP_UTF8 "000)");
    case uNAV: return QString("Micro-NavCoins (1 / 1" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
    case BTC: return QString("BTC");
    case EUR: return QString("Euro");
    case USD: return QString("US Dolar");
    default: return QString("???");
    }
}

qint64 NavCoinUnits::factor(int unit)
{

    QSettings settings;

    switch(unit)
    {
    case NAV:  return 100000000;
    case mNAV: return 100000;
    case uNAV: return 100;
    case BTC:  return settings.value("btcFactor", 0).toFloat();
    case EUR:  return settings.value("eurFactor", 0).toFloat();
    case USD:  return settings.value("usdFactor", 0).toFloat();
    default:   return 100000000;
    }
}

int NavCoinUnits::decimals(int unit)
{
    switch(unit)
    {
    case NAV: return 8;
    case mNAV: return 5;
    case uNAV: return 2;
    case BTC: return 8;
    case EUR: return 6;
    case USD: return 6;
    default: return 0;
    }
}

QString NavCoinUnits::format(int unit, const CAmount& nIn, bool fPlus, SeparatorStyle separators)
{
    // Note: not using straight sprintf here because we do NOT want
    // localized number formatting.
    if(!valid(unit))
        return QString(); // Refuse to format invalid unit
    qint64 n = (qint64)nIn;
    qint64 coin = factor(unit);
    int num_decimals = decimals(unit);
    qint64 n_abs = (n > 0 ? n : -n);
    double quotient;
    qint64 remainder;

    if(n < coin)
    {
      double q;
      double r = modf((double)n_abs / (double)coin, &q);
      quotient = q;
      remainder = r * (double)pow(10,num_decimals);
    }
    else
    {
      quotient = n_abs / coin;
      double q;
      double r = modf((double)n_abs / (double)coin, &q);
      remainder = r * (double)pow(10,num_decimals);
    }

    QString quotient_str = QString::number((qint64)quotient);
    QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0');

    // Use SI-style thin space separators as these are locale independent and can't be
    // confused with the decimal marker.
    QChar thin_sp(THIN_SP_CP);
    int q_size = quotient_str.size();
    if (separators == separatorAlways || (separators == separatorStandard && q_size > 4))
        for (int i = 3; i < q_size; i += 3)
            quotient_str.insert(q_size - i, thin_sp);

    if (n < 0)
        quotient_str.insert(0, '-');
    else if (fPlus && n > 0)
        quotient_str.insert(0, '+');

    return quotient_str + QString(".") + remainder_str;
}

// NOTE: Using formatWithUnit in an HTML context risks wrapping
// quantities at the thousands separator. More subtly, it also results
// in a standard space rather than a thin space, due to a bug in Qt's
// XML whitespace canonicalisation
//
// Please take care to use formatHtmlWithUnit instead, when
// appropriate.

QString NavCoinUnits::formatWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
{
    return format(unit, amount, plussign, separators) + QString(" ") + name(unit);
}

QString NavCoinUnits::formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
{
    QString str(formatWithUnit(unit, amount, plussign, separators));
    str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML));
    return QString("%1").arg(str);
}

bool NavCoinUnits::parse(int unit, const QString &value, CAmount *val_out)
{
    if(!valid(unit) || value.isEmpty())
        return false; // Refuse to parse invalid unit or empty string
    int num_decimals = decimals(unit);

    // Ignore spaces and thin spaces when parsing
    QStringList parts = removeSpaces(value).split(".");

    if(parts.size() > 2)
    {
        return false; // More than one dot
    }
    QString whole = parts[0];
    QString decimals;

    if(parts.size() > 1)
    {
        decimals = parts[1];
    }
    if(decimals.size() > num_decimals)
    {
        return false; // Exceeds max precision
    }
    bool ok = false;
    QString str = whole + decimals.leftJustified(num_decimals, '0');

    if(str.size() > 18)
    {
        return false; // Longer numbers will exceed 63 bits
    }
    CAmount retvalue(str.toLongLong(&ok));
    if(val_out)
    {
        *val_out = retvalue;
    }
    return ok;
}

QString NavCoinUnits::getAmountColumnTitle(int unit)
{
    QString amountTitle = QObject::tr("Amount");
    if (NavCoinUnits::valid(unit))
    {
        amountTitle += " ("+NavCoinUnits::name(unit) + ")";
    }
    return amountTitle;
}

int NavCoinUnits::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return unitlist.size();
}

QVariant NavCoinUnits::data(const QModelIndex &index, int role) const
{
    int row = index.row();
    if(row >= 0 && row < unitlist.size())
    {
        Unit unit = unitlist.at(row);
        switch(role)
        {
        case Qt::EditRole:
        case Qt::DisplayRole:
            return QVariant(name(unit));
        case Qt::ToolTipRole:
            return QVariant(description(unit));
        case UnitRole:
            return QVariant(static_cast<int>(unit));
        }
    }
    return QVariant();
}

CAmount NavCoinUnits::maxMoney()
{
    return MAX_MONEY;
}
<|endoftext|>


<commit_before>#include "overviewpage.h"
#include "ui_overviewpage.h"

#include "init.h"
#include "clientmodel.h"
#include "walletmodel.h"
#include "bitcoinunits.h"
#include "optionsmodel.h"
#include "transactiontablemodel.h"
#include "transactionfilterproxy.h"
#include "guiutil.h"
#include "guiconstants.h"

#include <QAbstractItemDelegate>
#include <QPainter>
#include <QTimer>

#define DECORATION_SIZE 64
#define NUM_ITEMS 3

class TxViewDelegate : public QAbstractItemDelegate
{
    Q_OBJECT
public:
    TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC)
    {

    }

    inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
                      const QModelIndex &index ) const
    {
        painter->save();

        QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
        QRect mainRect = option.rect;
        QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE));
        int xspace = DECORATION_SIZE + 8;
        int ypad = 6;
        int halfheight = (mainRect.height() - 2*ypad)/2;
        QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight);
        QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
        icon.paint(painter, decorationRect);

        QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
        QString address = index.data(Qt::DisplayRole).toString();
        qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong();
        bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool();
        QVariant value = index.data(Qt::ForegroundRole);
        QColor foreground = option.palette.color(QPalette::Text);
        if(value.canConvert<QBrush>())
        {
            QBrush brush = qvariant_cast<QBrush>(value);
            foreground = brush.color();
        }

        painter->setPen(foreground);
        painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address);

        if(amount < 0)
        {
            foreground = COLOR_NEGATIVE;
        }
        else if(!confirmed)
        {
            foreground = COLOR_UNCONFIRMED;
        }
        else
        {
            foreground = option.palette.color(QPalette::Text);
        }
        painter->setPen(foreground);
        QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true);
        if(!confirmed)
        {
            amountText = QString("[") + amountText + QString("]");
        }
        painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText);

        painter->setPen(option.palette.color(QPalette::Text));
        painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date));

        painter->restore();
    }

    inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        return QSize(DECORATION_SIZE, DECORATION_SIZE);
    }

    int unit;

};
#include "overviewpage.moc"

OverviewPage::OverviewPage(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::OverviewPage),
    clientModel(0),
    walletModel(0),
    currentBalance(-1),
    currentUnconfirmedBalance(-1),
    currentImmatureBalance(-1),
    txdelegate(new TxViewDelegate()),
    filter(0)
{
    ui->setupUi(this);

    // Recent transactions
    ui->listTransactions->setItemDelegate(txdelegate);
    ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
    ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
    ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);

    connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex)));

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(darkSendStatus()));
    timer->start(333);

    // init "out of sync" warning labels
    ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");
    ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")");

    showingDarkSendMessage = 0;
    darksendActionCheck = 0;

    // start with displaying the "out of sync" warnings
    showOutOfSyncWarning(true);
}

void OverviewPage::handleTransactionClicked(const QModelIndex &index)
{
    if(filter)
        emit transactionClicked(filter->mapToSource(index));
}

OverviewPage::~OverviewPage()
{
    delete ui;
}

void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, qint64 anonymizedBalance)
{
    int unit = walletModel->getOptionsModel()->getDisplayUnit();
    currentBalance = balance;
    currentUnconfirmedBalance = unconfirmedBalance;
    currentImmatureBalance = immatureBalance;
    currentAnonymizedBalance = anonymizedBalance;
    ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance));
    ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance));
    ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance));
    ui->labelAnonymized->setText(BitcoinUnits::formatWithUnit(unit, anonymizedBalance));

    // only show immature (newly mined) balance if it's non-zero, so as not to complicate things
    // for the non-mining users
    bool showImmature = immatureBalance != 0;
    ui->labelImmature->setVisible(showImmature);
    ui->labelImmatureText->setVisible(showImmature);
}

void OverviewPage::setClientModel(ClientModel *model)
{
    this->clientModel = model;
    if(model)
    {
        // Show warning if this is a prerelease version
        connect(model, SIGNAL(alertsChanged(QString)), this, SLOT(updateAlerts(QString)));
        updateAlerts(model->getStatusBarWarnings());
    }
}

void OverviewPage::setWalletModel(WalletModel *model)
{
    this->walletModel = model;
    if(model && model->getOptionsModel())
    {
        // Set up transaction list
        filter = new TransactionFilterProxy();
        filter->setSourceModel(model->getTransactionTableModel());
        filter->setLimit(NUM_ITEMS);
        filter->setDynamicSortFilter(true);
        filter->setSortRole(Qt::EditRole);
        filter->sort(TransactionTableModel::Status, Qt::DescendingOrder);

        ui->listTransactions->setModel(filter);
        ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);

        // Keep up to date with wallet
        setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getAnonymizedBalance());
        connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64)));

        connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
    }

    // update the display unit, to not use the default ("BTC")
    updateDisplayUnit();
}

void OverviewPage::updateDisplayUnit()
{
    if(walletModel && walletModel->getOptionsModel())
    {
        if(currentBalance != -1)
            setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance, currentAnonymizedBalance);

        // Update txdelegate->unit with the current unit
        txdelegate->unit = walletModel->getOptionsModel()->getDisplayUnit();

        ui->listTransactions->update();
    }
}

void OverviewPage::updateAlerts(const QString &warnings)
{
    this->ui->labelAlerts->setVisible(!warnings.isEmpty());
    this->ui->labelAlerts->setText(warnings);
}

void OverviewPage::showOutOfSyncWarning(bool fShow)
{
    ui->labelWalletStatus->setVisible(fShow);
    ui->labelTransactionsStatus->setVisible(fShow);
}

void OverviewPage::darkSendStatus()
{
    if(fDisableDarksend) {
        if(nBestHeight != cachedNumBlocks)
        {
            cachedNumBlocks = nBestHeight;

            ui->darksendEnabled->setText("Disabled");
            ui->darksendStatus->setText("");

            std::ostringstream convert;
            convert << pwalletMain->GetAverageAnonymizedRounds() << "/" << nDarksendRounds;
            QString s(convert.str().c_str());
            ui->darksendAvgRounds->setText(s);
        }

        return;
    }

    // check darksend status and unlock if needed
    if(nBestHeight != cachedNumBlocks)
    {
        // Balance and number of transactions might have changed
        cachedNumBlocks = nBestHeight;

        if (pwalletMain->GetBalance() - pwalletMain->GetAnonymizedBalance() > 2*COIN){
            if (walletModel->getEncryptionStatus() != WalletModel::Unencrypted){
                if((nAnonymizeDarkcoinAmount*COIN)-pwalletMain->GetAnonymizedBalance() > 1.1*COIN && walletModel->getEncryptionStatus() == WalletModel::Locked){
                    WalletModel::UnlockContext ctx(walletModel->requestUnlock());
                    if(!ctx.isValid()){
                        //unlock was cancelled
                        fDisableDarksend = true;
                        LogPrintf("Wallet is locked and user declined to unlock. Disabling Darksend.\n");
                    }
                }
                if((nAnonymizeDarkcoinAmount*COIN)-pwalletMain->GetAnonymizedBalance() <= 1.1*COIN &&
                    walletModel->getEncryptionStatus() == WalletModel::Unlocked &&
                    darkSendPool.GetMyTransactionCount() == 0){
                    LogPrintf("Darksend is complete, locking wallet.\n");
                    walletModel->Lock();
                }
            }
        }

        ui->darksendEnabled->setText("Enabled");

        std::ostringstream convert;
        convert << pwalletMain->GetAverageAnonymizedRounds() << "/" << nDarksendRounds;
        QString s(convert.str().c_str());
        ui->darksendAvgRounds->setText(s);

    }

    //if(!darkSendPool.sessionFoundMasternode) return;

    int state = darkSendPool.GetState();
    int entries = darkSendPool.GetEntriesCount();
    int accepted = darkSendPool.GetLastEntryAccepted();
    //int countAccepted = darkSendPool.GetCountEntriesAccepted();

    std::ostringstream convert;

    if(state == POOL_STATUS_ACCEPTING_ENTRIES) {
        if(entries == 0) {
            convert << "darkSend Status => Idle";
            showingDarkSendMessage = 0;
        } else if (accepted == 1) {
            convert << "darkSend Status => Your transaction was accepted into the pool!";
            if(showingDarkSendMessage % 10 > 8) {
                darkSendPool.lastEntryAccepted = 0;
                showingDarkSendMessage = 0;
            }
        } else {
            if(showingDarkSendMessage % 70 <= 40) convert << "darkSend Status => ( Entries " << entries << "/" << POOL_MAX_TRANSACTIONS << " )";
            else if(showingDarkSendMessage % 70 <= 50) convert << "darkSend Status => Waiting for more entries (" << entries << "/" << POOL_MAX_TRANSACTIONS << " ) .";
            else if(showingDarkSendMessage % 70 <= 60) convert << "darkSend Status => Waiting for more entries (" << entries << "/" << POOL_MAX_TRANSACTIONS << " ) ..";
            else if(showingDarkSendMessage % 70 <= 70) convert << "darkSend Status => Waiting for more entries (" << entries << "/" << POOL_MAX_TRANSACTIONS << " ) ...";
        }
    } else if(state == POOL_STATUS_SIGNING) {
        if(showingDarkSendMessage % 70 <= 10) convert << "darkSend Status => SIGNING";
        else if(showingDarkSendMessage % 70 <= 20) convert << "darkSend Status => SIGNING ( waiting. )";
        else if(showingDarkSendMessage % 70 <= 30) convert << "darkSend Status => SIGNING ( waiting.. )";
        else if(showingDarkSendMessage % 70 <= 40) convert << "darkSend Status => SIGNING ( waiting... )";
    } else if(state == POOL_STATUS_TRANSMISSION) {
        convert << "darkSend Status => TRANSMISSION";
    } else if (state == POOL_STATUS_IDLE) {
        convert << "darkSend Status => POOL_STATUS_IDLE";
    } else if (state == POOL_STATUS_FINALIZE_TRANSACTION) {
        convert << "darkSend Status => POOL_STATUS_FINALIZE_TRANSACTION";
    } else if(state == POOL_STATUS_ERROR) {
        convert << "darkSend Status => ERROR : " << darkSendPool.lastMessage;
    } else if(state == POOL_STATUS_SUCCESS) {
        convert << "darkSend Status => SUCCESS : " << darkSendPool.lastMessage;
    } else {
        convert << "darkSend Status => UNKNOWN STATE : ID=" << state;
    }

    if(state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) darkSendPool.Check();

    QString s(convert.str().c_str());

    if(s != ui->darksendStatus->text())
        LogPrintf("%s\n", convert.str().c_str());

    ui->darksendStatus->setText(s);

    showingDarkSendMessage++;
    darksendActionCheck++;

    // Get DarkSend Denomination Status
}
<commit_msg>changed some text around<commit_after>#include "overviewpage.h"
#include "ui_overviewpage.h"

#include "init.h"
#include "clientmodel.h"
#include "walletmodel.h"
#include "bitcoinunits.h"
#include "optionsmodel.h"
#include "transactiontablemodel.h"
#include "transactionfilterproxy.h"
#include "guiutil.h"
#include "guiconstants.h"

#include <QAbstractItemDelegate>
#include <QPainter>
#include <QTimer>

#define DECORATION_SIZE 64
#define NUM_ITEMS 3

class TxViewDelegate : public QAbstractItemDelegate
{
    Q_OBJECT
public:
    TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC)
    {

    }

    inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
                      const QModelIndex &index ) const
    {
        painter->save();

        QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
        QRect mainRect = option.rect;
        QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE));
        int xspace = DECORATION_SIZE + 8;
        int ypad = 6;
        int halfheight = (mainRect.height() - 2*ypad)/2;
        QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight);
        QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
        icon.paint(painter, decorationRect);

        QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
        QString address = index.data(Qt::DisplayRole).toString();
        qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong();
        bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool();
        QVariant value = index.data(Qt::ForegroundRole);
        QColor foreground = option.palette.color(QPalette::Text);
        if(value.canConvert<QBrush>())
        {
            QBrush brush = qvariant_cast<QBrush>(value);
            foreground = brush.color();
        }

        painter->setPen(foreground);
        painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address);

        if(amount < 0)
        {
            foreground = COLOR_NEGATIVE;
        }
        else if(!confirmed)
        {
            foreground = COLOR_UNCONFIRMED;
        }
        else
        {
            foreground = option.palette.color(QPalette::Text);
        }
        painter->setPen(foreground);
        QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true);
        if(!confirmed)
        {
            amountText = QString("[") + amountText + QString("]");
        }
        painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText);

        painter->setPen(option.palette.color(QPalette::Text));
        painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date));

        painter->restore();
    }

    inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        return QSize(DECORATION_SIZE, DECORATION_SIZE);
    }

    int unit;

};
#include "overviewpage.moc"

OverviewPage::OverviewPage(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::OverviewPage),
    clientModel(0),
    walletModel(0),
    currentBalance(-1),
    currentUnconfirmedBalance(-1),
    currentImmatureBalance(-1),
    txdelegate(new TxViewDelegate()),
    filter(0)
{
    ui->setupUi(this);

    // Recent transactions
    ui->listTransactions->setItemDelegate(txdelegate);
    ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
    ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
    ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);

    connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex)));

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(darkSendStatus()));
    timer->start(333);

    // init "out of sync" warning labels
    ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");
    ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")");

    showingDarkSendMessage = 0;
    darksendActionCheck = 0;

    // start with displaying the "out of sync" warnings
    showOutOfSyncWarning(true);
}

void OverviewPage::handleTransactionClicked(const QModelIndex &index)
{
    if(filter)
        emit transactionClicked(filter->mapToSource(index));
}

OverviewPage::~OverviewPage()
{
    delete ui;
}

void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, qint64 anonymizedBalance)
{
    int unit = walletModel->getOptionsModel()->getDisplayUnit();
    currentBalance = balance;
    currentUnconfirmedBalance = unconfirmedBalance;
    currentImmatureBalance = immatureBalance;
    currentAnonymizedBalance = anonymizedBalance;
    ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance));
    ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance));
    ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance));
    ui->labelAnonymized->setText(BitcoinUnits::formatWithUnit(unit, anonymizedBalance));

    // only show immature (newly mined) balance if it's non-zero, so as not to complicate things
    // for the non-mining users
    bool showImmature = immatureBalance != 0;
    ui->labelImmature->setVisible(showImmature);
    ui->labelImmatureText->setVisible(showImmature);
}

void OverviewPage::setClientModel(ClientModel *model)
{
    this->clientModel = model;
    if(model)
    {
        // Show warning if this is a prerelease version
        connect(model, SIGNAL(alertsChanged(QString)), this, SLOT(updateAlerts(QString)));
        updateAlerts(model->getStatusBarWarnings());
    }
}

void OverviewPage::setWalletModel(WalletModel *model)
{
    this->walletModel = model;
    if(model && model->getOptionsModel())
    {
        // Set up transaction list
        filter = new TransactionFilterProxy();
        filter->setSourceModel(model->getTransactionTableModel());
        filter->setLimit(NUM_ITEMS);
        filter->setDynamicSortFilter(true);
        filter->setSortRole(Qt::EditRole);
        filter->sort(TransactionTableModel::Status, Qt::DescendingOrder);

        ui->listTransactions->setModel(filter);
        ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);

        // Keep up to date with wallet
        setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getAnonymizedBalance());
        connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64)));

        connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
    }

    // update the display unit, to not use the default ("BTC")
    updateDisplayUnit();
}

void OverviewPage::updateDisplayUnit()
{
    if(walletModel && walletModel->getOptionsModel())
    {
        if(currentBalance != -1)
            setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance, currentAnonymizedBalance);

        // Update txdelegate->unit with the current unit
        txdelegate->unit = walletModel->getOptionsModel()->getDisplayUnit();

        ui->listTransactions->update();
    }
}

void OverviewPage::updateAlerts(const QString &warnings)
{
    this->ui->labelAlerts->setVisible(!warnings.isEmpty());
    this->ui->labelAlerts->setText(warnings);
}

void OverviewPage::showOutOfSyncWarning(bool fShow)
{
    ui->labelWalletStatus->setVisible(fShow);
    ui->labelTransactionsStatus->setVisible(fShow);
}

void OverviewPage::darkSendStatus()
{
    if(fDisableDarksend) {
        if(nBestHeight != cachedNumBlocks)
        {
            cachedNumBlocks = nBestHeight;

            ui->darksendEnabled->setText("Disabled");
            ui->darksendStatus->setText("");

            std::ostringstream convert;
            convert << pwalletMain->GetAverageAnonymizedRounds() << "/" << nDarksendRounds;
            QString s(convert.str().c_str());
            ui->darksendAvgRounds->setText(s);
        }

        return;
    }

    // check darksend status and unlock if needed
    if(nBestHeight != cachedNumBlocks)
    {
        // Balance and number of transactions might have changed
        cachedNumBlocks = nBestHeight;

        if (pwalletMain->GetBalance() - pwalletMain->GetAnonymizedBalance() > 2*COIN){
            if (walletModel->getEncryptionStatus() != WalletModel::Unencrypted){
                if((nAnonymizeDarkcoinAmount*COIN)-pwalletMain->GetAnonymizedBalance() > 1.1*COIN && walletModel->getEncryptionStatus() == WalletModel::Locked){
                    WalletModel::UnlockContext ctx(walletModel->requestUnlock());
                    if(!ctx.isValid()){
                        //unlock was cancelled
                        fDisableDarksend = true;
                        LogPrintf("Wallet is locked and user declined to unlock. Disabling Darksend.\n");
                    }
                }
                if((nAnonymizeDarkcoinAmount*COIN)-pwalletMain->GetAnonymizedBalance() <= 1.1*COIN &&
                    walletModel->getEncryptionStatus() == WalletModel::Unlocked &&
                    darkSendPool.GetMyTransactionCount() == 0){
                    LogPrintf("Darksend is complete, locking wallet.\n");
                    walletModel->Lock();
                }
            }
        }

        ui->darksendEnabled->setText("Enabled");

        std::ostringstream convert;
        convert << pwalletMain->GetAverageAnonymizedRounds() << "/" << nDarksendRounds;
        QString s(convert.str().c_str());
        ui->darksendAvgRounds->setText(s);

    }

    //if(!darkSendPool.sessionFoundMasternode) return;

    int state = darkSendPool.GetState();
    int entries = darkSendPool.GetEntriesCount();
    int accepted = darkSendPool.GetLastEntryAccepted();
    //int countAccepted = darkSendPool.GetCountEntriesAccepted();

    std::ostringstream convert;

    if(state == POOL_STATUS_ACCEPTING_ENTRIES) {
        if(entries == 0) {
            convert << "Idle";
            showingDarkSendMessage = 0;
        } else if (accepted == 1) {
            convert << "Your transaction was accepted into the pool!";
            if(showingDarkSendMessage % 10 > 8) {
                darkSendPool.lastEntryAccepted = 0;
                showingDarkSendMessage = 0;
            }
        } else {
            if(showingDarkSendMessage % 70 <= 40) convert << "Submitted to masternode => ( Entries " << entries << "/" << POOL_MAX_TRANSACTIONS << " )";
            else if(showingDarkSendMessage % 70 <= 50) convert << "Submitted to masternode => Waiting for more entries (" << entries << "/" << POOL_MAX_TRANSACTIONS << " ) .";
            else if(showingDarkSendMessage % 70 <= 60) convert << "Submitted to masternode => Waiting for more entries (" << entries << "/" << POOL_MAX_TRANSACTIONS << " ) ..";
            else if(showingDarkSendMessage % 70 <= 70) convert << "Submitted to masternode => Waiting for more entries (" << entries << "/" << POOL_MAX_TRANSACTIONS << " ) ...";
        }
    } else if(state == POOL_STATUS_SIGNING) {
        if(showingDarkSendMessage % 70 <= 10) convert << "Found enough users => SIGNING";
        else if(showingDarkSendMessage % 70 <= 20) convert << "Found enough users => SIGNING ( waiting. )";
        else if(showingDarkSendMessage % 70 <= 30) convert << "Found enough users => SIGNING ( waiting.. )";
        else if(showingDarkSendMessage % 70 <= 40) convert << "Found enough users => SIGNING ( waiting... )";
    } else if(state == POOL_STATUS_TRANSMISSION) {
        convert << "Found enough users => TRANSMISSION";
    } else if (state == POOL_STATUS_IDLE) {
        convert << "Found enough users => POOL_STATUS_IDLE";
    } else if (state == POOL_STATUS_FINALIZE_TRANSACTION) {
        convert << "Found enough users => POOL_STATUS_FINALIZE_TRANSACTION";
    } else if(state == POOL_STATUS_ERROR) {
        convert << "Found enough users => ERROR : " << darkSendPool.lastMessage;
    } else if(state == POOL_STATUS_SUCCESS) {
        convert << "Found enough users => SUCCESS : " << darkSendPool.lastMessage;
    } else {
        convert << "Found enough users => UNKNOWN STATE : ID=" << state;
    }

    if(state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) darkSendPool.Check();

    QString s(convert.str().c_str());

    if(s != ui->darksendStatus->text())
        LogPrintf("%s\n", convert.str().c_str());

    ui->darksendStatus->setText(s);

    showingDarkSendMessage++;
    darksendActionCheck++;

    // Get DarkSend Denomination Status
}
<|endoftext|>


<commit_before>#include "guardian.h"
#include "device_setup.h"
#include "prefs_link.h"
#include "ltr_model.h"
#include <cstdio>
#include <QMessageBox>

Guardian::Guardian(QWidget *parent) : parentWidget(parent), mdlType(-1), devType(-1),
  devDesc(QString::fromUtf8(""))
{
}

void Guardian::regTgt(ModelEdit *me)
{
  QObject::connect(me, SIGNAL(modelSelected(int)), this, SLOT(modelSelected(int)));
}

void Guardian::regTgt(DeviceSetup *ds)
{
  QObject::connect(ds, SIGNAL(deviceTypeChanged(int, const QString &)),
                   this, SLOT(deviceTypeChanged(int, const QString &)));
}

void Guardian::checkDeviceNModel()
{
  if((devType == WEBCAM_FT) || (devType == MACWEBCAM_FT)){
    //face tracker needs face model
    if(mdlType != MDL_FACE){
      QMessageBox::warning(parentWidget, QString::fromUtf8("Linuxtrack"),
                           devDesc + QString::fromUtf8(" requires Face type Model!"), QMessageBox::Ok);
    }
  }else if(devType == JOYSTICK){
    //face tracker needs face model
    if(mdlType != MDL_ABSOLUTE){
      QMessageBox::warning(parentWidget, QString::fromUtf8("Linuxtrack"),
                           devDesc + QString::fromUtf8(" requires Absolute type Model!"), QMessageBox::Ok);
    }
  }else{
    //ordinary tracker needs other than face model
    if(mdlType == MDL_FACE){
      QMessageBox::warning(parentWidget, QString::fromUtf8("Linuxtrack"),
                           devDesc + QString::fromUtf8(" won't work correctly with Face type Model!"),
                           QMessageBox::Ok);
    }else if(mdlType == MDL_ABSOLUTE){
      QMessageBox::warning(parentWidget, QString::fromUtf8("Linuxtrack"),
                           devDesc + QString::fromUtf8(" won't work correctly with Absolute type Model!"),
                           QMessageBox::Ok);
    }
  }
}

void Guardian::modelSelected(int modelType)
{
  mdlType = modelType;
  if(devType == -1){
    return;
  }
  checkDeviceNModel();
}

void Guardian::deviceTypeChanged(int deviceType, const QString &desc)
{
  devType = deviceType;
  devDesc = desc;
  if(mdlType == -1){
    return;
  }
  checkDeviceNModel();
}

<commit_msg>Ps3Eye facetracker won't get model warning anymore.<commit_after>#include "guardian.h"
#include "device_setup.h"
#include "prefs_link.h"
#include "ltr_model.h"
#include <cstdio>
#include <QMessageBox>

Guardian::Guardian(QWidget *parent) : parentWidget(parent), mdlType(-1), devType(-1),
  devDesc(QString::fromUtf8(""))
{
}

void Guardian::regTgt(ModelEdit *me)
{
  QObject::connect(me, SIGNAL(modelSelected(int)), this, SLOT(modelSelected(int)));
}

void Guardian::regTgt(DeviceSetup *ds)
{
  QObject::connect(ds, SIGNAL(deviceTypeChanged(int, const QString &)),
                   this, SLOT(deviceTypeChanged(int, const QString &)));
}

void Guardian::checkDeviceNModel()
{
  if((devType == WEBCAM_FT) || (devType == MACWEBCAM_FT) || (devType == MACPS3EYE_FT)){
    //face tracker needs face model
    if(mdlType != MDL_FACE){
      QMessageBox::warning(parentWidget, QString::fromUtf8("Linuxtrack"),
                           devDesc + QString::fromUtf8(" requires Face type Model!"), QMessageBox::Ok);
    }
  }else if(devType == JOYSTICK){
    //face tracker needs face model
    if(mdlType != MDL_ABSOLUTE){
      QMessageBox::warning(parentWidget, QString::fromUtf8("Linuxtrack"),
                           devDesc + QString::fromUtf8(" requires Absolute type Model!"), QMessageBox::Ok);
    }
  }else{
    //ordinary tracker needs other than face model
    if(mdlType == MDL_FACE){
      QMessageBox::warning(parentWidget, QString::fromUtf8("Linuxtrack"),
                           devDesc + QString::fromUtf8(" won't work correctly with Face type Model!"),
                           QMessageBox::Ok);
    }else if(mdlType == MDL_ABSOLUTE){
      QMessageBox::warning(parentWidget, QString::fromUtf8("Linuxtrack"),
                           devDesc + QString::fromUtf8(" won't work correctly with Absolute type Model!"),
                           QMessageBox::Ok);
    }
  }
}

void Guardian::modelSelected(int modelType)
{
  mdlType = modelType;
  if(devType == -1){
    return;
  }
  checkDeviceNModel();
}

void Guardian::deviceTypeChanged(int deviceType, const QString &desc)
{
  devType = deviceType;
  devDesc = desc;
  if(mdlType == -1){
    return;
  }
  checkDeviceNModel();
}

<|endoftext|>


<commit_before>/*
    Copyright (C) 2002 by Frank Richter

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

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

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

#include "cssysdef.h"
#include "csutil/util.h"
#include "csutil/nulcache.h"

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

SCF_IMPLEMENT_IBASE (csNullCacheManager)
  SCF_IMPLEMENTS_INTERFACE (iCacheManager)
SCF_IMPLEMENT_IBASE_END

csNullCacheManager::csNullCacheManager ()
{
  SCF_CONSTRUCT_IBASE (NULL);
}

csNullCacheManager::~csNullCacheManager ()
{
}

void csNullCacheManager::SetCurrentType (const char* type)
{
}

void csNullCacheManager::SetCurrentScope (const char* scope)
{
}

bool csNullCacheManager::CacheData (void*, uint32,
  	const char*, const char*, uint32)
{
  return false;
}

iDataBuffer* csNullCacheManager::ReadCache (
  	const char* type, const char* scope, uint32 id)
{
  return NULL;
}

bool csNullCacheManager::ClearCache (const char*, const char*,
  	const uint32*)
{
  return false;
}

<commit_msg>Eliminated copilation warnings.<commit_after>/*
    Copyright (C) 2002 by Frank Richter

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

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

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

#include "cssysdef.h"
#include "csutil/util.h"
#include "csutil/nulcache.h"

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

SCF_IMPLEMENT_IBASE (csNullCacheManager)
  SCF_IMPLEMENTS_INTERFACE (iCacheManager)
SCF_IMPLEMENT_IBASE_END

csNullCacheManager::csNullCacheManager ()
{
  SCF_CONSTRUCT_IBASE (NULL);
}

csNullCacheManager::~csNullCacheManager ()
{
}

void csNullCacheManager::SetCurrentType (const char*)
{
}

void csNullCacheManager::SetCurrentScope (const char*)
{
}

bool csNullCacheManager::CacheData (void*, uint32,
  	const char*, const char*, uint32)
{
  return false;
}

iDataBuffer* csNullCacheManager::ReadCache (
  	const char* /*type*/, const char* /*scope*/, uint32 /*id*/)
{
  return NULL;
}

bool csNullCacheManager::ClearCache (const char*, const char*,
  	const uint32*)
{
  return false;
}

<|endoftext|>


<commit_before>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "otbCoordinateToName.h"

namespace otb
{
namespace Wrapper
{

class ReadImageInfo : public Application
{
public:
  /** Standard class typedefs. */
  typedef ReadImageInfo                 Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ReadImageInfo, otb::Application);

private:
  ReadImageInfo()
  {
    SetName("ReadImageInfo");
    SetDescription("Get information about the image");

    // Documentation
    SetDocName("Read image information Application");
    SetDocLongDescription("Display informations about the input image like: image size, metadata, projections...");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag("Utilities");
    AddDocTag(Tags::Meta);
  }

  virtual ~ReadImageInfo()
  {
  }

  void DoCreateParameters()
  {
    AddParameter(ParameterType_InputImage,  "in",   "Input Image");

    //Create output parameters to store image informations
    AddParameter(ParameterType_Int,"sizex","Size X");
    GetParameterByKey("sizex")->SetRole(Role_Output);
    AddParameter(ParameterType_Int,"sizey","Size Y");
    GetParameterByKey("sizey")->SetRole(Role_Output);

    AddParameter(ParameterType_Int,"spacingx","Pixel Size X");
    GetParameterByKey("spacingx")->SetRole(Role_Output);
    AddParameter(ParameterType_Int,"spacingy","Pixel Size Y");
    GetParameterByKey("spacingy")->SetRole(Role_Output);
    AddParameter(ParameterType_Int,"numberbands","Number Of Bands");
    GetParameterByKey("numberbands")->SetRole(Role_Output);

    AddParameter(ParameterType_String,"sensor","Sensor id");
    GetParameterByKey("sensor")->SetRole(Role_Output);
    MandatoryOff("sensor");

    AddParameter(ParameterType_String,"id","Id of the image");
    GetParameterByKey("id")->SetRole(Role_Output);

    AddParameter(ParameterType_String,"time","Acquisition time");
    GetParameterByKey("time")->SetRole(Role_Output);

    AddParameter(ParameterType_Float,"ullat","Upper left lattitude");
    GetParameterByKey("ullat")->SetRole(Role_Output);
    SetDefaultParameterFloat("ullat", 0);
    AddParameter(ParameterType_Float,"ullon","Upper left longitude");
    GetParameterByKey("ullon")->SetRole(Role_Output);
    SetDefaultParameterFloat("ullon", 0);
    AddParameter(ParameterType_Float,"urlat","Upper right lattitude");
    GetParameterByKey("urlat")->SetRole(Role_Output);
    SetDefaultParameterFloat("urlat", 0);
    AddParameter(ParameterType_Float,"urlon","Upper right longitude");
    GetParameterByKey("urlon")->SetRole(Role_Output);
    SetDefaultParameterFloat("urlon", 0);
    AddParameter(ParameterType_Float,"lrlat","Lower right lattitude");
    GetParameterByKey("lrlat")->SetRole(Role_Output);
    SetDefaultParameterFloat("lrlat", 0);
    AddParameter(ParameterType_Float,"lrlon","Lower right longitude");
    GetParameterByKey("lrlon")->SetRole(Role_Output);
    SetDefaultParameterFloat("lrlon", 0);
    AddParameter(ParameterType_Float,"lllat","Lower left lattitude");
    GetParameterByKey("lllat")->SetRole(Role_Output);
    SetDefaultParameterFloat("lllat", 0);
    AddParameter(ParameterType_Float,"lllon","Lower left longitude");
    GetParameterByKey("lllon")->SetRole(Role_Output);
    SetDefaultParameterFloat("lllon", 0);

    AddParameter(ParameterType_String,"town","Main town near center of image");
    GetParameterByKey("town")->SetRole(Role_Output);

    AddParameter(ParameterType_String,"country","Country of the image");
    GetParameterByKey("country")->SetRole(Role_Output);

    AddParameter(ParameterType_Group, "rgb", "Default RGB Display");
    SetParameterDescription("rgb","This group of parameters allows to access to the default rgb composition.");
    GetParameterByKey("rgb")->SetRole(Role_Output);

    AddParameter(ParameterType_Int, "rgb.r", "Red Band");
    SetParameterDescription("rgb.r","Red band Number");
    SetDefaultParameterInt("rgb.r", 1);

    AddParameter(ParameterType_Int, "rgb.g", "Green Band");
    SetParameterDescription("rgb.g","Green band Number");
    SetDefaultParameterInt("rgb.g", 2);

    AddParameter(ParameterType_Int, "rgb.b", "Blue Band");
    SetParameterDescription("rgb.b","Blue band Number");
    SetDefaultParameterInt("rgb.b", 3);

    AddParameter(ParameterType_String,"projectionref","Projection Coordinate System");
    GetParameterByKey("projectionref")->SetRole(Role_Output);

    AddParameter(ParameterType_String,"keywordlist","Image Keywordlist");
    GetParameterByKey("keywordlist")->SetRole(Role_Output);

    AddParameter(ParameterType_Group, "gcp", "Ground Control Points informations");
    SetParameterDescription("gcp","This group of parameters allows to access to the GCPs informations.");
    GetParameterByKey("gcp")->SetRole(Role_Output);

    AddParameter(ParameterType_Int, "gcp.count", "GCPs Number");
    SetParameterDescription("gcp.count","Number of GCPs");
    SetDefaultParameterInt("gcp.count", 0);

    AddParameter(ParameterType_String,"gcp.proj","GCP Projection System");

    AddParameter(ParameterType_StringList,"gcp.ids","GCPs Id");
    AddParameter(ParameterType_StringList,"gcp.info","GCPs Info");

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    try
      {
      FloatVectorImageType::Pointer inImage = GetParameterImage("in");
      // Read informations
      typedef otb::ImageMetadataInterfaceBase ImageMetadataInterfaceType;
      ImageMetadataInterfaceType::Pointer metadataInterface = ImageMetadataInterfaceFactory::CreateIMI(inImage->GetMetaDataDictionary());

      //Get image size
      SetParameterInt("sizex",inImage->GetLargestPossibleRegion().GetSize()[0]);
      SetParameterInt("sizey",inImage->GetLargestPossibleRegion().GetSize()[1]);

      //Get image spacing
      SetParameterInt("spacingx",inImage->GetSpacing()[0]);
      SetParameterInt("spacingy",inImage->GetSpacing()[1]);

      SetParameterInt("numberbands",inImage->GetNumberOfComponentsPerPixel());

      //std::cout << "metadata " << metadataInterface << std::endl;
      SetParameterString("sensor",metadataInterface->GetSensorID());
      SetParameterString("id",metadataInterface->GetImageKeywordlist().GetMetadataByKey("image_id"));
      SetParameterString("projectionref",metadataInterface->GetProjectionRef());

      // Format acquisition time
      itk::OStringStream osstime;
      osstime<<metadataInterface->GetYear()<<"-";
      if(metadataInterface->GetMonth()<10)
	osstime<<"0";
      osstime<<metadataInterface->GetMonth()<<"-";
      if(metadataInterface->GetDay()<10)
	osstime<<"0";
      osstime<<metadataInterface->GetDay()<<"T";
      if(metadataInterface->GetHour()<10)
	osstime<<"0";
      osstime<<metadataInterface->GetHour()<<":";
      if(metadataInterface->GetMinute()<10)
	osstime<<"0";
      osstime<<metadataInterface->GetMinute();
      osstime<<":00";
      SetParameterString("time",osstime.str());

      itk::OStringStream osskeywordlist;
      osskeywordlist<<metadataInterface->GetImageKeywordlist() << std::endl;
      SetParameterString("keywordlist",osskeywordlist.str());

      double ullat = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ul_lat").c_str());
      double ullon = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ul_lon").c_str());
      double urlat = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ur_lat").c_str());
      double urlon = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ur_lon").c_str());
      double lrlat = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("lr_lat").c_str());
      double lrlon = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("lr_lon").c_str());
      double lllat = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ll_lat").c_str());
      double lllon = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ll_lon").c_str());

      SetParameterInt("rgb.r",metadataInterface->GetDefaultDisplay()[0]);
      SetParameterInt("rgb.g",metadataInterface->GetDefaultDisplay()[1]);
      SetParameterInt("rgb.b",metadataInterface->GetDefaultDisplay()[2]);

      SetParameterInt("gcp.count",metadataInterface->GetGCPCount());
      SetParameterString("gcp.proj",metadataInterface->GetGCPProjection());

      std::vector<std::string> gcp_ids;
      std::vector<std::string> gcp_infos;

      for(int gcpIdx = 0; gcpIdx  < GetParameterInt("gcp.count"); ++ gcpIdx)
	{
	gcp_ids.push_back(metadataInterface->GetGCPId(gcpIdx));
	gcp_infos.push_back(metadataInterface->GetGCPInfo(gcpIdx));
	}

      SetParameterStringList("gcp.ids",gcp_ids);
      SetParameterStringList("gcp.info",gcp_infos);

      // Retrieve footprint
      SetParameterFloat("ullat",ullat);
      SetParameterFloat("ullon",ullon);
      SetParameterFloat("urlat",urlat);
      SetParameterFloat("urlon",urlon);
      SetParameterFloat("lrlat",lrlat);
      SetParameterFloat("lrlon",lrlon);
      SetParameterFloat("lllat",lllat);
      SetParameterFloat("lllon",lllon);

      double centerlat = 0.25*(ullat+urlat+lrlat+lllat);
      double centerlon = 0.25*(ullon+urlon+lrlon+lllon);

      CoordinateToName::Pointer coord2name = CoordinateToName::New();
      coord2name->SetLat(centerlat);
      coord2name->SetLon(centerlon);
      coord2name->Evaluate();

      SetParameterString("town",coord2name->GetPlaceName());
      SetParameterString("country",coord2name->GetCountryName());
      }
    catch ( itk::ExceptionObject & err )
      {
      //Do nothing at all
      }
    //FIXME Logger must output also parameter groups
    this->GetLogger()->Info("");
  }

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ReadImageInfo)

<commit_msg>STYLE:kwstyle<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "otbCoordinateToName.h"

namespace otb
{
namespace Wrapper
{

class ReadImageInfo : public Application
{
public:
  /** Standard class typedefs. */
  typedef ReadImageInfo                 Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ReadImageInfo, otb::Application);

private:
  ReadImageInfo()
  {
    SetName("ReadImageInfo");
    SetDescription("Get information about the image");

    // Documentation
    SetDocName("Read image information Application");
    SetDocLongDescription("Display informations about the input image like: image size, metadata, projections...");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag("Utilities");
    AddDocTag(Tags::Meta);
  }

  virtual ~ReadImageInfo()
  {
  }

  void DoCreateParameters()
  {
    AddParameter(ParameterType_InputImage,  "in",   "Input Image");

    //Create output parameters to store image informations
    AddParameter(ParameterType_Int,"sizex","Size X");
    GetParameterByKey("sizex")->SetRole(Role_Output);
    AddParameter(ParameterType_Int,"sizey","Size Y");
    GetParameterByKey("sizey")->SetRole(Role_Output);

    AddParameter(ParameterType_Int,"spacingx","Pixel Size X");
    GetParameterByKey("spacingx")->SetRole(Role_Output);
    AddParameter(ParameterType_Int,"spacingy","Pixel Size Y");
    GetParameterByKey("spacingy")->SetRole(Role_Output);
    AddParameter(ParameterType_Int,"numberbands","Number Of Bands");
    GetParameterByKey("numberbands")->SetRole(Role_Output);

    AddParameter(ParameterType_String,"sensor","Sensor id");
    GetParameterByKey("sensor")->SetRole(Role_Output);
    MandatoryOff("sensor");

    AddParameter(ParameterType_String,"id","Id of the image");
    GetParameterByKey("id")->SetRole(Role_Output);

    AddParameter(ParameterType_String,"time","Acquisition time");
    GetParameterByKey("time")->SetRole(Role_Output);

    AddParameter(ParameterType_Float,"ullat","Upper left lattitude");
    GetParameterByKey("ullat")->SetRole(Role_Output);
    SetDefaultParameterFloat("ullat", 0);
    AddParameter(ParameterType_Float,"ullon","Upper left longitude");
    GetParameterByKey("ullon")->SetRole(Role_Output);
    SetDefaultParameterFloat("ullon", 0);
    AddParameter(ParameterType_Float,"urlat","Upper right lattitude");
    GetParameterByKey("urlat")->SetRole(Role_Output);
    SetDefaultParameterFloat("urlat", 0);
    AddParameter(ParameterType_Float,"urlon","Upper right longitude");
    GetParameterByKey("urlon")->SetRole(Role_Output);
    SetDefaultParameterFloat("urlon", 0);
    AddParameter(ParameterType_Float,"lrlat","Lower right lattitude");
    GetParameterByKey("lrlat")->SetRole(Role_Output);
    SetDefaultParameterFloat("lrlat", 0);
    AddParameter(ParameterType_Float,"lrlon","Lower right longitude");
    GetParameterByKey("lrlon")->SetRole(Role_Output);
    SetDefaultParameterFloat("lrlon", 0);
    AddParameter(ParameterType_Float,"lllat","Lower left lattitude");
    GetParameterByKey("lllat")->SetRole(Role_Output);
    SetDefaultParameterFloat("lllat", 0);
    AddParameter(ParameterType_Float,"lllon","Lower left longitude");
    GetParameterByKey("lllon")->SetRole(Role_Output);
    SetDefaultParameterFloat("lllon", 0);

    AddParameter(ParameterType_String,"town","Main town near center of image");
    GetParameterByKey("town")->SetRole(Role_Output);

    AddParameter(ParameterType_String,"country","Country of the image");
    GetParameterByKey("country")->SetRole(Role_Output);

    AddParameter(ParameterType_Group, "rgb", "Default RGB Display");
    SetParameterDescription("rgb","This group of parameters allows to access to the default rgb composition.");
    GetParameterByKey("rgb")->SetRole(Role_Output);

    AddParameter(ParameterType_Int, "rgb.r", "Red Band");
    SetParameterDescription("rgb.r","Red band Number");
    SetDefaultParameterInt("rgb.r", 1);

    AddParameter(ParameterType_Int, "rgb.g", "Green Band");
    SetParameterDescription("rgb.g","Green band Number");
    SetDefaultParameterInt("rgb.g", 2);

    AddParameter(ParameterType_Int, "rgb.b", "Blue Band");
    SetParameterDescription("rgb.b","Blue band Number");
    SetDefaultParameterInt("rgb.b", 3);

    AddParameter(ParameterType_String,"projectionref","Projection Coordinate System");
    GetParameterByKey("projectionref")->SetRole(Role_Output);

    AddParameter(ParameterType_String,"keywordlist","Image Keywordlist");
    GetParameterByKey("keywordlist")->SetRole(Role_Output);

    AddParameter(ParameterType_Group, "gcp", "Ground Control Points informations");
    SetParameterDescription("gcp","This group of parameters allows to access to the GCPs informations.");
    GetParameterByKey("gcp")->SetRole(Role_Output);

    AddParameter(ParameterType_Int, "gcp.count", "GCPs Number");
    SetParameterDescription("gcp.count","Number of GCPs");
    SetDefaultParameterInt("gcp.count", 0);

    AddParameter(ParameterType_String,"gcp.proj","GCP Projection System");

    AddParameter(ParameterType_StringList,"gcp.ids","GCPs Id");
    AddParameter(ParameterType_StringList,"gcp.info","GCPs Info");

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    try
      {
      FloatVectorImageType::Pointer inImage = GetParameterImage("in");
      // Read informations
      typedef otb::ImageMetadataInterfaceBase ImageMetadataInterfaceType;
      ImageMetadataInterfaceType::Pointer metadataInterface = ImageMetadataInterfaceFactory::CreateIMI(inImage->GetMetaDataDictionary());

      //Get image size
      SetParameterInt("sizex",inImage->GetLargestPossibleRegion().GetSize()[0]);
      SetParameterInt("sizey",inImage->GetLargestPossibleRegion().GetSize()[1]);

      //Get image spacing
      SetParameterInt("spacingx",inImage->GetSpacing()[0]);
      SetParameterInt("spacingy",inImage->GetSpacing()[1]);

      SetParameterInt("numberbands",inImage->GetNumberOfComponentsPerPixel());

      //std::cout << "metadata " << metadataInterface << std::endl;
      SetParameterString("sensor",metadataInterface->GetSensorID());
      SetParameterString("id",metadataInterface->GetImageKeywordlist().GetMetadataByKey("image_id"));
      SetParameterString("projectionref",metadataInterface->GetProjectionRef());

      // Format acquisition time
      itk::OStringStream osstime;
      osstime<<metadataInterface->GetYear()<<"-";
      if(metadataInterface->GetMonth()<10)
        osstime<<"0";
      osstime<<metadataInterface->GetMonth()<<"-";
      if(metadataInterface->GetDay()<10)
        osstime<<"0";
      osstime<<metadataInterface->GetDay()<<"T";
      if(metadataInterface->GetHour()<10)
        osstime<<"0";
      osstime<<metadataInterface->GetHour()<<":";
      if(metadataInterface->GetMinute()<10)
        osstime<<"0";
      osstime<<metadataInterface->GetMinute();
      osstime<<":00";
      SetParameterString("time",osstime.str());

      itk::OStringStream osskeywordlist;
      osskeywordlist<<metadataInterface->GetImageKeywordlist() << std::endl;
      SetParameterString("keywordlist",osskeywordlist.str());

      double ullat = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ul_lat").c_str());
      double ullon = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ul_lon").c_str());
      double urlat = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ur_lat").c_str());
      double urlon = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ur_lon").c_str());
      double lrlat = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("lr_lat").c_str());
      double lrlon = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("lr_lon").c_str());
      double lllat = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ll_lat").c_str());
      double lllon = atof(metadataInterface->GetImageKeywordlist().GetMetadataByKey("ll_lon").c_str());

      SetParameterInt("rgb.r",metadataInterface->GetDefaultDisplay()[0]);
      SetParameterInt("rgb.g",metadataInterface->GetDefaultDisplay()[1]);
      SetParameterInt("rgb.b",metadataInterface->GetDefaultDisplay()[2]);

      SetParameterInt("gcp.count",metadataInterface->GetGCPCount());
      SetParameterString("gcp.proj",metadataInterface->GetGCPProjection());

      std::vector<std::string> gcp_ids;
      std::vector<std::string> gcp_infos;

      for(int gcpIdx = 0; gcpIdx  < GetParameterInt("gcp.count"); ++ gcpIdx)
        {
        gcp_ids.push_back(metadataInterface->GetGCPId(gcpIdx));
        gcp_infos.push_back(metadataInterface->GetGCPInfo(gcpIdx));
        }

      SetParameterStringList("gcp.ids",gcp_ids);
      SetParameterStringList("gcp.info",gcp_infos);

      // Retrieve footprint
      SetParameterFloat("ullat",ullat);
      SetParameterFloat("ullon",ullon);
      SetParameterFloat("urlat",urlat);
      SetParameterFloat("urlon",urlon);
      SetParameterFloat("lrlat",lrlat);
      SetParameterFloat("lrlon",lrlon);
      SetParameterFloat("lllat",lllat);
      SetParameterFloat("lllon",lllon);

      double centerlat = 0.25*(ullat+urlat+lrlat+lllat);
      double centerlon = 0.25*(ullon+urlon+lrlon+lllon);

      CoordinateToName::Pointer coord2name = CoordinateToName::New();
      coord2name->SetLat(centerlat);
      coord2name->SetLon(centerlon);
      coord2name->Evaluate();

      SetParameterString("town",coord2name->GetPlaceName());
      SetParameterString("country",coord2name->GetCountryName());
      }
    catch ( itk::ExceptionObject & err )
      {
      //Do nothing at all
      }
    //FIXME Logger must output also parameter groups
    this->GetLogger()->Info("");
  }

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ReadImageInfo)
<|endoftext|>


<commit_before>#include <string>
#include <iostream>
#include <fstream>

#include "disk.h"
#include "command.h"
#include "error_handling.h"
#include "os.h"
#include "potions.h"
#include "scrolls.h"
#include "io.h"
#include "armor.h"
#include "daemons.h"
#include "colors.h"
#include "level.h"
#include "rings.h"
#include "misc.h"
#include "player.h"
#include "weapons.h"
#include "wand.h"
#include "options.h"
#include "rogue.h"
#include "traps.h"

#include "game.h"

using namespace std;

Game*   Game::game_ptr = nullptr;
IO*     Game::io = nullptr;
Level*  Game::level = nullptr;
string* Game::whoami = nullptr;
string* Game::save_game_path = nullptr;
int     Game::current_level = 1;
int     Game::levels_without_food = 0;

void Game::exit() {
  if (game_ptr != nullptr) {
    delete game_ptr;
  }
  ::exit(0);
}

void Game::new_level(int dungeon_level) {

  Game::current_level = dungeon_level;

  if (Game::level != nullptr) {
    delete Game::level;
  }

  Game::level = new Level();

  // Drop player in the new dungeon level
  if (player == nullptr) {
    player = new Player(true);
  }

  Coordinate new_player_pos = player->get_position();
  Game::level->get_random_room_coord(nullptr, &new_player_pos, 0, true);
  player->set_position(new_player_pos);

  // Unhold player just in case
  player->set_not_held();
}

int Game::run() {

  // Try to crash cleanly, and autosave if possible
  // Unless we are debugging, since that messes with gdb/lldb
#ifdef NDEBUG
  signal(SIGHUP, save_auto);
  signal(SIGQUIT, command_signal_endit);
  signal(SIGILL, save_auto);
  signal(SIGTRAP, save_auto);
  signal(SIGIOT, save_auto);
  signal(SIGFPE, save_auto);
  signal(SIGBUS, save_auto);
  signal(SIGSEGV, save_auto);
  signal(SIGSYS, save_auto);
  signal(SIGTERM, save_auto);
  signal(SIGINT, command_signal_quit);
#else
  Game::io->message("Seed: #" + to_string(starting_seed));
#endif

  player->set_previous_room(Game::level->get_room(player->get_position()));

#ifdef NDEBUG
  try {
    for (;;) command();
  } catch (const std::runtime_error &ex) {
    endwin();
    cout << ex.what() << endl;
    return 1;
  }
#else
  for (;;) command();
#endif

  // CODE NOT REACHED
}

Game::Game(string const& whoami_, string const& save_path_)
  : starting_seed(os_rand_seed) {
    Game::whoami = new string(whoami_);
    Game::save_game_path = new string(save_path_);

  if (game_ptr != nullptr) {
    error("Game is a singleton class");
  }
  game_ptr = this;
  cout << "Hello " << *whoami << ", just a moment while I dig the dungeon..." << flush;

  // Init stuff
  Game::io = new IO();                  // Graphics
  Scroll::init_scrolls();               // Names of scrolls
  Color::init_colors();                 // Colors for potions and stuff
  Potion::init_potions();               // Colors of potions
  Ring::init_rings();                   // Stone settings of rings
  Wand::init_wands();                   // Materials of wands
  Daemons::init_daemons();              // Over-time-effects
  Monster::init_monsters();             // Monster types
  Trap::init_traps();                   // Trap types
  Game::new_level(Game::current_level); // Level (and player)

  // Start up daemons and fuses
  Daemons::daemon_start(Daemons::runners_move, AFTER);
  Daemons::daemon_start(Daemons::doctor, AFTER);
  Daemons::daemon_start(Daemons::ring_abilities, AFTER);
}

Game::~Game() {
  Trap::free_traps();
  Monster::free_monsters();
  Daemons::free_daemons();
  Wand::free_wands();
  Ring::free_rings();
  Potion::free_potions();
  Color::free_colors();
  Scroll::free_scrolls();

  delete Game::io;
  Game::io = nullptr;

  delete Game::whoami;
  Game::whoami = nullptr;
}

Game::Game(ifstream& savefile) {

  if (game_ptr != nullptr) {
    error("Game is a singleton class");
  }
  game_ptr = this;

  Game::io = new IO();

  try {
    Scroll::load_scrolls(savefile);
    Color::init_colors();
    Potion::load_potions(savefile);
    Ring::load_rings(savefile);
    Wand::load_wands(savefile);
    Daemons::load_daemons(savefile);
    Monster::init_monsters();
    Trap::init_traps();
    Player::load_player(savefile);

    Disk::load_tag(TAG_GAME, savefile);
    Disk::load(TAG_WHOAMI, Game::whoami, savefile);
    Disk::load(TAG_SAVEPATH, Game::save_game_path, savefile);
    Disk::load(TAG_LEVEL, Game::current_level, savefile);
    Disk::load(TAG_FOODLESS, Game::levels_without_food, savefile);
  } catch (fatal_error &e) {
    Game::io->stop_curses();
    cout << "Failed to load game, corrupt save file (" << e.what() << ")\n";
    exit();
  }

  //Game::new_level(Game::current_level);
  Game::new_level(1);
}

bool Game::save() {
  ofstream savefile(*save_game_path, fstream::out | fstream::trunc);
  if (!savefile) {
    Game::io->message("Failed to save file " + *save_game_path);
    return false;
  }

  Scroll::save_scrolls(savefile);
  Potion::save_potions(savefile);
  Ring::save_rings(savefile);
  Wand::save_wands(savefile);
  Daemons::save_daemons(savefile);
  Player::save_player(savefile);

  Disk::save_tag(TAG_GAME, savefile);
  Disk::save(TAG_WHOAMI, Game::whoami, savefile);
  Disk::save(TAG_SAVEPATH, Game::save_game_path, savefile);
  Disk::save(TAG_LEVEL, Game::current_level, savefile);
  Disk::save(TAG_FOODLESS, Game::levels_without_food, savefile);

  savefile.close();
  return true;
}
<commit_msg>cleanup<commit_after>#include <string>
#include <iostream>
#include <fstream>

#include "disk.h"
#include "command.h"
#include "error_handling.h"
#include "os.h"
#include "potions.h"
#include "scrolls.h"
#include "io.h"
#include "armor.h"
#include "daemons.h"
#include "colors.h"
#include "level.h"
#include "rings.h"
#include "misc.h"
#include "player.h"
#include "weapons.h"
#include "wand.h"
#include "options.h"
#include "rogue.h"
#include "traps.h"

#include "game.h"

using namespace std;

Game*   Game::game_ptr = nullptr;
IO*     Game::io = nullptr;
Level*  Game::level = nullptr;
string* Game::whoami = nullptr;
string* Game::save_game_path = nullptr;
int     Game::current_level = 1;
int     Game::levels_without_food = 0;

void Game::exit() {
  if (game_ptr != nullptr) {
    delete game_ptr;
  }
  ::exit(0);
}

void Game::new_level(int dungeon_level) {

  current_level = dungeon_level;

  if (level != nullptr) {
    delete level;
  }

  level = new Level();

  // Drop player in the new dungeon level
  if (player == nullptr) {
    player = new Player(true);
  }

  Coordinate new_player_pos = player->get_position();
  level->get_random_room_coord(nullptr, &new_player_pos, 0, true);
  player->set_position(new_player_pos);

  // Unhold player just in case
  player->set_not_held();
}

int Game::run() {

  // Try to crash cleanly, and autosave if possible
  // Unless we are debugging, since that messes with gdb/lldb
#ifdef NDEBUG
  signal(SIGHUP, save_auto);
  signal(SIGQUIT, command_signal_endit);
  signal(SIGILL, save_auto);
  signal(SIGTRAP, save_auto);
  signal(SIGIOT, save_auto);
  signal(SIGFPE, save_auto);
  signal(SIGBUS, save_auto);
  signal(SIGSEGV, save_auto);
  signal(SIGSYS, save_auto);
  signal(SIGTERM, save_auto);
  signal(SIGINT, command_signal_quit);
#else
  io->message("Seed: #" + to_string(starting_seed));
#endif

  player->set_previous_room(level->get_room(player->get_position()));

#ifdef NDEBUG
  try {
    for (;;) command();
  } catch (const std::runtime_error &ex) {
    endwin();
    cout << ex.what() << endl;
    return 1;
  }
#else
  for (;;) command();
#endif

  // CODE NOT REACHED
}

Game::Game(string const& whoami_, string const& save_path_)
  : starting_seed(os_rand_seed) {
    whoami = new string(whoami_);
    save_game_path = new string(save_path_);

  if (game_ptr != nullptr) {
    error("Game is a singleton class");
  }
  game_ptr = this;
  cout << "Hello " << *whoami << ", just a moment while I dig the dungeon..." << flush;

  // Init stuff
  io = new IO();                        // Graphics
  Scroll::init_scrolls();               // Names of scrolls
  Color::init_colors();                 // Colors for potions and stuff
  Potion::init_potions();               // Colors of potions
  Ring::init_rings();                   // Stone settings of rings
  Wand::init_wands();                   // Materials of wands
  Daemons::init_daemons();              // Over-time-effects
  Monster::init_monsters();             // Monster types
  Trap::init_traps();                   // Trap types
  new_level(current_level);             // Level (and player)

  // Start up daemons and fuses
  Daemons::daemon_start(Daemons::runners_move, AFTER);
  Daemons::daemon_start(Daemons::doctor, AFTER);
  Daemons::daemon_start(Daemons::ring_abilities, AFTER);
}

Game::~Game() {
  Trap::free_traps();
  Monster::free_monsters();
  Daemons::free_daemons();
  Wand::free_wands();
  Ring::free_rings();
  Potion::free_potions();
  Color::free_colors();
  Scroll::free_scrolls();

  delete io;
  io = nullptr;

  delete whoami;
  whoami = nullptr;
}

Game::Game(ifstream& savefile) {

  if (game_ptr != nullptr) {
    error("Game is a singleton class");
  }
  game_ptr = this;

  io = new IO();

  try {
    Scroll::load_scrolls(savefile);
    Color::init_colors();
    Potion::load_potions(savefile);
    Ring::load_rings(savefile);
    Wand::load_wands(savefile);
    Daemons::load_daemons(savefile);
    Monster::init_monsters();
    Trap::init_traps();
    Player::load_player(savefile);
    //level = new Level(savefile);

    Disk::load_tag(TAG_GAME, savefile);

    Disk::load(TAG_WHOAMI, whoami, savefile);
    Disk::load(TAG_SAVEPATH, save_game_path, savefile);
    Disk::load(TAG_LEVEL, current_level, savefile);
    Disk::load(TAG_FOODLESS, levels_without_food, savefile);

    Game::new_level(1);

    Disk::load_tag(TAG_GAME, savefile);
  } catch (fatal_error &e) {
    io->stop_curses();
    cout << "Failed to load game, corrupt save file (" << e.what() << ")\n";
    exit();
  }

}

bool Game::save() {
  ofstream savefile(*save_game_path, fstream::out | fstream::trunc);
  if (!savefile) {
    io->message("Failed to save file " + *save_game_path);
    return false;
  }

  Scroll::save_scrolls(savefile);
  Potion::save_potions(savefile);
  Ring::save_rings(savefile);
  Wand::save_wands(savefile);
  Daemons::save_daemons(savefile);
  Player::save_player(savefile);
  //level->save(savefile);

  Disk::save_tag(TAG_GAME, savefile);

  Disk::save(TAG_WHOAMI, whoami, savefile);
  Disk::save(TAG_SAVEPATH, save_game_path, savefile);
  Disk::save(TAG_LEVEL, current_level, savefile);
  Disk::save(TAG_FOODLESS, levels_without_food, savefile);

  Disk::save_tag(TAG_GAME, savefile);

  savefile.close();
  return true;
}
<|endoftext|>