<commit_before>// ffmpeg player output (portaudio)
// part of MusicPlayer, https://github.com/albertz/music-player
// Copyright (c) 2012, Albert Zeyer, www.az2000.de
// All rights reserved.
// This code is under the 2-clause BSD license, see License.txt in the root directory of this project.

#include "ffmpeg.h"

#include <portaudio.h>
#include <boost/bind.hpp>

#ifdef __APPLE__
// PortAudio specific Mac stuff
#include "pa_mac_core.h"
#endif

// For setting the thread priority to realtime on MacOSX.
#ifdef __APPLE__
#include <mach/mach_init.h>
#include <mach/thread_policy.h>
#include <mach/thread_act.h> // the doc says mach/sched.h but that seems outdated...
#include <pthread.h>
#include <mach/mach_error.h>
#include <mach/mach_time.h>
#endif
static void setRealtime();

/*
The implementation with the PortAudio callback was there first.
For testing, I implemented also the blocking PortAudio interface.
I had some issues which small hiccups in the audio output -
maybe the blocking PortAudio implementation can avoid them better.
For the callback, we need to minimize the locks - or better, avoid
them fully. I'm not sure it is good to depend on thread context
switches in case it is locked. This however needs some heavy redesign.
*/
#define USE_PORTAUDIO_CALLBACK 0

int initPlayerOutput() {
	PaError ret = Pa_Initialize();
	if(ret != paNoError)
		Py_FatalError("PortAudio init failed");
	return 0;
}

template<typename T> struct OutPaSampleFormat{};
template<> struct OutPaSampleFormat<int16_t> {
	static const PaSampleFormat format = paInt16;
};
template<> struct OutPaSampleFormat<float32_t> {
	static const PaSampleFormat format = paFloat32;
};

struct PlayerObject::OutStream {
	PlayerObject* const player;
	PaStream* stream;
	bool needRealtimeReset; // PortAudio callback thread must set itself to realtime

	OutStream(PlayerObject* p) : player(p), stream(NULL), needRealtimeReset(false) {
		mlock(this, sizeof(*this));
	}
	~OutStream() { close(); }

#if USE_PORTAUDIO_CALLBACK
	static int paStreamCallback(
		const void *input, void *output,
		unsigned long frameCount,
		const PaStreamCallbackTimeInfo* timeInfo,
		PaStreamCallbackFlags statusFlags,
		void *userData )
	{
		OutStream* outStream = (OutStream*) userData;

		// We must not hold the PyGIL here!
		PyScopedLock lock(outStream->player->lock);

		if(outStream->needRealtimeReset) {
			outStream->needRealtimeReset = false;
			setRealtime();
		}

		outStream->player->readOutStream((OUTSAMPLE_t*) output, frameCount * outStream->player->outNumChannels, NULL);
		return paContinue;
	}
#else
	PyThread audioThread;
	void audioThreadProc(PyMutex& threadLock, bool& stopSignal) {
		while(true) {
			{
				PyScopedLock l(threadLock);
				if(stopSignal) return;
			}

			if(needRealtimeReset) {
				needRealtimeReset = false;
				setRealtime();
			}

			OUTSAMPLE_t buffer[4800 * 2]; // 100ms stereo in 48khz
			size_t bufferSize = sizeof(buffer)/sizeof(OUTSAMPLE_t);
			size_t frameCount = 0;
			{
				PyScopedLock lock(player->lock);
				if(stopSignal) return;
				size_t sampleNumOut = 0;
				player->readOutStream(buffer, bufferSize, &sampleNumOut);
				if(sampleNumOut < bufferSize) {
					// hm...
					if(player->playing) {
						printf("audioThreadProc: warning: too less samples\n");
						// fill with silence
						memset(&buffer[sampleNumOut], 0, (bufferSize - sampleNumOut) * sizeof(OUTSAMPLE_t));
						sampleNumOut = bufferSize;
					}
				}
				frameCount = sampleNumOut / player->outNumChannels;
			}

			PaError ret = Pa_WriteStream(stream, buffer, frameCount);
			if(ret == paOutputUnderflowed)
				printf("audioThreadProc: warning: paOutputUnderflowed\n");
			else if(ret != paNoError) {
				printf("audioThreadProc: Pa_WriteStream error %i (%s)\n", ret, Pa_GetErrorText(ret));
				// sleep half a second to avoid spamming
				for(int i = 0; i < 50; ++i) {
					usleep(10 * 1000);
					PyScopedLock l(threadLock);
					if(stopSignal) return;
				}
			}
		}
	}
#endif

	bool open() {
		if(stream) close();
		assert(stream == NULL);

		PaStreamParameters outputParameters;

#if defined(__APPLE__)
		PaMacCoreStreamInfo macInfo;
		PaMacCore_SetupStreamInfo( &macInfo,
			paMacCorePlayNice | paMacCorePro );
		outputParameters.hostApiSpecificStreamInfo = &macInfo;
#elif defined(__LINUX__)
		// TODO: if we have PaAlsa_EnableRealtimeScheduling in portaudio,
		// we can call that to enable RT priority with ALSA.
		// We could check dynamically via dsym.
		outputParameters.hostApiSpecificStreamInfo = NULL;
#else
		outputParameters.hostApiSpecificStreamInfo = NULL;
#endif

		outputParameters.device = Pa_GetDefaultOutputDevice();
		if (outputParameters.device == paNoDevice) {
			PyErr_SetString(PyExc_RuntimeError, "Pa_GetDefaultOutputDevice didn't returned a device");
			return false;
		}
		outputParameters.channelCount = player->outNumChannels;
		outputParameters.sampleFormat = OutPaSampleFormat<OUTSAMPLE_t>::format;
		outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;

		// Note about framesPerBuffer:
		// Earlier, we used (2048 * 5 * OUTSAMPLEBYTELEN) which caused
		// some random more or less rare cracking noises.
		// See here: https://github.com/albertz/music-player/issues/35
		// This doesn't seem to happen with paFramesPerBufferUnspecified.

		PaError ret = Pa_OpenStream(
			&stream,
			NULL, // no input
			&outputParameters,
			player->outSamplerate, // sampleRate
			paFramesPerBufferUnspecified, // framesPerBuffer,
			paClipOff | paDitherOff,
#if USE_PORTAUDIO_CALLBACK
			&paStreamCallback,
#else
			NULL,
#endif
			this //void *userData
			);

		if(ret != paNoError) {
			PyErr_Format(PyExc_RuntimeError, "Pa_OpenStream failed: (err %i) %s", ret, Pa_GetErrorText(ret));
			if(stream)
				close();
			return false;
		}

		needRealtimeReset = true;
		Pa_StartStream(stream);

#if !USE_PORTAUDIO_CALLBACK
		audioThread.func = boost::bind(&OutStream::audioThreadProc, this, _1, _2);
		audioThread.start();
#endif
		return true;
	}

	void close() {
		if(this->stream == NULL) return;
		// we expect that we have the player lock here.
		// reset fader.
		player->fader.init(0,0);
		// we must release the player lock so that any thread-join can be done.
		PaStream* stream = NULL;
		std::swap(stream, this->stream);
		PyScopedUnlock unlock(player->lock);
		audioThread.stop();
		Pa_CloseStream(stream);
	}

	bool isOpen() const { return stream != NULL; }

};

int PlayerObject::setPlaying(bool playing) {
	PlayerObject* player = this;
	bool oldplayingstate = false;
	PyScopedGIL gil;
	{
		PyScopedGIUnlock gunlock;

		player->workerThread.start(); // if not running yet, start
		if(!player->outStream.get())
			player->outStream.reset(new OutStream(this));
		assert(player->outStream.get() != NULL);

		if(soundcardOutputEnabled) {
			if(playing && !player->outStream->stream) {
				if(!player->outStream->open())
					playing = false;
			}
		}

		oldplayingstate = player->playing;
		if(soundcardOutputEnabled && player->outStream.get() && player->outStream->isOpen() && oldplayingstate != playing)
			fader.init(playing ? 1 : -1, outSamplerate);
		player->playing = playing;
	}

	if(!PyErr_Occurred() && player->dict) {
		Py_INCREF(player->dict);
		PyObject* onPlayingStateChange = PyDict_GetItemString(player->dict, "onPlayingStateChange");
		if(onPlayingStateChange && onPlayingStateChange != Py_None) {
			Py_INCREF(onPlayingStateChange);

			PyObject* kwargs = PyDict_New();
			assert(kwargs);
			PyDict_SetItemString_retain(kwargs, "oldState", PyBool_FromLong(oldplayingstate));
			PyDict_SetItemString_retain(kwargs, "newState", PyBool_FromLong(playing));

			PyObject* retObj = PyEval_CallObjectWithKeywords(onPlayingStateChange, NULL, kwargs);
			Py_XDECREF(retObj);

			// errors are not fatal from the callback, so handle it now and go on
			if(PyErr_Occurred())
				PyErr_Print();

			Py_DECREF(kwargs);
			Py_DECREF(onPlayingStateChange);
		}
		Py_DECREF(player->dict);
	}

	return PyErr_Occurred() ? -1 : 0;
}

#ifdef __APPLE__
// https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html
// Also, from Google Native Client, osx/nacl_thread_nice.c has some related code.
// Or, from Google Chrome, platform_thread_mac.mm.
void setRealtime() {
	kern_return_t ret;
	thread_port_t threadport = pthread_mach_thread_np(pthread_self());

	thread_extended_policy_data_t policy;
	policy.timeshare = 0;
	ret = thread_policy_set(threadport,
							THREAD_EXTENDED_POLICY,
							(thread_policy_t)&policy,
							THREAD_EXTENDED_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_EXTENDED_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}

	thread_precedence_policy_data_t precedence;
	precedence.importance = 63;
	ret = thread_policy_set(threadport,
							THREAD_PRECEDENCE_POLICY,
							(thread_policy_t)&precedence,
							THREAD_PRECEDENCE_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_PRECEDENCE_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}

	mach_timebase_info_data_t tb_info;
	mach_timebase_info(&tb_info);
	double timeFact = ((double)tb_info.denom / (double)tb_info.numer) * 1000000;

	thread_time_constraint_policy_data_t ttcpolicy;
	ttcpolicy.period = 2.9 * timeFact; // about 128 frames @44.1KHz
	ttcpolicy.computation = 0.75 * 2.9 * timeFact;
	ttcpolicy.constraint = 0.85 * 2.9 * timeFact;
	ttcpolicy.preemptible = 1;

	ret = thread_policy_set(threadport,
							THREAD_TIME_CONSTRAINT_POLICY,
							(thread_policy_t)&ttcpolicy,
							THREAD_TIME_CONSTRAINT_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_TIME_CONSTRAINT_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}
}
#else
void setRealtime() {} // not implemented yet
#endif

<commit_msg>Revert "move silence handling"<commit_after>// ffmpeg player output (portaudio)
// part of MusicPlayer, https://github.com/albertz/music-player
// Copyright (c) 2012, Albert Zeyer, www.az2000.de
// All rights reserved.
// This code is under the 2-clause BSD license, see License.txt in the root directory of this project.

#include "ffmpeg.h"

#include <portaudio.h>
#include <boost/bind.hpp>

#ifdef __APPLE__
// PortAudio specific Mac stuff
#include "pa_mac_core.h"
#endif

// For setting the thread priority to realtime on MacOSX.
#ifdef __APPLE__
#include <mach/mach_init.h>
#include <mach/thread_policy.h>
#include <mach/thread_act.h> // the doc says mach/sched.h but that seems outdated...
#include <pthread.h>
#include <mach/mach_error.h>
#include <mach/mach_time.h>
#endif
static void setRealtime();

/*
The implementation with the PortAudio callback was there first.
For testing, I implemented also the blocking PortAudio interface.
I had some issues which small hiccups in the audio output -
maybe the blocking PortAudio implementation can avoid them better.
For the callback, we need to minimize the locks - or better, avoid
them fully. I'm not sure it is good to depend on thread context
switches in case it is locked. This however needs some heavy redesign.
*/
#define USE_PORTAUDIO_CALLBACK 0

int initPlayerOutput() {
	PaError ret = Pa_Initialize();
	if(ret != paNoError)
		Py_FatalError("PortAudio init failed");
	return 0;
}

template<typename T> struct OutPaSampleFormat{};
template<> struct OutPaSampleFormat<int16_t> {
	static const PaSampleFormat format = paInt16;
};
template<> struct OutPaSampleFormat<float32_t> {
	static const PaSampleFormat format = paFloat32;
};

struct PlayerObject::OutStream {
	PlayerObject* const player;
	PaStream* stream;
	bool needRealtimeReset; // PortAudio callback thread must set itself to realtime

	OutStream(PlayerObject* p) : player(p), stream(NULL), needRealtimeReset(false) {
		mlock(this, sizeof(*this));
	}
	~OutStream() { close(); }

#if USE_PORTAUDIO_CALLBACK
	static int paStreamCallback(
		const void *input, void *output,
		unsigned long frameCount,
		const PaStreamCallbackTimeInfo* timeInfo,
		PaStreamCallbackFlags statusFlags,
		void *userData )
	{
		OutStream* outStream = (OutStream*) userData;

		// We must not hold the PyGIL here!
		PyScopedLock lock(outStream->player->lock);

		if(outStream->needRealtimeReset) {
			outStream->needRealtimeReset = false;
			setRealtime();
		}

		outStream->player->readOutStream((OUTSAMPLE_t*) output, frameCount * outStream->player->outNumChannels, NULL);
		return paContinue;
	}
#else
	PyThread audioThread;
	void audioThreadProc(PyMutex& threadLock, bool& stopSignal) {
		while(true) {
			{
				PyScopedLock l(threadLock);
				if(stopSignal) return;
			}

			if(needRealtimeReset) {
				needRealtimeReset = false;
				setRealtime();
			}

			OUTSAMPLE_t buffer[4800 * 2]; // 100ms stereo in 48khz
			size_t frameCount = 0;
			{
				PyScopedLock lock(player->lock);
				if(stopSignal) return;
				player->readOutStream(buffer, sizeof(buffer)/sizeof(OUTSAMPLE_t), NULL);
				frameCount = sizeof(buffer)/sizeof(OUTSAMPLE_t) / player->outNumChannels;
			}

			PaError ret = Pa_WriteStream(stream, buffer, frameCount);
			if(ret == paOutputUnderflowed)
				printf("warning: paOutputUnderflowed\n");
			else if(ret != paNoError) {
				printf("Pa_WriteStream error %i (%s)\n", ret, Pa_GetErrorText(ret));
				// sleep half a second to avoid spamming
				for(int i = 0; i < 50; ++i) {
					usleep(10 * 1000);
					PyScopedLock l(threadLock);
					if(stopSignal) return;
				}
			}
		}
	}
#endif

	bool open() {
		if(stream) close();
		assert(stream == NULL);

		PaStreamParameters outputParameters;

#if defined(__APPLE__)
		PaMacCoreStreamInfo macInfo;
		PaMacCore_SetupStreamInfo( &macInfo,
			paMacCorePlayNice | paMacCorePro );
		outputParameters.hostApiSpecificStreamInfo = &macInfo;
#elif defined(__LINUX__)
		// TODO: if we have PaAlsa_EnableRealtimeScheduling in portaudio,
		// we can call that to enable RT priority with ALSA.
		// We could check dynamically via dsym.
		outputParameters.hostApiSpecificStreamInfo = NULL;
#else
		outputParameters.hostApiSpecificStreamInfo = NULL;
#endif

		outputParameters.device = Pa_GetDefaultOutputDevice();
		if (outputParameters.device == paNoDevice) {
			PyErr_SetString(PyExc_RuntimeError, "Pa_GetDefaultOutputDevice didn't returned a device");
			return false;
		}
		outputParameters.channelCount = player->outNumChannels;
		outputParameters.sampleFormat = OutPaSampleFormat<OUTSAMPLE_t>::format;
		outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;

		// Note about framesPerBuffer:
		// Earlier, we used (2048 * 5 * OUTSAMPLEBYTELEN) which caused
		// some random more or less rare cracking noises.
		// See here: https://github.com/albertz/music-player/issues/35
		// This doesn't seem to happen with paFramesPerBufferUnspecified.

		PaError ret = Pa_OpenStream(
			&stream,
			NULL, // no input
			&outputParameters,
			player->outSamplerate, // sampleRate
			paFramesPerBufferUnspecified, // framesPerBuffer,
			paClipOff | paDitherOff,
#if USE_PORTAUDIO_CALLBACK
			&paStreamCallback,
#else
			NULL,
#endif
			this //void *userData
			);

		if(ret != paNoError) {
			PyErr_Format(PyExc_RuntimeError, "Pa_OpenStream failed: (err %i) %s", ret, Pa_GetErrorText(ret));
			if(stream)
				close();
			return false;
		}

		needRealtimeReset = true;
		Pa_StartStream(stream);

#if !USE_PORTAUDIO_CALLBACK
		audioThread.func = boost::bind(&OutStream::audioThreadProc, this, _1, _2);
		audioThread.start();
#endif
		return true;
	}

	void close() {
		if(this->stream == NULL) return;
		// we expect that we have the player lock here.
		// reset fader.
		player->fader.init(0,0);
		// we must release the player lock so that any thread-join can be done.
		PaStream* stream = NULL;
		std::swap(stream, this->stream);
		PyScopedUnlock unlock(player->lock);
		audioThread.stop();
		Pa_CloseStream(stream);
	}

	bool isOpen() const { return stream != NULL; }

};

int PlayerObject::setPlaying(bool playing) {
	PlayerObject* player = this;
	bool oldplayingstate = false;
	PyScopedGIL gil;
	{
		PyScopedGIUnlock gunlock;

		player->workerThread.start(); // if not running yet, start
		if(!player->outStream.get())
			player->outStream.reset(new OutStream(this));
		assert(player->outStream.get() != NULL);

		if(soundcardOutputEnabled) {
			if(playing && !player->outStream->stream) {
				if(!player->outStream->open())
					playing = false;
			}
		}

		oldplayingstate = player->playing;
		if(soundcardOutputEnabled && player->outStream.get() && player->outStream->isOpen() && oldplayingstate != playing)
			fader.init(playing ? 1 : -1, outSamplerate);
		player->playing = playing;
	}

	if(!PyErr_Occurred() && player->dict) {
		Py_INCREF(player->dict);
		PyObject* onPlayingStateChange = PyDict_GetItemString(player->dict, "onPlayingStateChange");
		if(onPlayingStateChange && onPlayingStateChange != Py_None) {
			Py_INCREF(onPlayingStateChange);

			PyObject* kwargs = PyDict_New();
			assert(kwargs);
			PyDict_SetItemString_retain(kwargs, "oldState", PyBool_FromLong(oldplayingstate));
			PyDict_SetItemString_retain(kwargs, "newState", PyBool_FromLong(playing));

			PyObject* retObj = PyEval_CallObjectWithKeywords(onPlayingStateChange, NULL, kwargs);
			Py_XDECREF(retObj);

			// errors are not fatal from the callback, so handle it now and go on
			if(PyErr_Occurred())
				PyErr_Print();

			Py_DECREF(kwargs);
			Py_DECREF(onPlayingStateChange);
		}
		Py_DECREF(player->dict);
	}

	return PyErr_Occurred() ? -1 : 0;
}

#ifdef __APPLE__
// https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html
// Also, from Google Native Client, osx/nacl_thread_nice.c has some related code.
// Or, from Google Chrome, platform_thread_mac.mm.
void setRealtime() {
	kern_return_t ret;
	thread_port_t threadport = pthread_mach_thread_np(pthread_self());

	thread_extended_policy_data_t policy;
	policy.timeshare = 0;
	ret = thread_policy_set(threadport,
							THREAD_EXTENDED_POLICY,
							(thread_policy_t)&policy,
							THREAD_EXTENDED_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_EXTENDED_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}

	thread_precedence_policy_data_t precedence;
	precedence.importance = 63;
	ret = thread_policy_set(threadport,
							THREAD_PRECEDENCE_POLICY,
							(thread_policy_t)&precedence,
							THREAD_PRECEDENCE_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_PRECEDENCE_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}

	mach_timebase_info_data_t tb_info;
	mach_timebase_info(&tb_info);
	double timeFact = ((double)tb_info.denom / (double)tb_info.numer) * 1000000;

	thread_time_constraint_policy_data_t ttcpolicy;
	ttcpolicy.period = 2.9 * timeFact; // about 128 frames @44.1KHz
	ttcpolicy.computation = 0.75 * 2.9 * timeFact;
	ttcpolicy.constraint = 0.85 * 2.9 * timeFact;
	ttcpolicy.preemptible = 1;

	ret = thread_policy_set(threadport,
							THREAD_TIME_CONSTRAINT_POLICY,
							(thread_policy_t)&ttcpolicy,
							THREAD_TIME_CONSTRAINT_POLICY_COUNT);
	if(ret != KERN_SUCCESS) {
		fprintf(stderr, "setRealtime() THREAD_TIME_CONSTRAINT_POLICY failed: %d, %s\n", ret, mach_error_string(ret));
		return;
	}
}
#else
void setRealtime() {} // not implemented yet
#endif

<|endoftext|>


<commit_before>/*
    This file is part of KMail.

    Copyright (c) 2004 Jakob Schrter <js@camaya.net>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.

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

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "xfaceconfigurator.h"

#include <kactivelabel.h>
#include <kdialog.h>
#include <kfiledialog.h>
#include <kglobalsettings.h>
#include <kimageio.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kurl.h>
#include <kio/netaccess.h>
using namespace KIO;
#include <kxface.h>
using namespace KPIM;
#include <kabc/stdaddressbook.h>
#include <kabc/addressee.h>
using namespace KABC;

#include <qbitmap.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qimage.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qwhatsthis.h>
#include <qwidgetstack.h>

// #include <assert.h>

using namespace KMail;
using namespace KPIM;

namespace KMail {

  XFaceConfigurator::XFaceConfigurator( QWidget * parent, const char * name )
    : QWidget( parent, name )
  {
    // tmp. vars:
    QLabel * label;
    QLabel * label1;
    KActiveLabel * label2;
    QWidget * page;
    QVBoxLayout * vlay;
    QHBoxLayout * hlay;
    QVBoxLayout * page_vlay;
    QPushButton * mFromFileBtn;
    QPushButton * mFromAddrbkBtn;

    vlay = new QVBoxLayout( this, 0, KDialog::spacingHint(), "main layout" );
    hlay = new QHBoxLayout( vlay );

    // "enable X-Face" checkbox:
    mEnableCheck = new QCheckBox( i18n("&Send picture with every message"), this );
    QWhatsThis::add( mEnableCheck,
        i18n( "Check this box if you want KMail to add a so-called X-Face header to messages "
            "written with this identity. A X-Face is a small (48x48 pixels) black and "
            "white image that some mail clients are able to display." ) );
    hlay->addWidget( mEnableCheck, Qt::AlignLeft | Qt::AlignVCenter );

    mXFaceLabel = new QLabel( this );
    QWhatsThis::add(mXFaceLabel,
                    i18n( "This is a preview of the picture selected/entered below." ) );
    mXFaceLabel->setFixedSize(48, 48);
    mXFaceLabel->setFrameShape( QFrame::Box );
    hlay->addWidget( mXFaceLabel );

//     label1 = new QLabel( "X-Face:", this );
//     vlay->addWidget( label1 );

    // "obtain X-Facet from" combo and label:
    hlay = new QHBoxLayout( vlay ); // inherits spacing
    mSourceCombo = new QComboBox( false, this );
    QWhatsThis::add(mSourceCombo,
                    i18n("Click on the widgets below to obtain help on the input methods."));
    mSourceCombo->setEnabled( false ); // since !mEnableCheck->isChecked()
    mSourceCombo->insertStringList( QStringList()
        << i18n( "continuation of \"obtain picture from\"",
                 "External Source" )
        << i18n( "continuation of \"obtain picture from\"",
                 "Input Field Below" ) );
    label = new QLabel( mSourceCombo,
                        i18n("Obtain pic&ture from:"), this );
    label->setEnabled( false ); // since !mEnableCheck->isChecked()
    hlay->addWidget( label );
    hlay->addWidget( mSourceCombo, 1 );

    // widget stack that is controlled by the source combo:
    QWidgetStack * widgetStack = new QWidgetStack( this );
    widgetStack->setEnabled( false ); // since !mEnableCheck->isChecked()
    vlay->addWidget( widgetStack, 1 );
    connect( mSourceCombo, SIGNAL(highlighted(int)),
             widgetStack, SLOT(raiseWidget(int)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             mSourceCombo, SLOT(setEnabled(bool)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             widgetStack, SLOT(setEnabled(bool)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             label, SLOT(setEnabled(bool)) );
    // The focus might be still in the widget that is disabled
    connect( mEnableCheck, SIGNAL(clicked()),
             mEnableCheck, SLOT(setFocus()) );

    int pageno = 0;
    // page 0: create X-Face from image file or addressbook entry
    page = new QWidget( widgetStack );
    widgetStack->addWidget( page, pageno ); // force sequential numbers (play safe)
    page_vlay = new QVBoxLayout( page, 0, KDialog::spacingHint() );
    hlay = new QHBoxLayout( page_vlay ); // inherits spacing
    mFromFileBtn = new QPushButton( "Select File", page );
    QWhatsThis::add( mFromFileBtn,
                     i18n("Use this to select an image file to create the picture from. "
                         "The image should be of high contrast and nearly quadratic shape. "
                         "A light background helps improve the result." ) );
    mFromFileBtn->setAutoDefault( false );
    page_vlay->addWidget( mFromFileBtn, 1 );
    connect( mFromFileBtn, SIGNAL(released()),
             this, SLOT(slotSelectFile()) );
    mFromAddrbkBtn = new QPushButton( "Set from Addressbook", page );
    QWhatsThis::add( mFromAddrbkBtn,
                     i18n( "You can use a scaled-down version of the picture "
                         "you have set in your address book entry." ) );
    mFromAddrbkBtn->setAutoDefault( false );
    page_vlay->addWidget( mFromAddrbkBtn, 1 );
    connect( mFromAddrbkBtn, SIGNAL(released()),
             this, SLOT(slotSelectFromAddressbook()) );
    label1 = new QLabel( i18n("<qt>KMail can send a small (48x48 pixels), low-quality, "
        "monochrome picture with every message. "
        "For example, this could be a picture of you or a glyph. "
        "It is shown in the recipient's mail client (if supported)." ), page );
    label1->setAlignment( QLabel::WordBreak | QLabel::AlignVCenter );
    page_vlay->addWidget( label1 );

    widgetStack->raiseWidget( 0 ); // since mSourceCombo->currentItem() == 0

    // page 1: input field for direct entering
    ++pageno;
    page = new QWidget( widgetStack );
    widgetStack->addWidget( page, pageno );
    page_vlay = new QVBoxLayout( page, 0, KDialog::spacingHint() );
    mTextEdit = new QTextEdit( page );
    page_vlay->addWidget( mTextEdit );
    QWhatsThis::add( mTextEdit, i18n( "Use this field to enter an arbitrary X-Face string." ) );
    mTextEdit->setFont( KGlobalSettings::fixedFont() );
    mTextEdit->setWrapPolicy( QTextEdit::Anywhere );
    mTextEdit->setTextFormat( Qt::PlainText );
    label2 = new KActiveLabel( i18n("Examples are available at http://www.xs4all.nl/~ace/X-Faces/."), page );
    page_vlay->addWidget( label2 );

    connect(mTextEdit, SIGNAL(textChanged()), this, SLOT(slotUpdateXFace()));
  }

  XFaceConfigurator::~XFaceConfigurator() {

  }

  bool XFaceConfigurator::isXFaceEnabled() const {
    return mEnableCheck->isChecked();
  }

  void XFaceConfigurator::setXFaceEnabled( bool enable ) {
    mEnableCheck->setChecked( enable );
  }

  QString XFaceConfigurator::xface() const {
    return mTextEdit->text();
  }

  void XFaceConfigurator::setXFace( const QString & text ) {
    mTextEdit->setText( text );
  }

  void XFaceConfigurator::setXfaceFromFile( const KURL &url )
  {
    QString tmpFile;
    if( KIO::NetAccess::download( url, tmpFile, this ) )
    {
      KXFace xf;
      mTextEdit->setText( xf.fromImage( QImage( tmpFile ) ) );
      KIO::NetAccess::removeTempFile( tmpFile );
    } else {
      KMessageBox::error(this, KIO::NetAccess::lastErrorString() );
    }
  }

  void XFaceConfigurator::slotSelectFile()
  {
    QStringList mimeTypes = KImageIO::mimeTypes (KImageIO::Reading);
    QString filter = mimeTypes.join (" ");
    KURL url = KFileDialog::getOpenURL( QString::null, filter, this, QString::null );
    if ( !url.isEmpty() )
      setXfaceFromFile( url );
  }

  void XFaceConfigurator::slotSelectFromAddressbook()
  {
    StdAddressBook *ab = StdAddressBook::self();
    Addressee me = ab->whoAmI();
    if ( !me.isEmpty() )
    {
      if ( me.photo().isIntern() )
      {
        QImage photo = me.photo().data();
        if ( !photo.isNull() )
        {
          KXFace xf;
          mTextEdit->setText( xf.fromImage( photo ) );
        }
        else
          KMessageBox::information( this, "No picture set for your adress book entry.", "No picture" );

      }
      else
      {
        KURL url = me.photo().url();
        if( !url.isEmpty() )
          setXfaceFromFile( url );
        else
          KMessageBox::information( this, "No picture set for your adress book entry.", "No picture" );
      }
    }
    else
      KMessageBox::information( this, "You don't have your own contact defined in the address book.", "No picture" );
  }

  void XFaceConfigurator::slotUpdateXFace()
  {
    QString str = mTextEdit->text();
    if ( !str.isEmpty() )
    {
      if ( str.startsWith("x-face:", false) )
      {
        str = str.remove("x-face:", false);
        mTextEdit->setText(str);
      }
      KXFace xf;
      mXFaceLabel->setPixmap( xf.toBitmap(str) );
    }
    else
      mXFaceLabel->setPixmap( 0L );
  }

} // namespace KMail

#include "xfaceconfigurator.moc"
<commit_msg>CVS_SILENT fix grammar<commit_after>/*
    This file is part of KMail.

    Copyright (c) 2004 Jakob Schrter <js@camaya.net>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.

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

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "xfaceconfigurator.h"

#include <kactivelabel.h>
#include <kdialog.h>
#include <kfiledialog.h>
#include <kglobalsettings.h>
#include <kimageio.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kurl.h>
#include <kio/netaccess.h>
using namespace KIO;
#include <kxface.h>
using namespace KPIM;
#include <kabc/stdaddressbook.h>
#include <kabc/addressee.h>
using namespace KABC;

#include <qbitmap.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qimage.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qwhatsthis.h>
#include <qwidgetstack.h>

// #include <assert.h>

using namespace KMail;
using namespace KPIM;

namespace KMail {

  XFaceConfigurator::XFaceConfigurator( QWidget * parent, const char * name )
    : QWidget( parent, name )
  {
    // tmp. vars:
    QLabel * label;
    QLabel * label1;
    KActiveLabel * label2;
    QWidget * page;
    QVBoxLayout * vlay;
    QHBoxLayout * hlay;
    QVBoxLayout * page_vlay;
    QPushButton * mFromFileBtn;
    QPushButton * mFromAddrbkBtn;

    vlay = new QVBoxLayout( this, 0, KDialog::spacingHint(), "main layout" );
    hlay = new QHBoxLayout( vlay );

    // "enable X-Face" checkbox:
    mEnableCheck = new QCheckBox( i18n("&Send picture with every message"), this );
    QWhatsThis::add( mEnableCheck,
        i18n( "Check this box if you want KMail to add a so-called X-Face header to messages "
            "written with this identity. An X-Face is a small (48x48 pixels) black and "
            "white image that some mail clients are able to display." ) );
    hlay->addWidget( mEnableCheck, Qt::AlignLeft | Qt::AlignVCenter );

    mXFaceLabel = new QLabel( this );
    QWhatsThis::add(mXFaceLabel,
                    i18n( "This is a preview of the picture selected/entered below." ) );
    mXFaceLabel->setFixedSize(48, 48);
    mXFaceLabel->setFrameShape( QFrame::Box );
    hlay->addWidget( mXFaceLabel );

//     label1 = new QLabel( "X-Face:", this );
//     vlay->addWidget( label1 );

    // "obtain X-Facet from" combo and label:
    hlay = new QHBoxLayout( vlay ); // inherits spacing
    mSourceCombo = new QComboBox( false, this );
    QWhatsThis::add(mSourceCombo,
                    i18n("Click on the widgets below to obtain help on the input methods."));
    mSourceCombo->setEnabled( false ); // since !mEnableCheck->isChecked()
    mSourceCombo->insertStringList( QStringList()
        << i18n( "continuation of \"obtain picture from\"",
                 "External Source" )
        << i18n( "continuation of \"obtain picture from\"",
                 "Input Field Below" ) );
    label = new QLabel( mSourceCombo,
                        i18n("Obtain pic&ture from:"), this );
    label->setEnabled( false ); // since !mEnableCheck->isChecked()
    hlay->addWidget( label );
    hlay->addWidget( mSourceCombo, 1 );

    // widget stack that is controlled by the source combo:
    QWidgetStack * widgetStack = new QWidgetStack( this );
    widgetStack->setEnabled( false ); // since !mEnableCheck->isChecked()
    vlay->addWidget( widgetStack, 1 );
    connect( mSourceCombo, SIGNAL(highlighted(int)),
             widgetStack, SLOT(raiseWidget(int)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             mSourceCombo, SLOT(setEnabled(bool)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             widgetStack, SLOT(setEnabled(bool)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             label, SLOT(setEnabled(bool)) );
    // The focus might be still in the widget that is disabled
    connect( mEnableCheck, SIGNAL(clicked()),
             mEnableCheck, SLOT(setFocus()) );

    int pageno = 0;
    // page 0: create X-Face from image file or addressbook entry
    page = new QWidget( widgetStack );
    widgetStack->addWidget( page, pageno ); // force sequential numbers (play safe)
    page_vlay = new QVBoxLayout( page, 0, KDialog::spacingHint() );
    hlay = new QHBoxLayout( page_vlay ); // inherits spacing
    mFromFileBtn = new QPushButton( "Select File", page );
    QWhatsThis::add( mFromFileBtn,
                     i18n("Use this to select an image file to create the picture from. "
                         "The image should be of high contrast and nearly quadratic shape. "
                         "A light background helps improve the result." ) );
    mFromFileBtn->setAutoDefault( false );
    page_vlay->addWidget( mFromFileBtn, 1 );
    connect( mFromFileBtn, SIGNAL(released()),
             this, SLOT(slotSelectFile()) );
    mFromAddrbkBtn = new QPushButton( "Set from Addressbook", page );
    QWhatsThis::add( mFromAddrbkBtn,
                     i18n( "You can use a scaled-down version of the picture "
                         "you have set in your address book entry." ) );
    mFromAddrbkBtn->setAutoDefault( false );
    page_vlay->addWidget( mFromAddrbkBtn, 1 );
    connect( mFromAddrbkBtn, SIGNAL(released()),
             this, SLOT(slotSelectFromAddressbook()) );
    label1 = new QLabel( i18n("<qt>KMail can send a small (48x48 pixels), low-quality, "
        "monochrome picture with every message. "
        "For example, this could be a picture of you or a glyph. "
        "It is shown in the recipient's mail client (if supported)." ), page );
    label1->setAlignment( QLabel::WordBreak | QLabel::AlignVCenter );
    page_vlay->addWidget( label1 );

    widgetStack->raiseWidget( 0 ); // since mSourceCombo->currentItem() == 0

    // page 1: input field for direct entering
    ++pageno;
    page = new QWidget( widgetStack );
    widgetStack->addWidget( page, pageno );
    page_vlay = new QVBoxLayout( page, 0, KDialog::spacingHint() );
    mTextEdit = new QTextEdit( page );
    page_vlay->addWidget( mTextEdit );
    QWhatsThis::add( mTextEdit, i18n( "Use this field to enter an arbitrary X-Face string." ) );
    mTextEdit->setFont( KGlobalSettings::fixedFont() );
    mTextEdit->setWrapPolicy( QTextEdit::Anywhere );
    mTextEdit->setTextFormat( Qt::PlainText );
    label2 = new KActiveLabel( i18n("Examples are available at http://www.xs4all.nl/~ace/X-Faces/."), page );
    page_vlay->addWidget( label2 );

    connect(mTextEdit, SIGNAL(textChanged()), this, SLOT(slotUpdateXFace()));
  }

  XFaceConfigurator::~XFaceConfigurator() {

  }

  bool XFaceConfigurator::isXFaceEnabled() const {
    return mEnableCheck->isChecked();
  }

  void XFaceConfigurator::setXFaceEnabled( bool enable ) {
    mEnableCheck->setChecked( enable );
  }

  QString XFaceConfigurator::xface() const {
    return mTextEdit->text();
  }

  void XFaceConfigurator::setXFace( const QString & text ) {
    mTextEdit->setText( text );
  }

  void XFaceConfigurator::setXfaceFromFile( const KURL &url )
  {
    QString tmpFile;
    if( KIO::NetAccess::download( url, tmpFile, this ) )
    {
      KXFace xf;
      mTextEdit->setText( xf.fromImage( QImage( tmpFile ) ) );
      KIO::NetAccess::removeTempFile( tmpFile );
    } else {
      KMessageBox::error(this, KIO::NetAccess::lastErrorString() );
    }
  }

  void XFaceConfigurator::slotSelectFile()
  {
    QStringList mimeTypes = KImageIO::mimeTypes (KImageIO::Reading);
    QString filter = mimeTypes.join (" ");
    KURL url = KFileDialog::getOpenURL( QString::null, filter, this, QString::null );
    if ( !url.isEmpty() )
      setXfaceFromFile( url );
  }

  void XFaceConfigurator::slotSelectFromAddressbook()
  {
    StdAddressBook *ab = StdAddressBook::self();
    Addressee me = ab->whoAmI();
    if ( !me.isEmpty() )
    {
      if ( me.photo().isIntern() )
      {
        QImage photo = me.photo().data();
        if ( !photo.isNull() )
        {
          KXFace xf;
          mTextEdit->setText( xf.fromImage( photo ) );
        }
        else
          KMessageBox::information( this, "No picture set for your adress book entry.", "No picture" );

      }
      else
      {
        KURL url = me.photo().url();
        if( !url.isEmpty() )
          setXfaceFromFile( url );
        else
          KMessageBox::information( this, "No picture set for your adress book entry.", "No picture" );
      }
    }
    else
      KMessageBox::information( this, "You don't have your own contact defined in the address book.", "No picture" );
  }

  void XFaceConfigurator::slotUpdateXFace()
  {
    QString str = mTextEdit->text();
    if ( !str.isEmpty() )
    {
      if ( str.startsWith("x-face:", false) )
      {
        str = str.remove("x-face:", false);
        mTextEdit->setText(str);
      }
      KXFace xf;
      mXFaceLabel->setPixmap( xf.toBitmap(str) );
    }
    else
      mXFaceLabel->setPixmap( 0L );
  }

} // namespace KMail

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


<commit_before>/*
    This file is part of KMail.

    Copyright (c) 2004 Jakob Schr�er <js@camaya.net>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.

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

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "xfaceconfigurator.h"

#include <kactivelabel.h>
#include <kdialog.h>
#include <kfiledialog.h>
#include <kglobalsettings.h>
#include <kimageio.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kurl.h>
#include <kio/netaccess.h>
using namespace KIO;
#include <kxface.h>
using namespace KPIM;
#include <kabc/stdaddressbook.h>
#include <kabc/addressee.h>
using namespace KABC;

#include <qbitmap.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qimage.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qwhatsthis.h>
#include <qwidgetstack.h>

// #include <assert.h>

using namespace KMail;
using namespace KPIM;

namespace KMail {

  XFaceConfigurator::XFaceConfigurator( QWidget * parent, const char * name )
    : QWidget( parent, name )
  {
    // tmp. vars:
    QLabel * label;
    QLabel * label1;
    KActiveLabel * label2;
    QWidget * page;
    QVBoxLayout * vlay;
    QHBoxLayout * hlay;
    QVBoxLayout * page_vlay;
    QPushButton * mFromFileBtn;
    QPushButton * mFromAddrbkBtn;

    vlay = new QVBoxLayout( this, 0, KDialog::spacingHint(), "main layout" );
    hlay = new QHBoxLayout( vlay );

    // "enable X-Face" checkbox:
    mEnableCheck = new QCheckBox( i18n("&Send picture with every message"), this );
    QWhatsThis::add( mEnableCheck,
        i18n( "Check this box if you want KMail to add a so-called X-Face header to messages "
            "written with this identity. An X-Face is a small (48x48 pixels) black and "
            "white image that some mail clients are able to display." ) );
    hlay->addWidget( mEnableCheck, Qt::AlignLeft | Qt::AlignVCenter );

    mXFaceLabel = new QLabel( this );
    QWhatsThis::add(mXFaceLabel,
                    i18n( "This is a preview of the picture selected/entered below." ) );
    mXFaceLabel->setFixedSize(48, 48);
    mXFaceLabel->setFrameShape( QFrame::Box );
    hlay->addWidget( mXFaceLabel );

//     label1 = new QLabel( "X-Face:", this );
//     vlay->addWidget( label1 );

    // "obtain X-Face from" combo and label:
    hlay = new QHBoxLayout( vlay ); // inherits spacing
    mSourceCombo = new QComboBox( false, this );
    QWhatsThis::add(mSourceCombo,
                    i18n("Click on the widgets below to obtain help on the input methods."));
    mSourceCombo->setEnabled( false ); // since !mEnableCheck->isChecked()
    mSourceCombo->insertStringList( QStringList()
        << i18n( "continuation of \"obtain picture from\"",
                 "External Source" )
        << i18n( "continuation of \"obtain picture from\"",
                 "Input Field Below" ) );
    label = new QLabel( mSourceCombo,
                        i18n("Obtain pic&ture from:"), this );
    label->setEnabled( false ); // since !mEnableCheck->isChecked()
    hlay->addWidget( label );
    hlay->addWidget( mSourceCombo, 1 );

    // widget stack that is controlled by the source combo:
    QWidgetStack * widgetStack = new QWidgetStack( this );
    widgetStack->setEnabled( false ); // since !mEnableCheck->isChecked()
    vlay->addWidget( widgetStack, 1 );
    connect( mSourceCombo, SIGNAL(highlighted(int)),
             widgetStack, SLOT(raiseWidget(int)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             mSourceCombo, SLOT(setEnabled(bool)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             widgetStack, SLOT(setEnabled(bool)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             label, SLOT(setEnabled(bool)) );
    // The focus might be still in the widget that is disabled
    connect( mEnableCheck, SIGNAL(clicked()),
             mEnableCheck, SLOT(setFocus()) );

    int pageno = 0;
    // page 0: create X-Face from image file or addressbook entry
    page = new QWidget( widgetStack );
    widgetStack->addWidget( page, pageno ); // force sequential numbers (play safe)
    page_vlay = new QVBoxLayout( page, 0, KDialog::spacingHint() );
    hlay = new QHBoxLayout( page_vlay ); // inherits spacing
    mFromFileBtn = new QPushButton( i18n("Select File"), page );
    QWhatsThis::add( mFromFileBtn,
                     i18n("Use this to select an image file to create the picture from. "
                         "The image should be of high contrast and nearly quadratic shape. "
                         "A light background helps improve the result." ) );
    mFromFileBtn->setAutoDefault( false );
    page_vlay->addWidget( mFromFileBtn, 1 );
    connect( mFromFileBtn, SIGNAL(released()),
             this, SLOT(slotSelectFile()) );
    mFromAddrbkBtn = new QPushButton( i18n("Set From Addressbook"), page );
    QWhatsThis::add( mFromAddrbkBtn,
                     i18n( "You can use a scaled-down version of the picture "
                         "you have set in your address book entry." ) );
    mFromAddrbkBtn->setAutoDefault( false );
    page_vlay->addWidget( mFromAddrbkBtn, 1 );
    connect( mFromAddrbkBtn, SIGNAL(released()),
             this, SLOT(slotSelectFromAddressbook()) );
    label1 = new QLabel( i18n("<qt>KMail can send a small (48x48 pixels), low-quality, "
        "monochrome picture with every message. "
        "For example, this could be a picture of you or a glyph. "
        "It is shown in the recipient's mail client (if supported)." ), page );
    label1->setAlignment( QLabel::WordBreak | QLabel::AlignVCenter );
    page_vlay->addWidget( label1 );

    widgetStack->raiseWidget( 0 ); // since mSourceCombo->currentItem() == 0

    // page 1: input field for direct entering
    ++pageno;
    page = new QWidget( widgetStack );
    widgetStack->addWidget( page, pageno );
    page_vlay = new QVBoxLayout( page, 0, KDialog::spacingHint() );
    mTextEdit = new QTextEdit( page );
    page_vlay->addWidget( mTextEdit );
    QWhatsThis::add( mTextEdit, i18n( "Use this field to enter an arbitrary X-Face string." ) );
    mTextEdit->setFont( KGlobalSettings::fixedFont() );
    mTextEdit->setWrapPolicy( QTextEdit::Anywhere );
    mTextEdit->setTextFormat( Qt::PlainText );
    label2 = new KActiveLabel( i18n("Examples are available at http://www.xs4all.nl/~ace/X-Faces/."), page );
    page_vlay->addWidget( label2 );

    connect(mTextEdit, SIGNAL(textChanged()), this, SLOT(slotUpdateXFace()));
  }

  XFaceConfigurator::~XFaceConfigurator() {

  }

  bool XFaceConfigurator::isXFaceEnabled() const {
    return mEnableCheck->isChecked();
  }

  void XFaceConfigurator::setXFaceEnabled( bool enable ) {
    mEnableCheck->setChecked( enable );
  }

  QString XFaceConfigurator::xface() const {
    return mTextEdit->text();
  }

  void XFaceConfigurator::setXFace( const QString & text ) {
    mTextEdit->setText( text );
  }

  void XFaceConfigurator::setXfaceFromFile( const KURL &url )
  {
    QString tmpFile;
    if( KIO::NetAccess::download( url, tmpFile, this ) )
    {
      KXFace xf;
      mTextEdit->setText( xf.fromImage( QImage( tmpFile ) ) );
      KIO::NetAccess::removeTempFile( tmpFile );
    } else {
      KMessageBox::error(this, KIO::NetAccess::lastErrorString() );
    }
  }

  void XFaceConfigurator::slotSelectFile()
  {
    QStringList mimeTypes = KImageIO::mimeTypes (KImageIO::Reading);
    QString filter = mimeTypes.join (" ");
    KURL url = KFileDialog::getOpenURL( QString::null, filter, this, QString::null );
    if ( !url.isEmpty() )
      setXfaceFromFile( url );
  }

  void XFaceConfigurator::slotSelectFromAddressbook()
  {
    StdAddressBook *ab = StdAddressBook::self();
    Addressee me = ab->whoAmI();
    if ( !me.isEmpty() )
    {
      if ( me.photo().isIntern() )
      {
        QImage photo = me.photo().data();
        if ( !photo.isNull() )
        {
          KXFace xf;
          mTextEdit->setText( xf.fromImage( photo ) );
        }
        else
          KMessageBox::information( this, i18n("No picture set for your adress book entry."), i18n("No Picture") );

      }
      else
      {
        KURL url = me.photo().url();
        if( !url.isEmpty() )
          setXfaceFromFile( url );
        else
          KMessageBox::information( this, i18n("No picture set for your adress book entry."), i18n("No Picture") );
      }
    }
    else
      KMessageBox::information( this, i18n("You do not have your own contact defined in the address book."), i18n("No Picture") );
  }

  void XFaceConfigurator::slotUpdateXFace()
  {
    QString str = mTextEdit->text();
    if ( !str.isEmpty() )
    {
      if ( str.startsWith("x-face:", false) )
      {
        str = str.remove("x-face:", false);
        mTextEdit->setText(str);
      }
      KXFace xf;
      QPixmap p( 48, 48, true );
      p.convertFromImage( xf.toImage(str) );
      mXFaceLabel->setPixmap( p );
    }
    else
      mXFaceLabel->setPixmap( 0L );
  }

} // namespace KMail

#include "xfaceconfigurator.moc"
<commit_msg>CVS_SILENT typos<commit_after>/*
    This file is part of KMail.

    Copyright (c) 2004 Jakob Schr�er <js@camaya.net>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.

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

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "xfaceconfigurator.h"

#include <kactivelabel.h>
#include <kdialog.h>
#include <kfiledialog.h>
#include <kglobalsettings.h>
#include <kimageio.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kurl.h>
#include <kio/netaccess.h>
using namespace KIO;
#include <kxface.h>
using namespace KPIM;
#include <kabc/stdaddressbook.h>
#include <kabc/addressee.h>
using namespace KABC;

#include <qbitmap.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qimage.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qwhatsthis.h>
#include <qwidgetstack.h>

// #include <assert.h>

using namespace KMail;
using namespace KPIM;

namespace KMail {

  XFaceConfigurator::XFaceConfigurator( QWidget * parent, const char * name )
    : QWidget( parent, name )
  {
    // tmp. vars:
    QLabel * label;
    QLabel * label1;
    KActiveLabel * label2;
    QWidget * page;
    QVBoxLayout * vlay;
    QHBoxLayout * hlay;
    QVBoxLayout * page_vlay;
    QPushButton * mFromFileBtn;
    QPushButton * mFromAddrbkBtn;

    vlay = new QVBoxLayout( this, 0, KDialog::spacingHint(), "main layout" );
    hlay = new QHBoxLayout( vlay );

    // "enable X-Face" checkbox:
    mEnableCheck = new QCheckBox( i18n("&Send picture with every message"), this );
    QWhatsThis::add( mEnableCheck,
        i18n( "Check this box if you want KMail to add a so-called X-Face header to messages "
            "written with this identity. An X-Face is a small (48x48 pixels) black and "
            "white image that some mail clients are able to display." ) );
    hlay->addWidget( mEnableCheck, Qt::AlignLeft | Qt::AlignVCenter );

    mXFaceLabel = new QLabel( this );
    QWhatsThis::add(mXFaceLabel,
                    i18n( "This is a preview of the picture selected/entered below." ) );
    mXFaceLabel->setFixedSize(48, 48);
    mXFaceLabel->setFrameShape( QFrame::Box );
    hlay->addWidget( mXFaceLabel );

//     label1 = new QLabel( "X-Face:", this );
//     vlay->addWidget( label1 );

    // "obtain X-Face from" combo and label:
    hlay = new QHBoxLayout( vlay ); // inherits spacing
    mSourceCombo = new QComboBox( false, this );
    QWhatsThis::add(mSourceCombo,
                    i18n("Click on the widgets below to obtain help on the input methods."));
    mSourceCombo->setEnabled( false ); // since !mEnableCheck->isChecked()
    mSourceCombo->insertStringList( QStringList()
        << i18n( "continuation of \"obtain picture from\"",
                 "External Source" )
        << i18n( "continuation of \"obtain picture from\"",
                 "Input Field Below" ) );
    label = new QLabel( mSourceCombo,
                        i18n("Obtain pic&ture from:"), this );
    label->setEnabled( false ); // since !mEnableCheck->isChecked()
    hlay->addWidget( label );
    hlay->addWidget( mSourceCombo, 1 );

    // widget stack that is controlled by the source combo:
    QWidgetStack * widgetStack = new QWidgetStack( this );
    widgetStack->setEnabled( false ); // since !mEnableCheck->isChecked()
    vlay->addWidget( widgetStack, 1 );
    connect( mSourceCombo, SIGNAL(highlighted(int)),
             widgetStack, SLOT(raiseWidget(int)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             mSourceCombo, SLOT(setEnabled(bool)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             widgetStack, SLOT(setEnabled(bool)) );
    connect( mEnableCheck, SIGNAL(toggled(bool)),
             label, SLOT(setEnabled(bool)) );
    // The focus might be still in the widget that is disabled
    connect( mEnableCheck, SIGNAL(clicked()),
             mEnableCheck, SLOT(setFocus()) );

    int pageno = 0;
    // page 0: create X-Face from image file or address book entry
    page = new QWidget( widgetStack );
    widgetStack->addWidget( page, pageno ); // force sequential numbers (play safe)
    page_vlay = new QVBoxLayout( page, 0, KDialog::spacingHint() );
    hlay = new QHBoxLayout( page_vlay ); // inherits spacing
    mFromFileBtn = new QPushButton( i18n("Select File"), page );
    QWhatsThis::add( mFromFileBtn,
                     i18n("Use this to select an image file to create the picture from. "
                         "The image should be of high contrast and nearly quadratic shape. "
                         "A light background helps improve the result." ) );
    mFromFileBtn->setAutoDefault( false );
    page_vlay->addWidget( mFromFileBtn, 1 );
    connect( mFromFileBtn, SIGNAL(released()),
             this, SLOT(slotSelectFile()) );
    mFromAddrbkBtn = new QPushButton( i18n("Set From Address Book"), page );
    QWhatsThis::add( mFromAddrbkBtn,
                     i18n( "You can use a scaled-down version of the picture "
                         "you have set in your address book entry." ) );
    mFromAddrbkBtn->setAutoDefault( false );
    page_vlay->addWidget( mFromAddrbkBtn, 1 );
    connect( mFromAddrbkBtn, SIGNAL(released()),
             this, SLOT(slotSelectFromAddressbook()) );
    label1 = new QLabel( i18n("<qt>KMail can send a small (48x48 pixels), low-quality, "
        "monochrome picture with every message. "
        "For example, this could be a picture of you or a glyph. "
        "It is shown in the recipient's mail client (if supported)." ), page );
    label1->setAlignment( QLabel::WordBreak | QLabel::AlignVCenter );
    page_vlay->addWidget( label1 );

    widgetStack->raiseWidget( 0 ); // since mSourceCombo->currentItem() == 0

    // page 1: input field for direct entering
    ++pageno;
    page = new QWidget( widgetStack );
    widgetStack->addWidget( page, pageno );
    page_vlay = new QVBoxLayout( page, 0, KDialog::spacingHint() );
    mTextEdit = new QTextEdit( page );
    page_vlay->addWidget( mTextEdit );
    QWhatsThis::add( mTextEdit, i18n( "Use this field to enter an arbitrary X-Face string." ) );
    mTextEdit->setFont( KGlobalSettings::fixedFont() );
    mTextEdit->setWrapPolicy( QTextEdit::Anywhere );
    mTextEdit->setTextFormat( Qt::PlainText );
    label2 = new KActiveLabel( i18n("Examples are available at http://www.xs4all.nl/~ace/X-Faces/."), page );
    page_vlay->addWidget( label2 );

    connect(mTextEdit, SIGNAL(textChanged()), this, SLOT(slotUpdateXFace()));
  }

  XFaceConfigurator::~XFaceConfigurator() {

  }

  bool XFaceConfigurator::isXFaceEnabled() const {
    return mEnableCheck->isChecked();
  }

  void XFaceConfigurator::setXFaceEnabled( bool enable ) {
    mEnableCheck->setChecked( enable );
  }

  QString XFaceConfigurator::xface() const {
    return mTextEdit->text();
  }

  void XFaceConfigurator::setXFace( const QString & text ) {
    mTextEdit->setText( text );
  }

  void XFaceConfigurator::setXfaceFromFile( const KURL &url )
  {
    QString tmpFile;
    if( KIO::NetAccess::download( url, tmpFile, this ) )
    {
      KXFace xf;
      mTextEdit->setText( xf.fromImage( QImage( tmpFile ) ) );
      KIO::NetAccess::removeTempFile( tmpFile );
    } else {
      KMessageBox::error(this, KIO::NetAccess::lastErrorString() );
    }
  }

  void XFaceConfigurator::slotSelectFile()
  {
    QStringList mimeTypes = KImageIO::mimeTypes (KImageIO::Reading);
    QString filter = mimeTypes.join (" ");
    KURL url = KFileDialog::getOpenURL( QString::null, filter, this, QString::null );
    if ( !url.isEmpty() )
      setXfaceFromFile( url );
  }

  void XFaceConfigurator::slotSelectFromAddressbook()
  {
    StdAddressBook *ab = StdAddressBook::self();
    Addressee me = ab->whoAmI();
    if ( !me.isEmpty() )
    {
      if ( me.photo().isIntern() )
      {
        QImage photo = me.photo().data();
        if ( !photo.isNull() )
        {
          KXFace xf;
          mTextEdit->setText( xf.fromImage( photo ) );
        }
        else
          KMessageBox::information( this, i18n("No picture set for your address book entry."), i18n("No Picture") );

      }
      else
      {
        KURL url = me.photo().url();
        if( !url.isEmpty() )
          setXfaceFromFile( url );
        else
          KMessageBox::information( this, i18n("No picture set for your address book entry."), i18n("No Picture") );
      }
    }
    else
      KMessageBox::information( this, i18n("You do not have your own contact defined in the address book."), i18n("No Picture") );
  }

  void XFaceConfigurator::slotUpdateXFace()
  {
    QString str = mTextEdit->text();
    if ( !str.isEmpty() )
    {
      if ( str.startsWith("x-face:", false) )
      {
        str = str.remove("x-face:", false);
        mTextEdit->setText(str);
      }
      KXFace xf;
      QPixmap p( 48, 48, true );
      p.convertFromImage( xf.toImage(str) );
      mXFaceLabel->setPixmap( p );
    }
    else
      mXFaceLabel->setPixmap( 0L );
  }

} // namespace KMail

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


<commit_before>#include "GridView.h"

using namespace std;

GridView::GridView()
{
	contentSize.w = 0;
	contentSize.h = 0;
	selectedPosition = -1;
	itemCountSecondaryDirection = 1;
	orientation = OrientationHorizontal;

	itemMargin = 0;
}

GridView::~GridView()
{
}

bool GridView::Initialize(ResourceManager* resourceManager, SDL_Renderer* renderer)
{
	isInitialized = true;
	return true;
}

void GridView::Update()
{
}

void GridView::Draw(SDL_Renderer* renderer)
{
	if (calculatedSize.w == 0 || calculatedSize.h == 0)
		return;

	if (contentSize.w == 0 || contentSize.h == 0)
		return;

	for (int i = 0; i < children.size(); i++)
	{
		children[i]->Draw(renderer);
	}
}

void GridView::OnLayoutChange()
{
	if (itemCountSecondaryDirection <= 0)
		throw runtime_error("GridView: itemCountSecondaryDirection must be greater than zero");

	int itemsInWidth = 0;
	int itemsInHeight = 0;

	if (orientation == OrientationHorizontal)
	{
		itemsInWidth = children.size() / itemCountSecondaryDirection;
		itemsInHeight = itemCountSecondaryDirection;

		if (children.size() % itemCountSecondaryDirection != 0)
			itemsInWidth++;
	}
	else
	{
		itemsInWidth = itemCountSecondaryDirection;
		itemsInHeight = children.size() / itemCountSecondaryDirection;

		if (children.size() % itemCountSecondaryDirection != 0)
			itemsInHeight++;
	}

	int* columnSizes = new int[itemsInWidth];
	int* rowSizes = new int[itemsInHeight];

	int* columnPositions = new int[itemsInWidth];
	int* rowPositions = new int[itemsInHeight];

	memset(columnSizes, 0, itemsInWidth * sizeof(int));
	memset(rowSizes, 0, itemsInHeight * sizeof(int));

	memset(columnPositions, 0, itemsInWidth * sizeof(int));
	memset(rowPositions, 0, itemsInHeight * sizeof(int));

	// Calculate column and row sizes
	for (int i = 0; i < children.size(); i++)
	{
		View* v = children.at(i);

		int curColumn;
		int curRow;

		if (orientation == OrientationHorizontal)
		{
			curColumn = i / itemCountSecondaryDirection;
			curRow = i % itemCountSecondaryDirection;
		}
		else
		{
			curColumn = i % itemCountSecondaryDirection;
			curRow = i / itemCountSecondaryDirection;
		}

		Box childMargin = v->GetLayoutMargin();
		Size childSize = v->CalculateLayout(Position(0, 0), Size(-1, -1));
		Size childSizeIncMargins = childSize + Size(childMargin.left + childMargin.right, childMargin.top + childMargin.bottom);

		if (childSizeIncMargins.w > columnSizes[curColumn])
			columnSizes[curColumn] = childSizeIncMargins.w;

		if (childSizeIncMargins.h > rowSizes[curRow])
			rowSizes[curRow] = childSizeIncMargins.h;
	}

	// Calculate positions for columns and rows
	for (int i = 0; i < itemsInWidth; i++)
	{
		if (i == 0)
			columnPositions[i] = 0;
		else
			columnPositions[i] = columnPositions[i - 1] + columnSizes[i - 1] + itemMargin;
	}

	for (int i = 0; i < itemsInHeight; i++)
	{
		if (i == 0)
			rowPositions[i] = 0;
		else
			rowPositions[i] = rowPositions[i - 1] + rowSizes[i - 1] + itemMargin;
	}

	// Set content area size
	contentSize.w = columnPositions[itemsInWidth - 1] + columnSizes[itemsInWidth - 1];
	contentSize.h = rowPositions[itemsInHeight - 1] + rowSizes[itemsInHeight - 1];

	// Position children
	for (int i = 0; i < children.size(); i++)
	{
		View* v = children.at(i);

		int curColumn;
		int curRow;

		if (orientation == OrientationHorizontal)
		{
			curColumn = i / itemCountSecondaryDirection;
			curRow = i % itemCountSecondaryDirection;
		}
		else
		{
			curColumn = i % itemCountSecondaryDirection;
			curRow = i / itemCountSecondaryDirection;
		}

		Box childMargin = v->GetLayoutMargin();
		v->SetRelativePosition(columnPositions[curColumn] + childMargin.left, rowPositions[curRow] + childMargin.top);
	}
}

View* GridView::Copy()
{
	GridView* gridView = new GridView();

	gridView->SetSize(size);
	gridView->SetRelativePosition(relativePosition);
	gridView->SetItemCountSecondaryDirection(itemCountSecondaryDirection);
	gridView->SetOrientation(orientation);

	for (View* view : children)
	{
		gridView->AddChildView(view->Copy());
	}

	return gridView;
}

int GridView::GetItemCountSecondaryDirection()
{
	return itemCountSecondaryDirection;
}

void GridView::SetItemCountSecondaryDirection(int count)
{
	itemCountSecondaryDirection = count;
}

Orientation GridView::GetOrientation()
{
	return orientation;
}

void GridView::SetOrientation(Orientation orientation)
{
	this->orientation = orientation;
}

bool GridView::SetProperty(string name, string value)
{
	bool propertyHandled = View::SetProperty(name, value);

	if (propertyHandled)
		return true;

	if (name == "orientation")
	{
		if (value == "horizontal")
			SetOrientation(OrientationHorizontal);
		else if (value == "vertical")
			SetOrientation(OrientationVertical);
		else
			throw runtime_error("invalid orientation");

		return true;
	}
	else if (name == "itemCountSecondaryDirection")
	{
		int itemCountSecondaryDirectionIntValue = atoi(value.c_str());
		if (itemCountSecondaryDirectionIntValue <= 0)
			throw runtime_error("invalid value for itemCountSecondaryDirection");
		SetItemCountSecondaryDirection(itemCountSecondaryDirectionIntValue);

		return true;
	}

	return false;
}
<commit_msg>Fix memory leaks<commit_after>#include "GridView.h"

using namespace std;

GridView::GridView()
{
	contentSize.w = 0;
	contentSize.h = 0;
	selectedPosition = -1;
	itemCountSecondaryDirection = 1;
	orientation = OrientationHorizontal;

	itemMargin = 0;
}

GridView::~GridView()
{
}

bool GridView::Initialize(ResourceManager* resourceManager, SDL_Renderer* renderer)
{
	isInitialized = true;
	return true;
}

void GridView::Update()
{
}

void GridView::Draw(SDL_Renderer* renderer)
{
	if (calculatedSize.w == 0 || calculatedSize.h == 0)
		return;

	if (contentSize.w == 0 || contentSize.h == 0)
		return;

	for (int i = 0; i < children.size(); i++)
	{
		children[i]->Draw(renderer);
	}
}

void GridView::OnLayoutChange()
{
	if (itemCountSecondaryDirection <= 0)
		throw runtime_error("GridView: itemCountSecondaryDirection must be greater than zero");

	int itemsInWidth = 0;
	int itemsInHeight = 0;

	if (orientation == OrientationHorizontal)
	{
		itemsInWidth = children.size() / itemCountSecondaryDirection;
		itemsInHeight = itemCountSecondaryDirection;

		if (children.size() % itemCountSecondaryDirection != 0)
			itemsInWidth++;
	}
	else
	{
		itemsInWidth = itemCountSecondaryDirection;
		itemsInHeight = children.size() / itemCountSecondaryDirection;

		if (children.size() % itemCountSecondaryDirection != 0)
			itemsInHeight++;
	}

	int* columnSizes = new int[itemsInWidth];
	int* rowSizes = new int[itemsInHeight];

	int* columnPositions = new int[itemsInWidth];
	int* rowPositions = new int[itemsInHeight];

	memset(columnSizes, 0, itemsInWidth * sizeof(int));
	memset(rowSizes, 0, itemsInHeight * sizeof(int));

	memset(columnPositions, 0, itemsInWidth * sizeof(int));
	memset(rowPositions, 0, itemsInHeight * sizeof(int));

	// Calculate column and row sizes
	for (int i = 0; i < children.size(); i++)
	{
		View* v = children.at(i);

		int curColumn;
		int curRow;

		if (orientation == OrientationHorizontal)
		{
			curColumn = i / itemCountSecondaryDirection;
			curRow = i % itemCountSecondaryDirection;
		}
		else
		{
			curColumn = i % itemCountSecondaryDirection;
			curRow = i / itemCountSecondaryDirection;
		}

		Box childMargin = v->GetLayoutMargin();
		Size childSize = v->CalculateLayout(Position(0, 0), Size(-1, -1));
		Size childSizeIncMargins = childSize + Size(childMargin.left + childMargin.right, childMargin.top + childMargin.bottom);

		if (childSizeIncMargins.w > columnSizes[curColumn])
			columnSizes[curColumn] = childSizeIncMargins.w;

		if (childSizeIncMargins.h > rowSizes[curRow])
			rowSizes[curRow] = childSizeIncMargins.h;
	}

	// Calculate positions for columns and rows
	for (int i = 0; i < itemsInWidth; i++)
	{
		if (i == 0)
			columnPositions[i] = 0;
		else
			columnPositions[i] = columnPositions[i - 1] + columnSizes[i - 1] + itemMargin;
	}

	for (int i = 0; i < itemsInHeight; i++)
	{
		if (i == 0)
			rowPositions[i] = 0;
		else
			rowPositions[i] = rowPositions[i - 1] + rowSizes[i - 1] + itemMargin;
	}

	// Set content area size
	contentSize.w = columnPositions[itemsInWidth - 1] + columnSizes[itemsInWidth - 1];
	contentSize.h = rowPositions[itemsInHeight - 1] + rowSizes[itemsInHeight - 1];

	// Position children
	for (int i = 0; i < children.size(); i++)
	{
		View* v = children.at(i);

		int curColumn;
		int curRow;

		if (orientation == OrientationHorizontal)
		{
			curColumn = i / itemCountSecondaryDirection;
			curRow = i % itemCountSecondaryDirection;
		}
		else
		{
			curColumn = i % itemCountSecondaryDirection;
			curRow = i / itemCountSecondaryDirection;
		}

		Box childMargin = v->GetLayoutMargin();
		v->SetRelativePosition(columnPositions[curColumn] + childMargin.left, rowPositions[curRow] + childMargin.top);
	}

	delete[] columnSizes;
	delete[] rowSizes;
	delete[] columnPositions;
	delete[] rowPositions;
}

View* GridView::Copy()
{
	GridView* gridView = new GridView();

	gridView->SetSize(size);
	gridView->SetRelativePosition(relativePosition);
	gridView->SetItemCountSecondaryDirection(itemCountSecondaryDirection);
	gridView->SetOrientation(orientation);

	for (View* view : children)
	{
		gridView->AddChildView(view->Copy());
	}

	return gridView;
}

int GridView::GetItemCountSecondaryDirection()
{
	return itemCountSecondaryDirection;
}

void GridView::SetItemCountSecondaryDirection(int count)
{
	itemCountSecondaryDirection = count;
}

Orientation GridView::GetOrientation()
{
	return orientation;
}

void GridView::SetOrientation(Orientation orientation)
{
	this->orientation = orientation;
}

bool GridView::SetProperty(string name, string value)
{
	bool propertyHandled = View::SetProperty(name, value);

	if (propertyHandled)
		return true;

	if (name == "orientation")
	{
		if (value == "horizontal")
			SetOrientation(OrientationHorizontal);
		else if (value == "vertical")
			SetOrientation(OrientationVertical);
		else
			throw runtime_error("invalid orientation");

		return true;
	}
	else if (name == "itemCountSecondaryDirection")
	{
		int itemCountSecondaryDirectionIntValue = atoi(value.c_str());
		if (itemCountSecondaryDirectionIntValue <= 0)
			throw runtime_error("invalid value for itemCountSecondaryDirection");
		SetItemCountSecondaryDirection(itemCountSecondaryDirectionIntValue);

		return true;
	}

	return false;
}
<|endoftext|>


<commit_before>#include "chainerx/native/native_device.h"

#include <cmath>
#include <cstdint>

#include "chainerx/array.h"
#include "chainerx/device.h"
#include "chainerx/dtype.h"
#include "chainerx/kernels/math.h"
#include "chainerx/native/elementwise.h"
#include "chainerx/native/kernel_regist.h"
#include "chainerx/numeric.h"
#include "chainerx/routines/math.h"

namespace chainerx {
namespace native {
namespace {

class NativePowKernel : public PowKernel {
public:
    void Call(const Array& x1, const Array& x2, const Array& out) override {
        x1.device().CheckDevicesCompatible(x1, x2, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T x2, T& out) { out = chainerx::Pow(x1, x2); }
            };
            Elementwise<const T, const T, T>(Impl{}, x1, x2, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowKernel, NativePowKernel);

class NativePowASKernel : public PowASKernel {
public:
    void Call(const Array& x1, Scalar x2, const Array& out) override {
        x1.device().CheckDevicesCompatible(x1, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T& out) { out = chainerx::Pow(x1, x2); }
                T x2;
            };
            Elementwise<const T, T>(Impl{static_cast<T>(x2)}, x1, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowASKernel, NativePowASKernel);

class NativePowSAKernel : public PowSAKernel {
public:
    void Call(Scalar x1, const Array& x2, const Array& out) {
        x2.device().CheckDevicesCompatible(x2, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T& out) { out = chainerx::Pow(x2, x1); }
                T x2;
            };
            Elementwise<const T, T>(Impl{static_cast<T>(x1)}, x2, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowSAKernel, NativePowSAKernel);

class NativeSquareKernel : public SquareKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = x * x; }
            };
            Elementwise<const T, T>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SquareKernel, NativeSquareKernel);

class NativeSqrtKernel : public SqrtKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Sqrt(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SqrtKernel, NativeSqrtKernel);

class NativeIsNanKernel : public IsNanKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = chainerx::IsNan(x); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsNanKernel, NativeIsNanKernel);

class NativeIsInfKernel : public IsInfKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = chainerx::IsInf(x); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsInfKernel, NativeIsInfKernel);

class NativeIsFiniteKernel : public IsFiniteKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = !(chainerx::IsInf(x) || chainerx::IsNan(x)); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsFiniteKernel, NativeIsFiniteKernel);

class NativeCeilKernel : public CeilKernel {
public:
    void Call(const Array& x, const Array& out) override {
        Device& device = x.device();
        device.CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Ceil(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(CeilKernel, NativeCeilKernel);

class NativeFloorKernel : public FloorKernel {
public:
    void Call(const Array& x, const Array& out) override {
        Device& device = x.device();
        device.CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Floor(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(FloorKernel, NativeFloorKernel);

}  // namespace
}  // namespace native
}  // namespace chainerx
<commit_msg>add missing override<commit_after>#include "chainerx/native/native_device.h"

#include <cmath>
#include <cstdint>

#include "chainerx/array.h"
#include "chainerx/device.h"
#include "chainerx/dtype.h"
#include "chainerx/kernels/math.h"
#include "chainerx/native/elementwise.h"
#include "chainerx/native/kernel_regist.h"
#include "chainerx/numeric.h"
#include "chainerx/routines/math.h"

namespace chainerx {
namespace native {
namespace {

class NativePowKernel : public PowKernel {
public:
    void Call(const Array& x1, const Array& x2, const Array& out) override {
        x1.device().CheckDevicesCompatible(x1, x2, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T x2, T& out) { out = chainerx::Pow(x1, x2); }
            };
            Elementwise<const T, const T, T>(Impl{}, x1, x2, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowKernel, NativePowKernel);

class NativePowASKernel : public PowASKernel {
public:
    void Call(const Array& x1, Scalar x2, const Array& out) override {
        x1.device().CheckDevicesCompatible(x1, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T& out) { out = chainerx::Pow(x1, x2); }
                T x2;
            };
            Elementwise<const T, T>(Impl{static_cast<T>(x2)}, x1, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowASKernel, NativePowASKernel);

class NativePowSAKernel : public PowSAKernel {
public:
    void Call(Scalar x1, const Array& x2, const Array& out) override {
        x2.device().CheckDevicesCompatible(x2, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T& out) { out = chainerx::Pow(x2, x1); }
                T x2;
            };
            Elementwise<const T, T>(Impl{static_cast<T>(x1)}, x2, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowSAKernel, NativePowSAKernel);

class NativeSquareKernel : public SquareKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = x * x; }
            };
            Elementwise<const T, T>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SquareKernel, NativeSquareKernel);

class NativeSqrtKernel : public SqrtKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Sqrt(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SqrtKernel, NativeSqrtKernel);

class NativeIsNanKernel : public IsNanKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = chainerx::IsNan(x); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsNanKernel, NativeIsNanKernel);

class NativeIsInfKernel : public IsInfKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = chainerx::IsInf(x); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsInfKernel, NativeIsInfKernel);

class NativeIsFiniteKernel : public IsFiniteKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = !(chainerx::IsInf(x) || chainerx::IsNan(x)); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsFiniteKernel, NativeIsFiniteKernel);

class NativeCeilKernel : public CeilKernel {
public:
    void Call(const Array& x, const Array& out) override {
        Device& device = x.device();
        device.CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Ceil(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(CeilKernel, NativeCeilKernel);

class NativeFloorKernel : public FloorKernel {
public:
    void Call(const Array& x, const Array& out) override {
        Device& device = x.device();
        device.CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Floor(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(FloorKernel, NativeFloorKernel);

}  // namespace
}  // namespace native
}  // namespace chainerx
<|endoftext|>


<commit_before>#include "chainerx/native/native_device.h"

#include <cmath>
#include <cstdint>

#include "chainerx/array.h"
#include "chainerx/device.h"
#include "chainerx/dtype.h"
#include "chainerx/kernels/math.h"
#include "chainerx/native/elementwise.h"
#include "chainerx/native/kernel_regist.h"
#include "chainerx/numeric.h"
#include "chainerx/routines/math.h"

namespace chainerx {
namespace native {
namespace {

class NativePowKernel : public PowKernel {
public:
    void Call(const Array& x1, const Array& x2, const Array& out) override {
        x1.device().CheckDevicesCompatible(x1, x2, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T x2, T& out) { out = chainerx::Pow(x1, x2); }
            };
            Elementwise<const T, const T, T>(Impl{}, x1, x2, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowKernel, NativePowKernel);

class NativePowASKernel : public PowASKernel {
public:
    void Call(const Array& x1, Scalar x2, const Array& out) {
        x1.device().CheckDevicesCompatible(x1, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T& out) { out = chainerx::Pow(x1, x2); }
                T x2;
            };
            Elementwise<const T, T>(Impl{static_cast<T>(x2)}, x1, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowASKernel, NativePowASKernel);

class NativePowSAKernel : public PowSAKernel {
public:
    void Call(Scalar x1, const Array& x2, const Array& out) {
        x2.device().CheckDevicesCompatible(x2, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T& out) { out = chainerx::Pow(x2, x1); }
                T x2;
            };
            Elementwise<const T, T>(Impl{static_cast<T>(x1)}, x2, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowSAKernel, NativePowSAKernel);

class NativeSquareKernel : public SquareKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = x * x; }
            };
            Elementwise<const T, T>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SquareKernel, NativeSquareKernel);

class NativeSqrtKernel : public SqrtKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Sqrt(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SqrtKernel, NativeSqrtKernel);

class NativeIsNanKernel : public IsNanKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = chainerx::IsNan(x); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsNanKernel, NativeIsNanKernel);

class NativeIsInfKernel : public IsInfKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = chainerx::IsInf(x); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsInfKernel, NativeIsInfKernel);

class NativeIsFiniteKernel : public IsFiniteKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = !(chainerx::IsInf(x) || chainerx::IsNan(x)); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsFiniteKernel, NativeIsFiniteKernel);

class NativeCeilKernel : public CeilKernel {
public:
    void Call(const Array& x, const Array& out) override {
        Device& device = x.device();
        device.CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Ceil(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(CeilKernel, NativeCeilKernel);

class NativeFloorKernel : public FloorKernel {
public:
    void Call(const Array& x, const Array& out) override {
        Device& device = x.device();
        device.CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Floor(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(FloorKernel, NativeFloorKernel);

}  // namespace
}  // namespace native
}  // namespace chainerx
<commit_msg>add missing override<commit_after>#include "chainerx/native/native_device.h"

#include <cmath>
#include <cstdint>

#include "chainerx/array.h"
#include "chainerx/device.h"
#include "chainerx/dtype.h"
#include "chainerx/kernels/math.h"
#include "chainerx/native/elementwise.h"
#include "chainerx/native/kernel_regist.h"
#include "chainerx/numeric.h"
#include "chainerx/routines/math.h"

namespace chainerx {
namespace native {
namespace {

class NativePowKernel : public PowKernel {
public:
    void Call(const Array& x1, const Array& x2, const Array& out) override {
        x1.device().CheckDevicesCompatible(x1, x2, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T x2, T& out) { out = chainerx::Pow(x1, x2); }
            };
            Elementwise<const T, const T, T>(Impl{}, x1, x2, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowKernel, NativePowKernel);

class NativePowASKernel : public PowASKernel {
public:
    void Call(const Array& x1, Scalar x2, const Array& out) override {
        x1.device().CheckDevicesCompatible(x1, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T& out) { out = chainerx::Pow(x1, x2); }
                T x2;
            };
            Elementwise<const T, T>(Impl{static_cast<T>(x2)}, x1, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowASKernel, NativePowASKernel);

class NativePowSAKernel : public PowSAKernel {
public:
    void Call(Scalar x1, const Array& x2, const Array& out) {
        x2.device().CheckDevicesCompatible(x2, out);
        VisitNumericDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x1, T& out) { out = chainerx::Pow(x2, x1); }
                T x2;
            };
            Elementwise<const T, T>(Impl{static_cast<T>(x1)}, x2, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(PowSAKernel, NativePowSAKernel);

class NativeSquareKernel : public SquareKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = x * x; }
            };
            Elementwise<const T, T>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SquareKernel, NativeSquareKernel);

class NativeSqrtKernel : public SqrtKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Sqrt(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SqrtKernel, NativeSqrtKernel);

class NativeIsNanKernel : public IsNanKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = chainerx::IsNan(x); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsNanKernel, NativeIsNanKernel);

class NativeIsInfKernel : public IsInfKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = chainerx::IsInf(x); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsInfKernel, NativeIsInfKernel);

class NativeIsFiniteKernel : public IsFiniteKernel {
public:
    void Call(const Array& x, const Array& out) override {
        x.device().CheckDevicesCompatible(x, out);
        VisitDtype(x.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, bool& out) { out = !(chainerx::IsInf(x) || chainerx::IsNan(x)); }
            };
            Elementwise<const T, bool>(Impl{}, x, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(IsFiniteKernel, NativeIsFiniteKernel);

class NativeCeilKernel : public CeilKernel {
public:
    void Call(const Array& x, const Array& out) override {
        Device& device = x.device();
        device.CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Ceil(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(CeilKernel, NativeCeilKernel);

class NativeFloorKernel : public FloorKernel {
public:
    void Call(const Array& x, const Array& out) override {
        Device& device = x.device();
        device.CheckDevicesCompatible(x, out);
        const Array& x_cast = x.dtype() == out.dtype() ? x : x.AsType(out.dtype());
        VisitFloatingPointDtype(out.dtype(), [&](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                void operator()(int64_t /*i*/, T x, T& out) { out = chainerx::Floor(x); }
            };
            Elementwise<const T, T>(Impl{}, x_cast, out);
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(FloorKernel, NativeFloorKernel);

}  // namespace
}  // namespace native
}  // namespace chainerx
<|endoftext|>