<commit_before>/**
 * ZNC Notifo Module
 *
 * Allows the user to enter a Notifo user and API token, and sends
 * channel highlights and personal messages to Notifo.
 *
 * Copyright (c) 2011 John Reese
 * Licensed under the MIT license
 */

#define REQUIRESSL

#include "znc.h"
#include "Chan.h"
#include "User.h"
#include "Modules.h"

#if (!defined(VERSION_MAJOR) || !defined(VERSION_MINOR) || (VERSION_MAJOR == 0 && VERSION_MINOR < 72))
#error This module needs ZNC 0.072 or newer.
#endif

#define DEBUG_HOST 0
#define DEBUG_LOGGING 0

class CNotifoMod : public CModule
{
	protected:

		// Application name
		CString app;

		// Too lazy to add CString("\r\n\") everywhere
		CString crlf;

		// BASIC auth string, needs to be encoded each time username/secret is changed
		CString notifo_auth;

		// Host and URL to send messages to
		CString notifo_host;
		CString notifo_url;

		// User agent to use
		CString user_agent;

		// User object
		CUser *user;

		// Configuration options
		MCString options;

	public:

		MODCONSTRUCTOR(CNotifoMod) {
			app = "ZNC";
			crlf = "\r\n";

#if DEBUG_HOST
			notifo_host = "notifo.leetcode.net";
			notifo_url = "/index.php";
#else
			notifo_host = "api.notifo.com";
			notifo_url = "/v1/send_notification";
#endif

			notifo_auth = "";
			user_agent = "ZNC To Notifo";

			// Current user
			user = GetUser();

			// Notifo user account and secret
			options["username"] = "";
			options["secret"] = "";
		}
		virtual ~CNotifoMod() {}

	protected:

		/**
		 * Shorthand for encoding a string for a URL.
		 *
		 * @param str String to be encoded
		 * @return Encoded string
		 */
		CString urlencode(const CString& str)
		{
			return str.Escape_n(CString::EASCII, CString::EURL);
		}

		/**
		 * Re-encode the authentication credentials.
		 */
		void authencode()
		{
			// BASIC auth, base64-encoded username:password
			CString auth = options["username"] + CString(":") + options["secret"];
			notifo_auth = auth.Base64Encode_n();
		}

		/**
		 * Send a message to the currently-configured Notifo account.
		 * Requires (and assumes) that the user has already configured their
		 * username and API secret using the 'set' command.
		 *
		 * @param message Message to be sent to the user
		 * @param title Message title to use
		 */
		void send_message(const CString& message, const CString& title="New Message")
		{
			// POST body parameters for the request
			CString post = "to=" + urlencode(options["username"]);
			post += "&msg=" + urlencode(message);
			post += "&label=" + urlencode(app);
			post += "&title=" + urlencode(title);
			post += "&uri=" + urlencode(CString("http://notifo.leetcode.net/"));

			// Request headers and POST body
			CString request = "POST " + notifo_url + " HTTP/1.1" + crlf;
			request += "Host: " + notifo_host + crlf;
			request += "Content-Type: application/x-www-form-urlencoded" + crlf;
			request += "Content-Length: " + CString(post.length()) + crlf;
			request += "User-Agent: " + user_agent + crlf;
			request += "Authorization: Basic " + notifo_auth + crlf;
			request += crlf;
			request += post + crlf;

			// Create the socket connection, write to it, and add it to the queue
			CSocket *sock = new CSocket(this);
			sock->Connect(notifo_host, 443, true);
			sock->Write(request);
			sock->Close(Csock::CLT_AFTERWRITE);
			AddSocket(sock);

#if DEBUG_LOGGING
			// Log the HTTP request
			FILE *fh = fopen("/tmp/notifo.log", "a");
			fputs(request.c_str(), fh);
			fclose(fh);
#endif
		}

		/**
		 * Determine if the given message matches any highlight rules.
		 *
		 * @param message Message contents
		 * @return True if message matches a highlight
		 */
		bool highlight(const CString& message)
		{
			CNick nick = user->GetIRCNick();

			if (message.find(nick.GetNick()) != string::npos)
			{
				return true;
			}

			return false;
		}

		/**
		 * Determine when to notify the user of a channel message.
		 *
		 * @param nick Nick that sent the message
		 * @param channel Channel the message was sent to
		 * @param message Message contents
		 * @return Notification should be sent
		 */
		bool notify_channel(const CNick& nick, const CChan& channel, const CString& message)
		{
			return highlight(message);
		}

		/**
		 * Determine when to notify the user of a private message.
		 *
		 * @param nick Nick that sent the message
		 * @return Notification should be sent
		 */
		bool notify_pm(const CNick& nick)
		{
			return true;
		}

	protected:

		/**
		 * Handle the plugin being loaded.  Retrieve plugin config values.
		 *
		 * @param args Plugin arguments
		 * @param message Message to show the user after loading
		 */
		bool OnLoad(const CString& args, CString& message)
		{
			for (MCString::iterator i = options.begin(); i != options.end(); i++)
			{
				CString value = GetNV(i->first);
				if (value != "")
				{
					options[i->first] = value;
				}
			}

			authencode();

			return true;
		}

		/**
		 * Handle channel messages.
		 *
		 * @param nick Nick that sent the message
		 * @param channel Channel the message was sent to
		 * @param message Message contents
		 */
		EModRet OnChanMsg(CNick& nick, CChan& channel, CString& message)
		{
			if (notify_channel(nick, channel, message))
			{
				CString title = "Highlight";
				CString msg = channel.GetName();
				msg += ": <" + nick.GetNick();
				msg += "> " + message;

				send_message(msg, title);
			}

			return CONTINUE;
		}

		/**
		 * Handle channel actions.
		 *
		 * @param nick Nick that sent the action
		 * @param channel Channel the message was sent to
		 * @param message Message contents
		 */
		EModRet OnChanAction(CNick& nick, CChan& channel, CString& message)
		{
			if (notify_channel(nick, channel, message))
			{
				CString title = "Highlight";
				CString msg = channel.GetName();
				msg += ": " + nick.GetNick();
				msg += " " + message;

				send_message(msg, title);
			}

			return CONTINUE;
		}

		/**
		 * Handle a private message.
		 *
		 * @param nick Nick that sent the message
		 * @param message Message contents
		 */
		EModRet OnPrivMsg(CNick& nick, CString& message)
		{
			if (notify_pm(nick))
			{
				CString title = "Private Message";
				CString msg = "From " + nick.GetNick();
				msg += ": " + message;

				send_message(msg, title);
			}

			return CONTINUE;
		}

		/**
		 * Handle a private action.
		 *
		 * @param nick Nick that sent the action
		 * @param message Message contents
		 */
		EModRet OnPrivAction(CNick& nick, CString& message)
		{
			if (notify_pm(nick))
			{
				CString title = "Private Message";
				CString msg = "* " + nick.GetNick();
				msg += " " + message;

				send_message(msg, title);
			}

			return CONTINUE;
		}

		/**
		 * Handle direct commands to the *notifo virtual user.
		 *
		 * @param command Command string
		 */
		void OnModCommand(const CString& command)
		{
			VCString tokens;
			int token_count = command.Split(" ", tokens, false);

			if (token_count < 1)
			{
				return;
			}

			CString action = tokens[0].AsLower();

			// SET command
			if (action == "set")
			{
				if (token_count != 3)
				{
					PutModule("Usage: set <option> <value>");
					return;
				}

				CString option = tokens[1].AsLower();
				CString value = tokens[2];
				MCString::iterator pos = options.find(option);

				if (pos == options.end())
				{
					PutModule("Error: invalid option name");
				}
				else
				{
					options[option] = value;
					SetNV(option, value);

					authencode();
				}
			}
			// GET command
			else if (action == "get")
			{
				if (token_count != 2)
				{
					PutModule("Usage: get <option>");
					return;
				}

				CString option = tokens[1].AsLower();
				MCString::iterator pos = options.find(option);

				if (pos == options.end())
				{
					PutModule("Error: invalid option name");
				}
				else
				{
					PutModule(option + CString(": \"") + options[option] + CString("\""));
				}
			}
			// SEND command
			else if (action == "send")
			{
				CString message = command.Token(1, true, " ", true);
				send_message(message);
			}
			else
			{
				PutModule("Error: invalid command");
			}
		}
};

MODULEDEFS(CNotifoMod, "Send highlights and personal messages to a Notifo account")
<commit_msg>Implemented client_count condition<commit_after>/**
 * ZNC Notifo Module
 *
 * Allows the user to enter a Notifo user and API token, and sends
 * channel highlights and personal messages to Notifo.
 *
 * Copyright (c) 2011 John Reese
 * Licensed under the MIT license
 */

#define REQUIRESSL

#include "znc.h"
#include "Chan.h"
#include "User.h"
#include "Modules.h"

#if (!defined(VERSION_MAJOR) || !defined(VERSION_MINOR) || (VERSION_MAJOR == 0 && VERSION_MINOR < 72))
#error This module needs ZNC 0.072 or newer.
#endif

#define DEBUG_HOST 0
#define DEBUG_LOGGING 0

class CNotifoMod : public CModule
{
	protected:

		// Application name
		CString app;

		// Too lazy to add CString("\r\n\") everywhere
		CString crlf;

		// BASIC auth string, needs to be encoded each time username/secret is changed
		CString notifo_auth;

		// Host and URL to send messages to
		CString notifo_host;
		CString notifo_url;

		// User agent to use
		CString user_agent;

		// User object
		CUser *user;

		// Configuration options
		MCString options;

	public:

		MODCONSTRUCTOR(CNotifoMod) {
			app = "ZNC";
			crlf = "\r\n";

#if DEBUG_HOST
			notifo_host = "notifo.leetcode.net";
			notifo_url = "/index.php";
#else
			notifo_host = "api.notifo.com";
			notifo_url = "/v1/send_notification";
#endif

			notifo_auth = "";
			user_agent = "ZNC To Notifo";

			// Current user
			user = GetUser();

			// Notifo user account and secret
			options["username"] = "";
			options["secret"] = "";

			// Notification conditions
			options["client_count_less_than"] = "0";
		}
		virtual ~CNotifoMod() {}

	protected:

		/**
		 * Shorthand for encoding a string for a URL.
		 *
		 * @param str String to be encoded
		 * @return Encoded string
		 */
		CString urlencode(const CString& str)
		{
			return str.Escape_n(CString::EASCII, CString::EURL);
		}

		/**
		 * Re-encode the authentication credentials.
		 */
		void authencode()
		{
			// BASIC auth, base64-encoded username:password
			CString auth = options["username"] + CString(":") + options["secret"];
			notifo_auth = auth.Base64Encode_n();
		}

		/**
		 * Send a message to the currently-configured Notifo account.
		 * Requires (and assumes) that the user has already configured their
		 * username and API secret using the 'set' command.
		 *
		 * @param message Message to be sent to the user
		 * @param title Message title to use
		 */
		void send_message(const CString& message, const CString& title="New Message")
		{
			// POST body parameters for the request
			CString post = "to=" + urlencode(options["username"]);
			post += "&msg=" + urlencode(message);
			post += "&label=" + urlencode(app);
			post += "&title=" + urlencode(title);
			post += "&uri=" + urlencode(CString("http://notifo.leetcode.net/"));

			// Request headers and POST body
			CString request = "POST " + notifo_url + " HTTP/1.1" + crlf;
			request += "Host: " + notifo_host + crlf;
			request += "Content-Type: application/x-www-form-urlencoded" + crlf;
			request += "Content-Length: " + CString(post.length()) + crlf;
			request += "User-Agent: " + user_agent + crlf;
			request += "Authorization: Basic " + notifo_auth + crlf;
			request += crlf;
			request += post + crlf;

			// Create the socket connection, write to it, and add it to the queue
			CSocket *sock = new CSocket(this);
			sock->Connect(notifo_host, 443, true);
			sock->Write(request);
			sock->Close(Csock::CLT_AFTERWRITE);
			AddSocket(sock);

#if DEBUG_LOGGING
			// Log the HTTP request
			FILE *fh = fopen("/tmp/notifo.log", "a");
			fputs(request.c_str(), fh);
			fclose(fh);
#endif
		}

		/**
		 * Check how many clients are connected to ZNC.
		 *
		 * @return Number of connected clients
		 */
		unsigned int client_count()
		{
			return user->GetClients().size();
		}

		/**
		 * Check if the client_count condition is met.
		 *
		 * @return True if client_count is less than client_count_less_than or if client_count_less_than is zero
		 */
		bool client_count_less_than()
		{
			unsigned int value = options["client_count_less_than"].ToUInt();
			return value == 0 || client_count() < value;
		}

		/**
		 * Determine if the given message matches any highlight rules.
		 *
		 * @param message Message contents
		 * @return True if message matches a highlight
		 */
		bool highlight(const CString& message)
		{
			CNick nick = user->GetIRCNick();

			if (message.find(nick.GetNick()) != string::npos)
			{
				return true;
			}

			return false;
		}

		/**
		 * Determine when to notify the user of a channel message.
		 *
		 * @param nick Nick that sent the message
		 * @param channel Channel the message was sent to
		 * @param message Message contents
		 * @return Notification should be sent
		 */
		bool notify_channel(const CNick& nick, const CChan& channel, const CString& message)
		{
			if (!highlight(message))
			{
				return false;
			}

			if (!client_count_less_than())
			{
				return false;
			}

			return true;
		}

		/**
		 * Determine when to notify the user of a private message.
		 *
		 * @param nick Nick that sent the message
		 * @return Notification should be sent
		 */
		bool notify_pm(const CNick& nick)
		{
			return true;
		}

	protected:

		/**
		 * Handle the plugin being loaded.  Retrieve plugin config values.
		 *
		 * @param args Plugin arguments
		 * @param message Message to show the user after loading
		 */
		bool OnLoad(const CString& args, CString& message)
		{
			for (MCString::iterator i = options.begin(); i != options.end(); i++)
			{
				CString value = GetNV(i->first);
				if (value != "")
				{
					options[i->first] = value;
				}
			}

			authencode();

			return true;
		}

		/**
		 * Handle channel messages.
		 *
		 * @param nick Nick that sent the message
		 * @param channel Channel the message was sent to
		 * @param message Message contents
		 */
		EModRet OnChanMsg(CNick& nick, CChan& channel, CString& message)
		{
			if (notify_channel(nick, channel, message))
			{
				CString title = "Highlight";
				CString msg = channel.GetName();
				msg += ": <" + nick.GetNick();
				msg += "> " + message;

				send_message(msg, title);
			}

			return CONTINUE;
		}

		/**
		 * Handle channel actions.
		 *
		 * @param nick Nick that sent the action
		 * @param channel Channel the message was sent to
		 * @param message Message contents
		 */
		EModRet OnChanAction(CNick& nick, CChan& channel, CString& message)
		{
			if (notify_channel(nick, channel, message))
			{
				CString title = "Highlight";
				CString msg = channel.GetName();
				msg += ": " + nick.GetNick();
				msg += " " + message;

				send_message(msg, title);
			}

			return CONTINUE;
		}

		/**
		 * Handle a private message.
		 *
		 * @param nick Nick that sent the message
		 * @param message Message contents
		 */
		EModRet OnPrivMsg(CNick& nick, CString& message)
		{
			if (notify_pm(nick))
			{
				CString title = "Private Message";
				CString msg = "From " + nick.GetNick();
				msg += ": " + message;

				send_message(msg, title);
			}

			return CONTINUE;
		}

		/**
		 * Handle a private action.
		 *
		 * @param nick Nick that sent the action
		 * @param message Message contents
		 */
		EModRet OnPrivAction(CNick& nick, CString& message)
		{
			if (notify_pm(nick))
			{
				CString title = "Private Message";
				CString msg = "* " + nick.GetNick();
				msg += " " + message;

				send_message(msg, title);
			}

			return CONTINUE;
		}

		/**
		 * Handle direct commands to the *notifo virtual user.
		 *
		 * @param command Command string
		 */
		void OnModCommand(const CString& command)
		{
			VCString tokens;
			int token_count = command.Split(" ", tokens, false);

			if (token_count < 1)
			{
				return;
			}

			CString action = tokens[0].AsLower();

			// SET command
			if (action == "set")
			{
				if (token_count != 3)
				{
					PutModule("Usage: set <option> <value>");
					return;
				}

				CString option = tokens[1].AsLower();
				CString value = tokens[2];
				MCString::iterator pos = options.find(option);

				if (pos == options.end())
				{
					PutModule("Error: invalid option name");
				}
				else
				{
					options[option] = value;
					SetNV(option, value);

					authencode();
				}
			}
			// GET command
			else if (action == "get")
			{
				if (token_count != 2)
				{
					PutModule("Usage: get <option>");
					return;
				}

				CString option = tokens[1].AsLower();
				MCString::iterator pos = options.find(option);

				if (pos == options.end())
				{
					PutModule("Error: invalid option name");
				}
				else
				{
					PutModule(option + CString(": \"") + options[option] + CString("\""));
				}
			}
			// SEND command
			else if (action == "send")
			{
				CString message = command.Token(1, true, " ", true);
				send_message(message);
			}
			else
			{
				PutModule("Error: invalid command");
			}
		}
};

MODULEDEFS(CNotifoMod, "Send highlights and personal messages to a Notifo account")
<|endoftext|>


<commit_before>/*!
    \file mutex.cpp
    \brief Mutex synchronization primitive implementation
    \author Ivan Shynkarenka
    \date 04.04.2016
    \copyright MIT License
*/

#include "threads/mutex.h"

#include "errors/exceptions.h"
#include "errors/fatal.h"

#include <algorithm>

#if defined(__CYGWIN__)
#include "threads/thread.h"
#endif
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
#include <pthread.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#undef max
#undef min
#endif

namespace CppCommon {

//! @cond INTERNALS

class Mutex::Impl
{
public:
    Impl()
    {
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
        int result = pthread_mutex_init(&_mutex, nullptr);
        if (result != 0)
            throwex SystemException("Failed to initialize a mutex!", result);
#elif defined(_WIN32) || defined(_WIN64)
        _mutex = CreateMutex(nullptr, FALSE, nullptr);
        if (_mutex == nullptr)
            throwex SystemException("Failed to create a mutex!");
#endif
    }

    ~Impl()
    {
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
        int result = pthread_mutex_destroy(&_mutex);
        if (result != 0)
            fatality(SystemException("Failed to destroy a mutex!", result));
#elif defined(_WIN32) || defined(_WIN64)
        if (!CloseHandle(_mutex))
            fatality(SystemException("Failed to close a mutex!"));
#endif
    }

    bool TryLock()
    {
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
        int result = pthread_mutex_trylock(&_mutex);
        if ((result != 0) && (result != EBUSY))
            throwex SystemException("Failed to try lock a mutex!", result);
        return (result == 0);
#elif defined(_WIN32) || defined(_WIN64)
        DWORD result = WaitForSingleObject(_mutex, 0);
        if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
            throwex SystemException("Failed to try lock a mutex!");
        return (result == WAIT_OBJECT_0);
#endif
    }

    bool TryLockFor(const Timespan& timespan)
    {
        if (timespan < 0)
            return TryLock();
#if defined(__APPLE__) || defined(__CYGWIN__)
        // Calculate a finish timestamp
        Timestamp finish = NanoTimestamp() + timespan;

        // Try to acquire lock at least one time
        if (TryLock())
            return true;
        else
        {
            // Try lock or yield for the given timespan
            while (NanoTimestamp() < finish)
            {
                if (TryLock())
                    return true;
                else
                    Thread::Yield();
            }

            // Failed to acquire lock
            return false;
        }
#elif defined(unix) || defined(__unix) || defined(__unix__)
        struct timespec timeout;
        timeout.tv_sec = timespan.seconds();
        timeout.tv_nsec = timespan.nanoseconds() % 1000000000;
        int result = pthread_mutex_timedlock(&_mutex, &timeout);
        if ((result != 0) && (result != ETIMEDOUT))
            throwex SystemException("Failed to try lock a mutex for the given timeout!", result);
        return (result == 0);
#elif defined(_WIN32) || defined(_WIN64)
        DWORD result = WaitForSingleObject(_mutex, std::max((DWORD)1, (DWORD)timespan.milliseconds()));
        if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
            throwex SystemException("Failed to try lock a mutex for the given timeout!");
        return (result == WAIT_OBJECT_0);
#endif
    }

    void Lock()
    {
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
        int result = pthread_mutex_lock(&_mutex);
        if (result != 0)
            throwex SystemException("Failed to lock a mutex!", result);
#elif defined(_WIN32) || defined(_WIN64)
        DWORD result = WaitForSingleObject(_mutex, INFINITE);
        if (result != WAIT_OBJECT_0)
            throwex SystemException("Failed to lock a mutex!");
#endif
    }

    void Unlock()
    {
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
        int result = pthread_mutex_unlock(&_mutex);
        if (result != 0)
            throwex SystemException("Failed to unlock a mutex!", result);
#elif defined(_WIN32) || defined(_WIN64)
        if (!ReleaseMutex(_mutex))
            throwex SystemException("Failed to unlock a mutex!");
#endif
    }

private:
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
    pthread_mutex_t _mutex;
#elif defined(_WIN32) || defined(_WIN64)
    HANDLE _mutex;
#endif
};

//! @endcond

Mutex::Mutex() : _pimpl(std::make_unique<Impl>())
{
}

Mutex::Mutex(Mutex&& mutex) noexcept : _pimpl(std::move(mutex._pimpl))
{
}

Mutex::~Mutex()
{
}

Mutex& Mutex::operator=(Mutex&& mutex) noexcept
{
    _pimpl = std::move(mutex._pimpl);
    return *this;
}

bool Mutex::TryLock()
{
    return _pimpl->TryLock();
}

bool Mutex::TryLockFor(const Timespan& timespan)
{
    return _pimpl->TryLockFor(timespan);
}

void Mutex::Lock()
{
    _pimpl->Lock();
}

void Mutex::Unlock()
{
    _pimpl->Unlock();
}

} // namespace CppCommon
<commit_msg>Fix OSX build<commit_after>/*!
    \file mutex.cpp
    \brief Mutex synchronization primitive implementation
    \author Ivan Shynkarenka
    \date 04.04.2016
    \copyright MIT License
*/

#include "threads/mutex.h"

#include "errors/exceptions.h"
#include "errors/fatal.h"

#include <algorithm>

#if defined(__APPLE__) || defined(__CYGWIN__)
#include "threads/thread.h"
#endif
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
#include <pthread.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#undef max
#undef min
#endif

namespace CppCommon {

//! @cond INTERNALS

class Mutex::Impl
{
public:
    Impl()
    {
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
        int result = pthread_mutex_init(&_mutex, nullptr);
        if (result != 0)
            throwex SystemException("Failed to initialize a mutex!", result);
#elif defined(_WIN32) || defined(_WIN64)
        _mutex = CreateMutex(nullptr, FALSE, nullptr);
        if (_mutex == nullptr)
            throwex SystemException("Failed to create a mutex!");
#endif
    }

    ~Impl()
    {
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
        int result = pthread_mutex_destroy(&_mutex);
        if (result != 0)
            fatality(SystemException("Failed to destroy a mutex!", result));
#elif defined(_WIN32) || defined(_WIN64)
        if (!CloseHandle(_mutex))
            fatality(SystemException("Failed to close a mutex!"));
#endif
    }

    bool TryLock()
    {
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
        int result = pthread_mutex_trylock(&_mutex);
        if ((result != 0) && (result != EBUSY))
            throwex SystemException("Failed to try lock a mutex!", result);
        return (result == 0);
#elif defined(_WIN32) || defined(_WIN64)
        DWORD result = WaitForSingleObject(_mutex, 0);
        if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
            throwex SystemException("Failed to try lock a mutex!");
        return (result == WAIT_OBJECT_0);
#endif
    }

    bool TryLockFor(const Timespan& timespan)
    {
        if (timespan < 0)
            return TryLock();
#if defined(__APPLE__) || defined(__CYGWIN__)
        // Calculate a finish timestamp
        Timestamp finish = NanoTimestamp() + timespan;

        // Try to acquire lock at least one time
        if (TryLock())
            return true;
        else
        {
            // Try lock or yield for the given timespan
            while (NanoTimestamp() < finish)
            {
                if (TryLock())
                    return true;
                else
                    Thread::Yield();
            }

            // Failed to acquire lock
            return false;
        }
#elif defined(unix) || defined(__unix) || defined(__unix__)
        struct timespec timeout;
        timeout.tv_sec = timespan.seconds();
        timeout.tv_nsec = timespan.nanoseconds() % 1000000000;
        int result = pthread_mutex_timedlock(&_mutex, &timeout);
        if ((result != 0) && (result != ETIMEDOUT))
            throwex SystemException("Failed to try lock a mutex for the given timeout!", result);
        return (result == 0);
#elif defined(_WIN32) || defined(_WIN64)
        DWORD result = WaitForSingleObject(_mutex, std::max((DWORD)1, (DWORD)timespan.milliseconds()));
        if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
            throwex SystemException("Failed to try lock a mutex for the given timeout!");
        return (result == WAIT_OBJECT_0);
#endif
    }

    void Lock()
    {
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
        int result = pthread_mutex_lock(&_mutex);
        if (result != 0)
            throwex SystemException("Failed to lock a mutex!", result);
#elif defined(_WIN32) || defined(_WIN64)
        DWORD result = WaitForSingleObject(_mutex, INFINITE);
        if (result != WAIT_OBJECT_0)
            throwex SystemException("Failed to lock a mutex!");
#endif
    }

    void Unlock()
    {
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
        int result = pthread_mutex_unlock(&_mutex);
        if (result != 0)
            throwex SystemException("Failed to unlock a mutex!", result);
#elif defined(_WIN32) || defined(_WIN64)
        if (!ReleaseMutex(_mutex))
            throwex SystemException("Failed to unlock a mutex!");
#endif
    }

private:
#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
    pthread_mutex_t _mutex;
#elif defined(_WIN32) || defined(_WIN64)
    HANDLE _mutex;
#endif
};

//! @endcond

Mutex::Mutex() : _pimpl(std::make_unique<Impl>())
{
}

Mutex::Mutex(Mutex&& mutex) noexcept : _pimpl(std::move(mutex._pimpl))
{
}

Mutex::~Mutex()
{
}

Mutex& Mutex::operator=(Mutex&& mutex) noexcept
{
    _pimpl = std::move(mutex._pimpl);
    return *this;
}

bool Mutex::TryLock()
{
    return _pimpl->TryLock();
}

bool Mutex::TryLockFor(const Timespan& timespan)
{
    return _pimpl->TryLockFor(timespan);
}

void Mutex::Lock()
{
    _pimpl->Lock();
}

void Mutex::Unlock()
{
    _pimpl->Unlock();
}

} // namespace CppCommon
<|endoftext|>


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

#include "net/base/directory_lister.h"

#include <algorithm>
#include <vector>

#include "base/file_util.h"
#include "base/i18n/file_util_icu.h"
#include "base/message_loop.h"
#include "base/platform_thread.h"
#include "base/thread_restrictions.h"
#include "net/base/net_errors.h"

namespace net {

static const int kFilesPerEvent = 8;

// A task which is used to signal the delegate asynchronously.
class DirectoryDataEvent : public Task {
public:
  explicit DirectoryDataEvent(DirectoryLister* d) : lister(d), error(0) {
    // Allocations of the FindInfo aren't super cheap, so reserve space.
    data.reserve(64);
  }

  void Run() {
    if (data.empty()) {
      lister->OnDone(error);
      return;
    }
    lister->OnReceivedData(&data[0], static_cast<int>(data.size()));
  }

  scoped_refptr<DirectoryLister> lister;
  std::vector<DirectoryLister::DirectoryListerData> data;
  int error;
};

// Comparator for sorting lister results. This uses the locale aware filename
// comparison function on the filenames for sorting in the user's locale.
// Static.
bool DirectoryLister::CompareAlphaDirsFirst(const DirectoryListerData& a,
                                            const DirectoryListerData& b) {
  // Parent directory before all else.
  if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(a.info)))
    return true;
  if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(b.info)))
    return false;

  // Directories before regular files.
  bool a_is_directory = file_util::FileEnumerator::IsDirectory(a.info);
  bool b_is_directory = file_util::FileEnumerator::IsDirectory(b.info);
  if (a_is_directory != b_is_directory)
    return a_is_directory;

  return file_util::LocaleAwareCompareFilenames(
      file_util::FileEnumerator::GetFilename(a.info),
      file_util::FileEnumerator::GetFilename(b.info));
}

// Static.
bool DirectoryLister::CompareDate(const DirectoryListerData& a,
                                  const DirectoryListerData& b) {
  // Parent directory before all else.
  if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(a.info)))
    return true;
  if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(b.info)))
    return false;

  // Directories before regular files.
  bool a_is_directory = file_util::FileEnumerator::IsDirectory(a.info);
  bool b_is_directory = file_util::FileEnumerator::IsDirectory(b.info);
  if (a_is_directory != b_is_directory)
    return a_is_directory;
#if defined(OS_POSIX)
  return a.info.stat.st_mtime > b.info.stat.st_mtime;
#elif defined(OS_WIN)
  if (a.info.ftLastWriteTime.dwHighDateTime ==
      b.info.ftLastWriteTime.dwHighDateTime) {
    return a.info.ftLastWriteTime.dwLowDateTime >
           b.info.ftLastWriteTime.dwLowDateTime;
  } else {
    return a.info.ftLastWriteTime.dwHighDateTime >
           b.info.ftLastWriteTime.dwHighDateTime;
  }
#endif
}

// Comparator for sorting find result by paths. This uses the locale-aware
// comparison function on the filenames for sorting in the user's locale.
// Static.
bool DirectoryLister::CompareFullPath(const DirectoryListerData& a,
                                      const DirectoryListerData& b) {
  return file_util::LocaleAwareCompareFilenames(a.path, b.path);
}

DirectoryLister::DirectoryLister(const FilePath& dir,
                                 DirectoryListerDelegate* delegate)
    : dir_(dir),
      recursive_(false),
      delegate_(delegate),
      sort_(ALPHA_DIRS_FIRST),
      message_loop_(NULL),
      thread_(kNullThreadHandle) {
  DCHECK(!dir.value().empty());
}

DirectoryLister::DirectoryLister(const FilePath& dir,
                                 bool recursive,
                                 SORT_TYPE sort,
                                 DirectoryListerDelegate* delegate)
    : dir_(dir),
      recursive_(recursive),
      delegate_(delegate),
      sort_(sort),
      message_loop_(NULL),
      thread_(kNullThreadHandle) {
  DCHECK(!dir.value().empty());
}

DirectoryLister::~DirectoryLister() {
  if (thread_) {
    // This is a bug and we should stop joining this thread.
    // http://crbug.com/65331
    base::ThreadRestrictions::ScopedAllowIO allow_io;
    PlatformThread::Join(thread_);
  }
}

bool DirectoryLister::Start() {
  // spawn a thread to enumerate the specified directory

  // pass events back to the current thread
  message_loop_ = MessageLoop::current();
  DCHECK(message_loop_) << "calling thread must have a message loop";

  AddRef();  // the thread will release us when it is done

  if (!PlatformThread::Create(0, this, &thread_)) {
    Release();
    return false;
  }

  return true;
}

void DirectoryLister::Cancel() {
  canceled_.Set();

  if (thread_) {
    PlatformThread::Join(thread_);
    thread_ = kNullThreadHandle;
  }
}

void DirectoryLister::ThreadMain() {
  DirectoryDataEvent* e = new DirectoryDataEvent(this);

  if (!file_util::DirectoryExists(dir_)) {
    e->error = net::ERR_FILE_NOT_FOUND;
    message_loop_->PostTask(FROM_HERE, e);
    Release();
    return;
  }

  int types = file_util::FileEnumerator::FILES |
              file_util::FileEnumerator::DIRECTORIES;
  if (!recursive_)
    types |= file_util::FileEnumerator::INCLUDE_DOT_DOT;

  file_util::FileEnumerator file_enum(dir_, recursive_,
      static_cast<file_util::FileEnumerator::FILE_TYPE>(types));

  FilePath path;
  while (!canceled_.IsSet() && !(path = file_enum.Next()).empty()) {
    DirectoryListerData data;
    file_enum.GetFindInfo(&data.info);
    data.path = path;
    e->data.push_back(data);

    /* TODO(brettw) bug 24107: It would be nice to send incremental updates.
       We gather them all so they can be sorted, but eventually the sorting
       should be done from JS to give more flexibility in the page. When we do
       that, we can uncomment this to send incremental updates to the page.
    if (++e->count == kFilesPerEvent) {
      message_loop_->PostTask(FROM_HERE, e);
      e = new DirectoryDataEvent(this);
    }
    */
  }

  if (!e->data.empty()) {
    // Sort the results. See the TODO above (this sort should be removed and we
    // should do it from JS).
    if (sort_ == DATE)
      std::sort(e->data.begin(), e->data.end(), CompareDate);
    else if (sort_ == FULL_PATH)
      std::sort(e->data.begin(), e->data.end(), CompareFullPath);
    else if (sort_ == ALPHA_DIRS_FIRST)
      std::sort(e->data.begin(), e->data.end(), CompareAlphaDirsFirst);
    else
      DCHECK_EQ(NO_SORT, sort_);

    message_loop_->PostTask(FROM_HERE, e);
    e = new DirectoryDataEvent(this);
  }

  // Notify done
  Release();
  message_loop_->PostTask(FROM_HERE, e);
}

void DirectoryLister::OnReceivedData(const DirectoryListerData* data,
                                     int count) {
  // Since the delegate can clear itself during the OnListFile callback, we
  // need to null check it during each iteration of the loop.  Similarly, it is
  // necessary to check the canceled_ flag to avoid sending data to a delegate
  // who doesn't want anymore.
  for (int i = 0; !canceled_.IsSet() && delegate_ && i < count; ++i)
    delegate_->OnListFile(data[i]);
}

void DirectoryLister::OnDone(int error) {
  // If canceled is set, we need to report some kind of error,
  // but don't overwrite the error condition if it is already set.
  if (!error && canceled_.IsSet())
    error = net::ERR_ABORTED;

  if (delegate_)
    delegate_->OnListDone(error);
}

}  // namespace net
<commit_msg>net::DirectoryLister: mark another buggy use of IO<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/directory_lister.h"

#include <algorithm>
#include <vector>

#include "base/file_util.h"
#include "base/i18n/file_util_icu.h"
#include "base/message_loop.h"
#include "base/platform_thread.h"
#include "base/thread_restrictions.h"
#include "net/base/net_errors.h"

namespace net {

static const int kFilesPerEvent = 8;

// A task which is used to signal the delegate asynchronously.
class DirectoryDataEvent : public Task {
public:
  explicit DirectoryDataEvent(DirectoryLister* d) : lister(d), error(0) {
    // Allocations of the FindInfo aren't super cheap, so reserve space.
    data.reserve(64);
  }

  void Run() {
    if (data.empty()) {
      lister->OnDone(error);
      return;
    }
    lister->OnReceivedData(&data[0], static_cast<int>(data.size()));
  }

  scoped_refptr<DirectoryLister> lister;
  std::vector<DirectoryLister::DirectoryListerData> data;
  int error;
};

// Comparator for sorting lister results. This uses the locale aware filename
// comparison function on the filenames for sorting in the user's locale.
// Static.
bool DirectoryLister::CompareAlphaDirsFirst(const DirectoryListerData& a,
                                            const DirectoryListerData& b) {
  // Parent directory before all else.
  if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(a.info)))
    return true;
  if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(b.info)))
    return false;

  // Directories before regular files.
  bool a_is_directory = file_util::FileEnumerator::IsDirectory(a.info);
  bool b_is_directory = file_util::FileEnumerator::IsDirectory(b.info);
  if (a_is_directory != b_is_directory)
    return a_is_directory;

  return file_util::LocaleAwareCompareFilenames(
      file_util::FileEnumerator::GetFilename(a.info),
      file_util::FileEnumerator::GetFilename(b.info));
}

// Static.
bool DirectoryLister::CompareDate(const DirectoryListerData& a,
                                  const DirectoryListerData& b) {
  // Parent directory before all else.
  if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(a.info)))
    return true;
  if (file_util::IsDotDot(file_util::FileEnumerator::GetFilename(b.info)))
    return false;

  // Directories before regular files.
  bool a_is_directory = file_util::FileEnumerator::IsDirectory(a.info);
  bool b_is_directory = file_util::FileEnumerator::IsDirectory(b.info);
  if (a_is_directory != b_is_directory)
    return a_is_directory;
#if defined(OS_POSIX)
  return a.info.stat.st_mtime > b.info.stat.st_mtime;
#elif defined(OS_WIN)
  if (a.info.ftLastWriteTime.dwHighDateTime ==
      b.info.ftLastWriteTime.dwHighDateTime) {
    return a.info.ftLastWriteTime.dwLowDateTime >
           b.info.ftLastWriteTime.dwLowDateTime;
  } else {
    return a.info.ftLastWriteTime.dwHighDateTime >
           b.info.ftLastWriteTime.dwHighDateTime;
  }
#endif
}

// Comparator for sorting find result by paths. This uses the locale-aware
// comparison function on the filenames for sorting in the user's locale.
// Static.
bool DirectoryLister::CompareFullPath(const DirectoryListerData& a,
                                      const DirectoryListerData& b) {
  return file_util::LocaleAwareCompareFilenames(a.path, b.path);
}

DirectoryLister::DirectoryLister(const FilePath& dir,
                                 DirectoryListerDelegate* delegate)
    : dir_(dir),
      recursive_(false),
      delegate_(delegate),
      sort_(ALPHA_DIRS_FIRST),
      message_loop_(NULL),
      thread_(kNullThreadHandle) {
  DCHECK(!dir.value().empty());
}

DirectoryLister::DirectoryLister(const FilePath& dir,
                                 bool recursive,
                                 SORT_TYPE sort,
                                 DirectoryListerDelegate* delegate)
    : dir_(dir),
      recursive_(recursive),
      delegate_(delegate),
      sort_(sort),
      message_loop_(NULL),
      thread_(kNullThreadHandle) {
  DCHECK(!dir.value().empty());
}

DirectoryLister::~DirectoryLister() {
  if (thread_) {
    // This is a bug and we should stop joining this thread.
    // http://crbug.com/65331
    base::ThreadRestrictions::ScopedAllowIO allow_io;
    PlatformThread::Join(thread_);
  }
}

bool DirectoryLister::Start() {
  // spawn a thread to enumerate the specified directory

  // pass events back to the current thread
  message_loop_ = MessageLoop::current();
  DCHECK(message_loop_) << "calling thread must have a message loop";

  AddRef();  // the thread will release us when it is done

  if (!PlatformThread::Create(0, this, &thread_)) {
    Release();
    return false;
  }

  return true;
}

void DirectoryLister::Cancel() {
  canceled_.Set();

  if (thread_) {
    // This is a bug and we should stop joining this thread.
    // http://crbug.com/65331
    base::ThreadRestrictions::ScopedAllowIO allow_io;
    PlatformThread::Join(thread_);
    thread_ = kNullThreadHandle;
  }
}

void DirectoryLister::ThreadMain() {
  DirectoryDataEvent* e = new DirectoryDataEvent(this);

  if (!file_util::DirectoryExists(dir_)) {
    e->error = net::ERR_FILE_NOT_FOUND;
    message_loop_->PostTask(FROM_HERE, e);
    Release();
    return;
  }

  int types = file_util::FileEnumerator::FILES |
              file_util::FileEnumerator::DIRECTORIES;
  if (!recursive_)
    types |= file_util::FileEnumerator::INCLUDE_DOT_DOT;

  file_util::FileEnumerator file_enum(dir_, recursive_,
      static_cast<file_util::FileEnumerator::FILE_TYPE>(types));

  FilePath path;
  while (!canceled_.IsSet() && !(path = file_enum.Next()).empty()) {
    DirectoryListerData data;
    file_enum.GetFindInfo(&data.info);
    data.path = path;
    e->data.push_back(data);

    /* TODO(brettw) bug 24107: It would be nice to send incremental updates.
       We gather them all so they can be sorted, but eventually the sorting
       should be done from JS to give more flexibility in the page. When we do
       that, we can uncomment this to send incremental updates to the page.
    if (++e->count == kFilesPerEvent) {
      message_loop_->PostTask(FROM_HERE, e);
      e = new DirectoryDataEvent(this);
    }
    */
  }

  if (!e->data.empty()) {
    // Sort the results. See the TODO above (this sort should be removed and we
    // should do it from JS).
    if (sort_ == DATE)
      std::sort(e->data.begin(), e->data.end(), CompareDate);
    else if (sort_ == FULL_PATH)
      std::sort(e->data.begin(), e->data.end(), CompareFullPath);
    else if (sort_ == ALPHA_DIRS_FIRST)
      std::sort(e->data.begin(), e->data.end(), CompareAlphaDirsFirst);
    else
      DCHECK_EQ(NO_SORT, sort_);

    message_loop_->PostTask(FROM_HERE, e);
    e = new DirectoryDataEvent(this);
  }

  // Notify done
  Release();
  message_loop_->PostTask(FROM_HERE, e);
}

void DirectoryLister::OnReceivedData(const DirectoryListerData* data,
                                     int count) {
  // Since the delegate can clear itself during the OnListFile callback, we
  // need to null check it during each iteration of the loop.  Similarly, it is
  // necessary to check the canceled_ flag to avoid sending data to a delegate
  // who doesn't want anymore.
  for (int i = 0; !canceled_.IsSet() && delegate_ && i < count; ++i)
    delegate_->OnListFile(data[i]);
}

void DirectoryLister::OnDone(int error) {
  // If canceled is set, we need to report some kind of error,
  // but don't overwrite the error condition if it is already set.
  if (!error && canceled_.IsSet())
    error = net::ERR_ABORTED;

  if (delegate_)
    delegate_->OnListDone(error);
}

}  // namespace net
<|endoftext|>


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

#ifndef _SFXDATWIN_HXX
#define _SFXDATWIN_HXX

#ifndef _BRWBOX_HXX
#include <brwbox.hxx>
#endif

#ifndef _BRWHEAD_HXX
#include <brwhead.hxx>
#endif

#ifndef _TIMER_HXX //autogen
#include <vcl/timer.hxx>
#endif
#ifndef _IMAGE_HXX //autogen
#include <vcl/image.hxx>
#endif
#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif
#ifndef _TRANSFER_HXX
#include "transfer.hxx"
#endif

//===================================================================

#define MIN_COLUMNWIDTH  2
#define DRAG_CRITICAL    4

DECLARE_LIST( RectangleList, Rectangle* );

//===================================================================

class ButtonFrame
{
    Rectangle   aRect;
    Rectangle   aInnerRect;
    String      aText;
    BOOL        bPressed;
    BOOL        bCurs;
    BOOL        bAbbr;
    BOOL        m_bDrawDisabled;

public:
               ButtonFrame( const Point& rPt, const Size& rSz,
                            const String &rText,
                            BOOL bPress = FALSE,
                            BOOL bCursor = FALSE,
                            BOOL bAbbreviate = TRUE,
                            BOOL _bDrawDisabled = FALSE)
                :aRect( rPt, rSz )
                ,aInnerRect( Point( aRect.Left()+1, aRect.Top()+1 ),
                            Size( aRect.GetWidth()-2, aRect.GetHeight()-2 ) )
                ,aText(rText)
                ,bPressed(bPress)
                ,bCurs(bCursor)
                ,bAbbr(bAbbreviate)
                ,m_bDrawDisabled(_bDrawDisabled)
            {
            }

    void    Draw( OutputDevice& rDev );
};

//===================================================================

class BrowserColumn
{
    USHORT              _nId;
    ULONG               _nOriginalWidth;
    ULONG               _nWidth;
    Image               _aImage;
    String              _aTitle;
    BOOL                _bFrozen;
    HeaderBarItemBits   _nFlags;

public:
                        BrowserColumn( USHORT nItemId, const Image &rImage,
                                        const String& rTitle, ULONG nWidthPixel, const Fraction& rCurrentZoom,
                                        HeaderBarItemBits nFlags );

    USHORT              GetId() const { return _nId; }

    ULONG               Width() { return _nWidth; }
    Image&              GetImage() { return _aImage; }
    String&             Title() { return _aTitle; }
    HeaderBarItemBits&  Flags() { return _nFlags; }

    BOOL                IsFrozen() const { return _bFrozen; }
    void                Freeze( BOOL bFreeze = TRUE ) { _bFrozen = bFreeze; }

    virtual void        Draw( BrowseBox& rBox, OutputDevice& rDev,
                              const Point& rPos, BOOL bCurs  );

    void                SetWidth(ULONG nNewWidthPixel, const Fraction& rCurrentZoom);
    void                ZoomChanged(const Fraction& rNewZoom);
};

//===================================================================

class BrowserDataWin
            :public Control
            ,public DragSourceHelper
            ,public DropTargetHelper
{
friend class BrowseBox;
    BrowserHeader*  pHeaderBar;     // only for BROWSER_HEADERBAR_NEW
    Window*         pEventWin;      // Window of forwarded events
    ScrollBarBox*   pCornerWin;     // Window in the corner btw the ScrollBars
    BOOL*           pDtorNotify;
    AutoTimer       aMouseTimer;    // recalls MouseMove on dragging out
    MouseEvent      aRepeatEvt;     // a MouseEvent to repeat
    Point           aLastMousePos;  // verhindert pseudo-MouseMoves

    String          aRealRowCount;  // zur Anzeige im VScrollBar

    RectangleList   aInvalidRegion; // invalidated Rectangles during !UpdateMode
    FASTBOOL        bInPaint;       // TRUE while in Paint
    FASTBOOL        bInCommand;     // TRUE while in Command
    FASTBOOL        bNoScrollBack;  // nur vorwaerts scrollen
    FASTBOOL        bNoHScroll;     // kein horizontaler Scrollbar
    FASTBOOL        bAutoHScroll;   // autohide horizontaler Scrollbar
    FASTBOOL        bAutoVScroll;   // autohide horizontaler Scrollbar
    FASTBOOL        bUpdateMode;    // nicht SV-UpdateMode wegen Invalidate()
    FASTBOOL        bAutoSizeLastCol;// last column always fills up window
    FASTBOOL        bHighlightAuto; // new auto-highlight by SetFont() etc.
    FASTBOOL        bResizeOnPaint; // outstanding resize-event
    FASTBOOL        bUpdateOnUnlock;    // Update() while locked
    FASTBOOL        bInUpdateScrollbars;    // Rekursionsschutz
    FASTBOOL        bHadRecursion;          // Rekursion war aufgetreten
    FASTBOOL        bOwnDataChangedHdl;     // dont change colors in DataChanged
    FASTBOOL        bCallingDropCallback;   // we're in a callback to AcceptDrop or ExecuteDrop curently
    USHORT          nUpdateLock;    // lock count, dont call Control::Update()!
    short           nCursorHidden;  // new conuter for DoHide/ShowCursor

public:
                    BrowserDataWin( BrowseBox* pParent );
                    ~BrowserDataWin();

    virtual void    DataChanged( const DataChangedEvent& rDCEvt );
    virtual void    Paint( const Rectangle& rRect );
    virtual void    RequestHelp( const HelpEvent& rHEvt );
    virtual void    Command( const CommandEvent& rEvt );
    virtual void    MouseButtonDown( const MouseEvent& rEvt );
    virtual void    MouseMove( const MouseEvent& rEvt );
                    DECL_LINK( RepeatedMouseMove, void * );

    virtual void    MouseButtonUp( const MouseEvent& rEvt );
    virtual void    KeyInput( const KeyEvent& rEvt );

    // DropTargetHelper overridables
    virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt );
    virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt );

    // DragSourceHelper overridables
    virtual void    StartDrag( sal_Int8 _nAction, const Point& _rPosPixel );

    BrowseEvent     CreateBrowseEvent( const Point& rPosPixel );
    void            Repaint();
    BrowseBox*      GetParent() const
                         { return (BrowseBox*) Window::GetParent(); }
    const String&   GetRealRowCount() const { return aRealRowCount; }

    void            SetUpdateMode( BOOL bMode );
    FASTBOOL        GetUpdateMode() const { return bUpdateMode; }
    void            EnterUpdateLock() { ++nUpdateLock; }
    void            LeaveUpdateLock();
    void            Update();
    void            DoOutstandingInvalidations();
    void            Invalidate();
    void            Invalidate( const Rectangle& rRect );
};

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

inline void BrowserDataWin::Repaint()
{
    if ( GetUpdateMode() )
        Update();
    Paint( Rectangle( Point(), GetOutputSizePixel() ) );
}

//===================================================================

class BrowserScrollBar: public ScrollBar
{
    ULONG           _nTip;
    ULONG           _nLastPos;
    BrowserDataWin* _pDataWin;

public:
                    BrowserScrollBar( Window* pParent, WinBits nStyle,
                                      BrowserDataWin *pDataWin )
                    :   ScrollBar( pParent, nStyle ),
                        _nTip( 0 ),
                        _nLastPos( ULONG_MAX ),
                        _pDataWin( pDataWin )
                    {}
                    //ScrollBar( Window* pParent, const ResId& rResId );

    virtual void    Tracking( const TrackingEvent& rTEvt );
    virtual void    EndScroll();
};

//===================================================================

void InitSettings_Impl( Window *pWin,
         BOOL bFont = TRUE, BOOL bForeground = TRUE, BOOL bBackground = TRUE );

//===================================================================

#ifdef DBG_MI

void DoLog_Impl( const BrowseBox *pThis, const char *pWhat, const char *pWho );
#define LOG(pThis,what,who) DoLog_Impl(pThis,what,who)

#else

#define LOG(pThis,what,who)

#endif

#endif

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

#ifndef _SFXDATWIN_HXX
#define _SFXDATWIN_HXX

#ifndef _BRWBOX_HXX
#include <brwbox.hxx>
#endif

#ifndef _BRWHEAD_HXX
#include <brwhead.hxx>
#endif

#ifndef _TIMER_HXX //autogen
#include <vcl/timer.hxx>
#endif
#ifndef _IMAGE_HXX //autogen
#include <vcl/image.hxx>
#endif
#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif
#ifndef _TRANSFER_HXX
#include "transfer.hxx"
#endif

//===================================================================

#define MIN_COLUMNWIDTH  2
#define DRAG_CRITICAL    4

DECLARE_LIST( RectangleList, Rectangle* );

//===================================================================

class ButtonFrame
{
    Rectangle   aRect;
    Rectangle   aInnerRect;
    String      aText;
    BOOL        bPressed;
    BOOL        bCurs;
    BOOL        bAbbr;
    BOOL        m_bDrawDisabled;

public:
               ButtonFrame( const Point& rPt, const Size& rSz,
                            const String &rText,
                            BOOL bPress = FALSE,
                            BOOL bCursor = FALSE,
                            BOOL bAbbreviate = TRUE,
                            BOOL _bDrawDisabled = FALSE)
                :aRect( rPt, rSz )
                ,aInnerRect( Point( aRect.Left()+1, aRect.Top()+1 ),
                            Size( aRect.GetWidth()-2, aRect.GetHeight()-2 ) )
                ,aText(rText)
                ,bPressed(bPress)
                ,bCurs(bCursor)
                ,bAbbr(bAbbreviate)
                ,m_bDrawDisabled(_bDrawDisabled)
            {
            }

    void    Draw( OutputDevice& rDev );
};

//===================================================================

class BrowserColumn
{
    USHORT              _nId;
    ULONG               _nOriginalWidth;
    ULONG               _nWidth;
    Image               _aImage;
    String              _aTitle;
    BOOL                _bFrozen;
    HeaderBarItemBits   _nFlags;

public:
                        BrowserColumn( USHORT nItemId, const Image &rImage,
                                        const String& rTitle, ULONG nWidthPixel, const Fraction& rCurrentZoom,
                                        HeaderBarItemBits nFlags );

    USHORT              GetId() const { return _nId; }

    ULONG               Width() { return _nWidth; }
    Image&              GetImage() { return _aImage; }
    String&             Title() { return _aTitle; }
    HeaderBarItemBits&  Flags() { return _nFlags; }

    BOOL                IsFrozen() const { return _bFrozen; }
    void                Freeze( BOOL bFreeze = TRUE ) { _bFrozen = bFreeze; }

    virtual void        Draw( BrowseBox& rBox, OutputDevice& rDev,
                              const Point& rPos, BOOL bCurs  );

    void                SetWidth(ULONG nNewWidthPixel, const Fraction& rCurrentZoom);
    void                ZoomChanged(const Fraction& rNewZoom);
};

//===================================================================

class BrowserDataWin
            :public Control
            ,public DragSourceHelper
            ,public DropTargetHelper
{
friend class BrowseBox;
    BrowserHeader*  pHeaderBar;     // only for BROWSER_HEADERBAR_NEW
    Window*         pEventWin;      // Window of forwarded events
    ScrollBarBox*   pCornerWin;     // Window in the corner btw the ScrollBars
    BOOL*           pDtorNotify;
    AutoTimer       aMouseTimer;    // recalls MouseMove on dragging out
    MouseEvent      aRepeatEvt;     // a MouseEvent to repeat
    Point           aLastMousePos;  // verhindert pseudo-MouseMoves

    String          aRealRowCount;  // zur Anzeige im VScrollBar

    RectangleList   aInvalidRegion; // invalidated Rectangles during !UpdateMode
    FASTBOOL        bInPaint;       // TRUE while in Paint
    FASTBOOL        bInCommand;     // TRUE while in Command
    FASTBOOL        bNoScrollBack;  // nur vorwaerts scrollen
    FASTBOOL        bNoHScroll;     // kein horizontaler Scrollbar
    FASTBOOL        bAutoHScroll;   // autohide horizontaler Scrollbar
    FASTBOOL        bAutoVScroll;   // autohide horizontaler Scrollbar
    FASTBOOL        bUpdateMode;    // nicht SV-UpdateMode wegen Invalidate()
    FASTBOOL        bAutoSizeLastCol;// last column always fills up window
    FASTBOOL        bHighlightAuto; // new auto-highlight by SetFont() etc.
    FASTBOOL        bResizeOnPaint; // outstanding resize-event
    FASTBOOL        bUpdateOnUnlock;    // Update() while locked
    FASTBOOL        bInUpdateScrollbars;    // Rekursionsschutz
    FASTBOOL        bHadRecursion;          // Rekursion war aufgetreten
    FASTBOOL        bOwnDataChangedHdl;     // dont change colors in DataChanged
    FASTBOOL        bCallingDropCallback;   // we're in a callback to AcceptDrop or ExecuteDrop curently
    USHORT          nUpdateLock;    // lock count, dont call Control::Update()!
    short           nCursorHidden;  // new conuter for DoHide/ShowCursor

    long            m_nDragRowDividerLimit;
    long            m_nDragRowDividerOffset;

public:
                    BrowserDataWin( BrowseBox* pParent );
                    ~BrowserDataWin();

    virtual void    DataChanged( const DataChangedEvent& rDCEvt );
    virtual void    Paint( const Rectangle& rRect );
    virtual void    RequestHelp( const HelpEvent& rHEvt );
    virtual void    Command( const CommandEvent& rEvt );
    virtual void    MouseButtonDown( const MouseEvent& rEvt );
    virtual void    MouseMove( const MouseEvent& rEvt );
                    DECL_LINK( RepeatedMouseMove, void * );

    virtual void    MouseButtonUp( const MouseEvent& rEvt );
    virtual void    KeyInput( const KeyEvent& rEvt );
    virtual void    Tracking( const TrackingEvent& rTEvt );

    // DropTargetHelper overridables
    virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt );
    virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt );

    // DragSourceHelper overridables
    virtual void    StartDrag( sal_Int8 _nAction, const Point& _rPosPixel );

    BrowseEvent     CreateBrowseEvent( const Point& rPosPixel );
    void            Repaint();
    BrowseBox*      GetParent() const
                         { return (BrowseBox*) Window::GetParent(); }
    const String&   GetRealRowCount() const { return aRealRowCount; }

    void            SetUpdateMode( BOOL bMode );
    FASTBOOL        GetUpdateMode() const { return bUpdateMode; }
    void            EnterUpdateLock() { ++nUpdateLock; }
    void            LeaveUpdateLock();
    void            Update();
    void            DoOutstandingInvalidations();
    void            Invalidate();
    void            Invalidate( const Rectangle& rRect );

protected:
    void            StartRowDividerDrag( const Point& _rStartPos );
    BOOL            ImplRowDividerHitTest( const BrowserMouseEvent& _rEvent );
};

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

inline void BrowserDataWin::Repaint()
{
    if ( GetUpdateMode() )
        Update();
    Paint( Rectangle( Point(), GetOutputSizePixel() ) );
}

//===================================================================

class BrowserScrollBar: public ScrollBar
{
    ULONG           _nTip;
    ULONG           _nLastPos;
    BrowserDataWin* _pDataWin;

public:
                    BrowserScrollBar( Window* pParent, WinBits nStyle,
                                      BrowserDataWin *pDataWin )
                    :   ScrollBar( pParent, nStyle ),
                        _nTip( 0 ),
                        _nLastPos( ULONG_MAX ),
                        _pDataWin( pDataWin )
                    {}
                    //ScrollBar( Window* pParent, const ResId& rResId );

    virtual void    Tracking( const TrackingEvent& rTEvt );
    virtual void    EndScroll();
};

//===================================================================

void InitSettings_Impl( Window *pWin,
         BOOL bFont = TRUE, BOOL bForeground = TRUE, BOOL bBackground = TRUE );

//===================================================================

#ifdef DBG_MI

void DoLog_Impl( const BrowseBox *pThis, const char *pWhat, const char *pWho );
#define LOG(pThis,what,who) DoLog_Impl(pThis,what,who)

#else

#define LOG(pThis,what,who)

#endif

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cuitbxform.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-26 07:28:28 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#ifdef SVX_DLLIMPLEMENTATION
#undef SVX_DLLIMPLEMENTATION
#endif

#include <string> // HACK: prevent conflict between STLPORT and Workshop headers

#ifndef _REF_HXX
#include <tools/ref.hxx>
#endif
#ifndef _SHL_HXX
#include <tools/shl.hxx>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SV_TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif
#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _SVX_FMITEMS_HXX //autogen
#include "fmitems.hxx"
#endif

#ifndef _SV_SOUND_HXX //autogen
#include <vcl/sound.hxx>
#endif

#ifndef _SVX_DIALMGR_HXX
#include "dialmgr.hxx"
#endif
#ifndef _SVX_DIALOGS_HRC
#include "dialogs.hrc"
#endif
/*
#ifndef _TBXCTL_HXX
#include "tbxctl.hxx"
#endif
#ifndef _TBXDRAW_HXX
#include "tbxdraw.hxx"
#endif
*/
#ifndef _CUI_TBXFORM_HXX
#include "cuitbxform.hxx"
#endif
#ifndef _SVX_FMRESIDS_HRC
#include "fmresids.hrc"
#endif
#ifndef _SVX_FMITEMS_HXX
#include "fmitems.hxx"
#endif
#ifndef _SVX_FMHELP_HRC
#include "fmhelp.hrc"
#endif
#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif
#ifndef _SFXVIEWSH_HXX
#include <sfx2/viewsh.hxx>
#endif
//========================================================================
// class FmInputRecordNoDialog
//========================================================================

FmInputRecordNoDialog::FmInputRecordNoDialog(Window * pParent)
    :ModalDialog( pParent, SVX_RES(RID_SVX_DLG_INPUTRECORDNO))
    ,m_aLabel(this, SVX_RES(1))
    ,m_aRecordNo(this, SVX_RES(1))
    ,m_aOk(this, SVX_RES(1))
    ,m_aCancel(this, SVX_RES(1))
{
    m_aRecordNo.SetMin(1);
    m_aRecordNo.SetMax(0x7FFFFFFF);
    m_aRecordNo.SetStrictFormat(TRUE);
    m_aRecordNo.SetDecimalDigits(0);

    FreeResource();
}
<commit_msg>INTEGRATION: CWS vgbugs07 (1.8.50); FILE MERGED 2007/06/04 13:26:15 vg 1.8.50.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cuitbxform.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 16:59:30 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#ifdef SVX_DLLIMPLEMENTATION
#undef SVX_DLLIMPLEMENTATION
#endif

#include <string> // HACK: prevent conflict between STLPORT and Workshop headers

#ifndef _REF_HXX
#include <tools/ref.hxx>
#endif
#ifndef _SHL_HXX
#include <tools/shl.hxx>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SV_TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif
#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif
#ifndef _SVX_FMITEMS_HXX //autogen
#include "fmitems.hxx"
#endif

#ifndef _SV_SOUND_HXX //autogen
#include <vcl/sound.hxx>
#endif

#ifndef _SVX_DIALMGR_HXX
#include <svx/dialmgr.hxx>
#endif
#ifndef _SVX_DIALOGS_HRC
#include <svx/dialogs.hrc>
#endif
/*
#ifndef _TBXCTL_HXX
#include "tbxctl.hxx"
#endif
#ifndef _TBXDRAW_HXX
#include "tbxdraw.hxx"
#endif
*/
#ifndef _CUI_TBXFORM_HXX
#include "cuitbxform.hxx"
#endif
#ifndef _SVX_FMRESIDS_HRC
#include "fmresids.hrc"
#endif
#ifndef _SVX_FMITEMS_HXX
#include "fmitems.hxx"
#endif
#ifndef _SVX_FMHELP_HRC
#include "fmhelp.hrc"
#endif
#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif
#ifndef _SFXVIEWSH_HXX
#include <sfx2/viewsh.hxx>
#endif
//========================================================================
// class FmInputRecordNoDialog
//========================================================================

FmInputRecordNoDialog::FmInputRecordNoDialog(Window * pParent)
    :ModalDialog( pParent, SVX_RES(RID_SVX_DLG_INPUTRECORDNO))
    ,m_aLabel(this, SVX_RES(1))
    ,m_aRecordNo(this, SVX_RES(1))
    ,m_aOk(this, SVX_RES(1))
    ,m_aCancel(this, SVX_RES(1))
{
    m_aRecordNo.SetMin(1);
    m_aRecordNo.SetMax(0x7FFFFFFF);
    m_aRecordNo.SetStrictFormat(TRUE);
    m_aRecordNo.SetDecimalDigits(0);

    FreeResource();
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <svx/camera3d.hxx>
#include <tools/stream.hxx>

Camera3D::Camera3D(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt,
                   double fFocalLen, double fBankAng) :
    aResetPos(rPos),
    aResetLookAt(rLookAt),
    fResetFocalLength(fFocalLen),
    fResetBankAngle(fBankAng),
    fBankAngle(fBankAng),
    bAutoAdjustProjection(sal_True)
{
    SetVPD(0);
    SetPosition(rPos);
    SetLookAt(rLookAt);
    SetFocalLength(fFocalLen);
}

Camera3D::Camera3D()
{
    basegfx::B3DPoint aVector3D(0.0 ,0.0 ,1.0);
    Camera3D(aVector3D, basegfx::B3DPoint());
}

// Set default values for reset

void Camera3D::SetDefaults(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt,
                            double fFocalLen, double fBankAng)
{
    aResetPos           = rPos;
    aResetLookAt        = rLookAt;
    fResetFocalLength   = fFocalLen;
    fResetBankAngle     = fBankAng;
}

// Set ViewWindow and adjust PRP

void Camera3D::SetViewWindow(double fX, double fY, double fW, double fH)
{
    Viewport3D::SetViewWindow(fX, fY, fW, fH);
    if ( bAutoAdjustProjection )
        SetFocalLength(fFocalLength);
}

void Camera3D::SetPosition(const basegfx::B3DPoint& rNewPos)
{
    if ( rNewPos != aPosition )
    {
        aPosition = rNewPos;
        SetVRP(aPosition);
        SetVPN(aPosition - aLookAt);
        SetBankAngle(fBankAngle);
    }
}

void Camera3D::SetLookAt(const basegfx::B3DPoint& rNewLookAt)
{
    if ( rNewLookAt != aLookAt )
    {
        aLookAt = rNewLookAt;
        SetVPN(aPosition - aLookAt);
        SetBankAngle(fBankAngle);
    }
}

void Camera3D::SetPosAndLookAt(const basegfx::B3DPoint& rNewPos,
                               const basegfx::B3DPoint& rNewLookAt)
{
    if ( rNewPos != aPosition || rNewLookAt != aLookAt )
    {
        aPosition = rNewPos;
        aLookAt = rNewLookAt;

        SetVRP(aPosition);
        SetVPN(aPosition - aLookAt);
        SetBankAngle(fBankAngle);
    }
}

void Camera3D::SetBankAngle(double fAngle)
{
    basegfx::B3DVector aDiff(aPosition - aLookAt);
    basegfx::B3DVector aPrj(aDiff);
    fBankAngle = fAngle;

    if ( aDiff.getY() == 0 )
    {
        aPrj.setY(-1.0);
    }
    else
    {   // aPrj = Projection from aDiff on the XZ-plane
        aPrj.setY(0.0);

        if ( aDiff.getY() < 0.0 )
        {
            aPrj = -aPrj;
        }
    }

    // Calculate from aDiff to uppwards pointing View-Up-Vector
    aPrj = aPrj.getPerpendicular(aDiff);
    aDiff.normalize();

    // Rotate on Z axis, to rotate the BankAngle and back
    basegfx::B3DHomMatrix aTf;
    const double fV(sqrt(aDiff.getY() * aDiff.getY() + aDiff.getZ() * aDiff.getZ()));

    if ( fV != 0.0 )
    {
        basegfx::B3DHomMatrix aTemp;
        const double fSin(aDiff.getY() / fV);
        const double fCos(aDiff.getZ() / fV);

        aTemp.set(1, 1, fCos);
        aTemp.set(2, 2, fCos);
        aTemp.set(2, 1, fSin);
        aTemp.set(1, 2, -fSin);

        aTf *= aTemp;
    }

    {
        basegfx::B3DHomMatrix aTemp;
        const double fSin(-aDiff.getX());
        const double fCos(fV);

        aTemp.set(0, 0, fCos);
        aTemp.set(2, 2, fCos);
        aTemp.set(0, 2, fSin);
        aTemp.set(2, 0, -fSin);

        aTf *= aTemp;
    }

    aTf.rotate(0.0, 0.0, fBankAngle);

    {
        basegfx::B3DHomMatrix aTemp;
        const double fSin(aDiff.getX());
        const double fCos(fV);

        aTemp.set(0, 0, fCos);
        aTemp.set(2, 2, fCos);
        aTemp.set(0, 2, fSin);
        aTemp.set(2, 0, -fSin);

        aTf *= aTemp;
    }

    if ( fV != 0.0 )
    {
        basegfx::B3DHomMatrix aTemp;
        const double fSin(-aDiff.getY() / fV);
        const double fCos(aDiff.getZ() / fV);

        aTemp.set(1, 1, fCos);
        aTemp.set(2, 2, fCos);
        aTemp.set(2, 1, fSin);
        aTemp.set(1, 2, -fSin);

        aTf *= aTemp;
    }

    SetVUV(aTf * aPrj);
}

void Camera3D::SetFocalLength(double fLen)
{
    if ( fLen < 5 )
        fLen = 5;
    SetPRP(basegfx::B3DPoint(0.0, 0.0, fLen / 35.0 * aViewWin.W));
    fFocalLength = fLen;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>reintroduce removed line, fdo#62402<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <svx/camera3d.hxx>
#include <tools/stream.hxx>

Camera3D::Camera3D(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt,
                   double fFocalLen, double fBankAng) :
    aResetPos(rPos),
    aResetLookAt(rLookAt),
    fResetFocalLength(fFocalLen),
    fResetBankAngle(fBankAng),
    fBankAngle(fBankAng),
    bAutoAdjustProjection(sal_True)
{
    SetVPD(0);
    SetPosition(rPos);
    SetLookAt(rLookAt);
    SetFocalLength(fFocalLen);
}

Camera3D::Camera3D()
{
    basegfx::B3DPoint aVector3D(0.0 ,0.0 ,1.0);
    Camera3D(aVector3D, basegfx::B3DPoint());
}

// Set default values for reset

void Camera3D::SetDefaults(const basegfx::B3DPoint& rPos, const basegfx::B3DPoint& rLookAt,
                            double fFocalLen, double fBankAng)
{
    aResetPos           = rPos;
    aResetLookAt        = rLookAt;
    fResetFocalLength   = fFocalLen;
    fResetBankAngle     = fBankAng;
}

// Set ViewWindow and adjust PRP

void Camera3D::SetViewWindow(double fX, double fY, double fW, double fH)
{
    Viewport3D::SetViewWindow(fX, fY, fW, fH);
    if ( bAutoAdjustProjection )
        SetFocalLength(fFocalLength);
}

void Camera3D::SetPosition(const basegfx::B3DPoint& rNewPos)
{
    if ( rNewPos != aPosition )
    {
        aPosition = rNewPos;
        SetVRP(aPosition);
        SetVPN(aPosition - aLookAt);
        SetBankAngle(fBankAngle);
    }
}

void Camera3D::SetLookAt(const basegfx::B3DPoint& rNewLookAt)
{
    if ( rNewLookAt != aLookAt )
    {
        aLookAt = rNewLookAt;
        SetVPN(aPosition - aLookAt);
        SetBankAngle(fBankAngle);
    }
}

void Camera3D::SetPosAndLookAt(const basegfx::B3DPoint& rNewPos,
                               const basegfx::B3DPoint& rNewLookAt)
{
    if ( rNewPos != aPosition || rNewLookAt != aLookAt )
    {
        aPosition = rNewPos;
        aLookAt = rNewLookAt;

        SetVRP(aPosition);
        SetVPN(aPosition - aLookAt);
        SetBankAngle(fBankAngle);
    }
}

void Camera3D::SetBankAngle(double fAngle)
{
    basegfx::B3DVector aDiff(aPosition - aLookAt);
    basegfx::B3DVector aPrj(aDiff);
    fBankAngle = fAngle;

    if ( aDiff.getY() == 0 )
    {
        aPrj.setY(-1.0);
    }
    else
    {   // aPrj = Projection from aDiff on the XZ-plane
        aPrj.setY(0.0);

        if ( aDiff.getY() < 0.0 )
        {
            aPrj = -aPrj;
        }
    }

    // Calculate from aDiff to uppwards pointing View-Up-Vector
    // duplicated line is intentional!
    aPrj = aPrj.getPerpendicular(aDiff);
    aPrj = aPrj.getPerpendicular(aDiff);
    aDiff.normalize();

    // Rotate on Z axis, to rotate the BankAngle and back
    basegfx::B3DHomMatrix aTf;
    const double fV(sqrt(aDiff.getY() * aDiff.getY() + aDiff.getZ() * aDiff.getZ()));

    if ( fV != 0.0 )
    {
        basegfx::B3DHomMatrix aTemp;
        const double fSin(aDiff.getY() / fV);
        const double fCos(aDiff.getZ() / fV);

        aTemp.set(1, 1, fCos);
        aTemp.set(2, 2, fCos);
        aTemp.set(2, 1, fSin);
        aTemp.set(1, 2, -fSin);

        aTf *= aTemp;
    }

    {
        basegfx::B3DHomMatrix aTemp;
        const double fSin(-aDiff.getX());
        const double fCos(fV);

        aTemp.set(0, 0, fCos);
        aTemp.set(2, 2, fCos);
        aTemp.set(0, 2, fSin);
        aTemp.set(2, 0, -fSin);

        aTf *= aTemp;
    }

    aTf.rotate(0.0, 0.0, fBankAngle);

    {
        basegfx::B3DHomMatrix aTemp;
        const double fSin(aDiff.getX());
        const double fCos(fV);

        aTemp.set(0, 0, fCos);
        aTemp.set(2, 2, fCos);
        aTemp.set(0, 2, fSin);
        aTemp.set(2, 0, -fSin);

        aTf *= aTemp;
    }

    if ( fV != 0.0 )
    {
        basegfx::B3DHomMatrix aTemp;
        const double fSin(-aDiff.getY() / fV);
        const double fCos(aDiff.getZ() / fV);

        aTemp.set(1, 1, fCos);
        aTemp.set(2, 2, fCos);
        aTemp.set(2, 1, fSin);
        aTemp.set(1, 2, -fSin);

        aTf *= aTemp;
    }

    SetVUV(aTf * aPrj);
}

void Camera3D::SetFocalLength(double fLen)
{
    if ( fLen < 5 )
        fLen = 5;
    SetPRP(basegfx::B3DPoint(0.0, 0.0, fLen / 35.0 * aViewWin.W));
    fFocalLength = fLen;
}

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


<commit_before>/*
 * LAMG.cpp
 *
 *  Created on: 12.11.2014
 *      Author: Michael Wegner (michael.wegner@student.kit.edu)
 */

#include "LAMG.h"

namespace NetworKit {

std::vector<bool> LAMG::lowDegreeNodes(const Matrix &matrix) {
	std::vector<bool> eliminate(matrix.numberOfRows(), true);
	for (index i = 0; i < matrix.numberOfRows(); ++i) {
		if (matrix.nnzInRow(i) <= 4 && eliminate[i]) {
			matrix.forNonZeroElementsInRow(i, [&](index i, index j, edgeweight w){
				eliminate[j] = false;
			});
		}
	}

	return eliminate;
}

std::vector<Vector> LAMG::computeTestVectors(const Matrix &matrix, const count numberOfVectors) const {
	std::vector<Vector> testVectors(numberOfVectors, Vector(matrix.numberOfColumns()));
	Vector zeroVector(matrix.numberOfColumns(), 0.0);
	for (count i = 0; i < numberOfVectors; ++i) {
		for (count j = 0; j < matrix.numberOfColumns(); ++j) {
			testVectors[i][j] = Aux::Random::real(-1.0, 1.0);
		}

		// do 3 GS sweeps on the system Av = 0
		testVectors[i] = smoother.relax(matrix, zeroVector, testVectors[i], 3);
	}

	return testVectors;
}

Matrix LAMG::computeAffinityMatrix(const Matrix &matrix, const std::vector<Vector> &testVectors) const {
	assert(testVectors.size() > 0);
	Matrix C(matrix.numberOfRows(), matrix.numberOfColumns());
	matrix.forNonZeroElementsInRowOrder([&](index i, index j, edgeweight value){
		if (j < i) continue; // symmetric
		double ij = 0.0;
		double ii = 0.0;
		double jj = 0.0;
		for (count k = 0; k < testVectors.size(); ++k) {
			ii += testVectors[k][i] * testVectors[k][i];
			jj += testVectors[k][j] * testVectors[k][j];
			ij += testVectors[k][i] * testVectors[k][j];
		}

		double weight = (ij * ij) / (ii*ii * jj*jj);

		C.setValue(i, j, weight);
		C.setValue(j, i, weight); // symmetric
	});

	return C;
}

bool LAMG::addEliminationLevel(Matrix &matrix, LAMGHierarchy &hierarchy) {
	bool nodesEliminated = false;

	Matrix P = DiagonalMatrix(matrix.numberOfRows());
	while (matrix.numberOfRows() > 1) {
		std::vector<bool> eliminate = lowDegreeNodes(matrix);
		if (eliminate.size() < 0.01 * matrix.numberOfRows()) {
			if (nodesEliminated) { // add level if nodes have been eliminated
				hierarchy.addLevel(matrix, P, LAMGHierarchy::ELIMINATION);
			}
			return nodesEliminated;
		}

		count numFNodes = eliminate.size();
		count numCNodes = matrix.numberOfRows() - numFNodes;

		// calculate matrix S = {(-A_FC^T * A_FF^-1)^T, Ic} and permutation matrix M
		Matrix S(matrix.numberOfRows(), numCNodes);
		Matrix M(matrix.numberOfRows());

		index fIndex = 0;
		index cIndex = numFNodes;
		for (index i = 0; i < matrix.numberOfRows(); ++i) {
			if (eliminate[i]) {
				matrix.forNonZeroElementsInRow(i, [&](index i, index j, edgeweight value){ // (-A_FC^T * A_FF^-1)^T in row i
					S.setValue(fIndex, j, -value / matrix.nnzInRow(i));
				});

				M.setValue(i, fIndex, 1);
				fIndex++;
			} else {
				S.setValue(cIndex, cIndex - numFNodes, 1);
				M.setValue(i, cIndex, 1);
				cIndex++;
			}
		}

		// compute P
		Matrix P_iteration = M * S;

		// compute coarsened matrix and add level
		matrix = Matrix::mTmMultiply(P_iteration, matrix * P_iteration);
		P = P * P_iteration;
	}

	if (nodesEliminated) { // add level if nodes have been eliminated
		hierarchy.addLevel(matrix, P);
	}

	return nodesEliminated;
}

bool LAMG::addAggregationLevel(Matrix &matrix, LAMGHierarchy &hierarchy) {
	// TODO
	return false;
}

LAMGHierarchy LAMG::buildHierarchy(const Graph &graph) {
	return LAMGHierarchy();
}

LAMGHierarchy LAMG::buildHierarchy(const Matrix &matrix) {
	return LAMGHierarchy();
}

} /* namespace NetworKit */
<commit_msg>fixed error in affinity calculation<commit_after>/*
 * LAMG.cpp
 *
 *  Created on: 12.11.2014
 *      Author: Michael Wegner (michael.wegner@student.kit.edu)
 */

#include "LAMG.h"

namespace NetworKit {

std::vector<bool> LAMG::lowDegreeNodes(const Matrix &matrix) {
	std::vector<bool> eliminate(matrix.numberOfRows(), true);
	for (index i = 0; i < matrix.numberOfRows(); ++i) {
		if (matrix.nnzInRow(i) <= 4 && eliminate[i]) {
			matrix.forNonZeroElementsInRow(i, [&](index i, index j, edgeweight w){
				eliminate[j] = false;
			});
		}
	}

	return eliminate;
}

std::vector<Vector> LAMG::computeTestVectors(const Matrix &matrix, const count numberOfVectors) const {
	std::vector<Vector> testVectors(numberOfVectors, Vector(matrix.numberOfColumns()));
	Vector zeroVector(matrix.numberOfColumns(), 0.0);
	for (count i = 0; i < numberOfVectors; ++i) {
		for (count j = 0; j < matrix.numberOfColumns(); ++j) {
			testVectors[i][j] = Aux::Random::real(-1.0, 1.0);
		}

		// do 3 GS sweeps on the system Av = 0
		testVectors[i] = smoother.relax(matrix, zeroVector, testVectors[i], 3);
	}

	return testVectors;
}

Matrix LAMG::computeAffinityMatrix(const Matrix &matrix, const std::vector<Vector> &testVectors) const {
	assert(testVectors.size() > 0);
	Matrix C(matrix.numberOfRows(), matrix.numberOfColumns());
	matrix.forNonZeroElementsInRowOrder([&](index i, index j, edgeweight value){
		if (j >= i) {  // symmetric
			double ij = 0.0;
			double ii = 0.0;
			double jj = 0.0;
			for (count k = 0; k < testVectors.size(); ++k) {
				ii += testVectors[k][i] * testVectors[k][i];
				jj += testVectors[k][j] * testVectors[k][j];
				ij += testVectors[k][i] * testVectors[k][j];
			}

			double weight = (ij * ij) / (ii*ii * jj*jj);

			C.setValue(i, j, weight);
			C.setValue(j, i, weight); // symmetric
		}
	});

	return C;
}

bool LAMG::addEliminationLevel(Matrix &matrix, LAMGHierarchy &hierarchy) {
	bool nodesEliminated = false;

	Matrix P = DiagonalMatrix(matrix.numberOfRows());
	while (matrix.numberOfRows() > 1) {
		std::vector<bool> eliminate = lowDegreeNodes(matrix);
		if (eliminate.size() < 0.01 * matrix.numberOfRows()) {
			if (nodesEliminated) { // add level if nodes have been eliminated
				hierarchy.addLevel(matrix, P, LAMGHierarchy::ELIMINATION);
			}
			return nodesEliminated;
		}

		count numFNodes = eliminate.size();
		count numCNodes = matrix.numberOfRows() - numFNodes;

		// calculate matrix S = {(-A_FC^T * A_FF^-1)^T, Ic} and permutation matrix M
		Matrix S(matrix.numberOfRows(), numCNodes);
		Matrix M(matrix.numberOfRows());

		index fIndex = 0;
		index cIndex = numFNodes;
		for (index i = 0; i < matrix.numberOfRows(); ++i) {
			if (eliminate[i]) {
				matrix.forNonZeroElementsInRow(i, [&](index i, index j, edgeweight value){ // (-A_FC^T * A_FF^-1)^T in row i
					S.setValue(fIndex, j, -value / matrix.nnzInRow(i));
				});

				M.setValue(i, fIndex, 1);
				fIndex++;
			} else {
				S.setValue(cIndex, cIndex - numFNodes, 1);
				M.setValue(i, cIndex, 1);
				cIndex++;
			}
		}

		// compute P
		Matrix P_iteration = M * S;

		// compute coarsened matrix and add level
		matrix = Matrix::mTmMultiply(P_iteration, matrix * P_iteration);
		P = P * P_iteration;
	}

	if (nodesEliminated) { // add level if nodes have been eliminated
		hierarchy.addLevel(matrix, P);
	}

	return nodesEliminated;
}

bool LAMG::addAggregationLevel(Matrix &matrix, LAMGHierarchy &hierarchy) {
	// TODO
	return false;
}

LAMGHierarchy LAMG::buildHierarchy(const Graph &graph) {
	return LAMGHierarchy();
}

LAMGHierarchy LAMG::buildHierarchy(const Matrix &matrix) {
	return LAMGHierarchy();
}

} /* namespace NetworKit */
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 11/9/2019, 9:10:42 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
constexpr ll MOD{1000000007LL};
constexpr ll MAX_SIZE{3000010LL};
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// for C++14
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

using Info = tuple<int, int>;

int main()
{
  int N;
  cin >> N;
  vector<int> A(N), B(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  for (auto i = 0; i < N; i++)
  {
    cin >> B[i];
  }
  vector<Info> V(N);
  for (auto i = 0; i < N; i++)
  {
    V[i] = Info(B[i], A[i]);
  }
  sort(V.begin(), V.end());
  sort(A.begin(), A.end());
  sort(B.begin(), B.end());
  for (auto i = 0; i < N; i++)
  {
    if (A[i] > B[i])
    {
      No();
    }
  }
  vector<bool> C(N, true);
  for (auto i = 1; i < N; i++)
  {
    C[i] = (A[i] <= B[i - 1]);
  }
  vector<int> sum(N + 1, 0);
  for (auto i = 0; i < N; i++)
  {
    int t{C[i] ? 0 : 1};
    sum[i + 1] = sum[i] + t;
  }
  for (auto k = 0; k < N; k++)
  {
    int x{get<1>(V[k])};
    int y{get<0>(V[k])};
    if (x > y)
    {
      continue;
    }
    auto it_a{upper_bound(A.begin(), A.end(), x)};
    --it_a;
    assert(*it_a == x);
    auto it_b{lower_bound(B.begin(), B.end(), y)};
    assert(*it_b == y);
    int num_a(it_a - A.begin());
    int num_b(it_b - B.begin());
    if (num_b <= num_a)
    {
      Yes();
    }
    else
    {
      if (sum[num_b + 1] - sum[num_a + 1] == 0)
      {
        Yes();
      }
    }
  }
  No();
}<commit_msg>submit C.cpp to 'C - Swaps' (nikkei2019-2-qual) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1
/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 11/9/2019, 9:10:42 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
constexpr ll MOD{1000000007LL};
constexpr ll MAX_SIZE{3000010LL};
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// for C++14
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

using Info = tuple<int, int>;

int main()
{
  int N;
  cin >> N;
  vector<int> A(N), B(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  for (auto i = 0; i < N; i++)
  {
    cin >> B[i];
  }
  vector<Info> V(N);
  for (auto i = 0; i < N; i++)
  {
    V[i] = Info(B[i], A[i]);
  }
  sort(A.begin(), A.end());
  sort(B.begin(), B.end());
  for (auto i = 0; i < N; i++)
  {
    if (A[i] > B[i])
    {
      No();
    }
  }
  vector<bool> C(N, true);
  for (auto i = 1; i < N; i++)
  {
    C[i] = (A[i] <= B[i - 1]);
  }
  vector<int> sum(N, 0);
  for (auto i = 1; i < N; i++)
  {
    int t{C[i] ? 0 : 1};
    sum[i] = sum[i - 1] + t;
  }
  for (auto k = 0; k < N; k++)
  {
    int x{get<1>(V[k])};
    int y{get<0>(V[k])};
    if (x > y)
    {
      continue;
    }
    auto it_a{upper_bound(A.begin(), A.end(), x)};
    --it_a;
    assert(*it_a == x);
    auto it_b{lower_bound(B.begin(), B.end(), y)};
    assert(*it_b == y);
    int num_a(it_a - A.begin());
    int num_b(it_b - B.begin());
    if (num_b <= num_a)
    {
      Yes();
    }
    else
    {
      if (sum[num_b + 1] - sum[num_a] == 0)
      {
        Yes();
      }
    }
  }
  No();
}<|endoftext|>