<commit_before>//
//  PyQtGuiObject.cpp
//  MusicPlayer
//
//  Created by <NAME> on 18.01.14.
//  Copyright (c) 2014 <NAME>. All rights reserved.
//

#include "PyQtGuiObject.hpp"
#include "PythonHelpers.h"
#include "PyThreading.hpp"
#include "QtBaseWidget.hpp"
#include "QtApp.hpp"


static Vec imp_get_pos(GuiObject* obj) {
	Vec ret;
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget) {
			QPoint pos = widget->pos();
			ret.x = pos.x();
			ret.y = pos.y();
		}
	});
	return ret;
}

static Vec imp_get_size(GuiObject* obj) {
	Vec ret;
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget) {
			QSize size = widget->frameSize();
			ret.x = size.width();
			ret.y = size.height();
		}
	});
	return ret;
}

static Vec imp_get_innnerSize(GuiObject* obj) {
	Vec ret;
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget) {
			QSize size = widget->size();
			ret.x = size.width();
			ret.y = size.height();
		}
	});
	return ret;
}

static Autoresize imp_get_autoresize(GuiObject* obj) {
	Autoresize ret;
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget) {
			// TODO ...
			// Not sure. I think Qt doesn't do autoresizing.
		}
	});
	return ret;
}

static void imp_set_pos(GuiObject* obj, const Vec& v) {
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget)
			widget->move(v.x, v.y);
	});
}

static void imp_set_size(GuiObject* obj, const Vec& v) {
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget)
			widget->resize(v.x, v.y);
	});
}

static void imp_set_autoresize(GuiObject* obj, const Autoresize& r) {
	// TODO ...
}

static void imp_addChild(GuiObject* obj, GuiObject* child) {
	if(QtApp::isFork()) {
		printf("PyQtGuiObject::imp_addChild called in fork\n");
		return;
	}

	{
		PyScopedGIL gil;
		if(!PyType_IsSubtype(Py_TYPE(child), &QtGuiObject_Type)) {
			PyErr_Format(PyExc_ValueError, "QtGuiObject.addChild: we expect a QtGuiObject");
			return;
		}
	}
	
	execInMainThread_sync([&]() {
		auto childWidget = ((PyQtGuiObject*) child)->widget;
		((PyQtGuiObject*) obj)->addChild(childWidget);
	});
}

static void imp_meth_updateContent(GuiObject* obj) {
	((PyQtGuiObject*) obj)->updateContent();
}

// Called *with* the Python GIL.
static void imp_meth_childIter(GuiObject* obj, boost::function<void(GuiObject* child, bool& stop)> callback) {
	if(QtApp::isFork())
		// I think there is no safe way in a fork to do this.
		// Thus just skip it.
		return;
		
	// We can only access the widget from the main thread, thus this becomes a bit
	// more complicated.
	PyScopedGIUnlock unlock;
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		
		PyScopedGIL gil;
		// Warning: The callback might be called from another (the main) thread
		// here. Not sure if that is a problem. I guess (hope) not.
		widget->childIter(callback);
	});
}

QtBaseWidget* PyQtGuiObject::getParentWidget() {
	if(QtApp::isFork()) {
		printf("PyQtGuiObject::getParentWidget called in fork\n");
		return NULL;
	}

	assert(QApplication::instance()->thread() == QThread::currentThread());
	PyScopedGIL gil;
	if(parent && !PyType_IsSubtype(Py_TYPE(parent), &QtGuiObject_Type)) {
		return ((PyQtGuiObject*) parent)->widget;
	}
	return NULL;<commit_msg>warning comment<commit_after>//
//  PyQtGuiObject.cpp
//  MusicPlayer
//
//  Created by <NAME> on 18.01.14.
//  Copyright (c) 2014 <NAME>. All rights reserved.
//

#include "PyQtGuiObject.hpp"
#include "PythonHelpers.h"
#include "PyThreading.hpp"
#include "QtBaseWidget.hpp"
#include "QtApp.hpp"


static Vec imp_get_pos(GuiObject* obj) {
	Vec ret;
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget) {
			QPoint pos = widget->pos();
			ret.x = pos.x();
			ret.y = pos.y();
		}
	});
	return ret;
}

static Vec imp_get_size(GuiObject* obj) {
	Vec ret;
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget) {
			QSize size = widget->frameSize();
			ret.x = size.width();
			ret.y = size.height();
		}
	});
	return ret;
}

static Vec imp_get_innnerSize(GuiObject* obj) {
	Vec ret;
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget) {
			QSize size = widget->size();
			ret.x = size.width();
			ret.y = size.height();
		}
	});
	return ret;
}

static Autoresize imp_get_autoresize(GuiObject* obj) {
	Autoresize ret;
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget) {
			// TODO ...
			// Not sure. I think Qt doesn't do autoresizing.
		}
	});
	return ret;
}

static void imp_set_pos(GuiObject* obj, const Vec& v) {
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget)
			widget->move(v.x, v.y);
	});
}

static void imp_set_size(GuiObject* obj, const Vec& v) {
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		if(widget)
			widget->resize(v.x, v.y);
	});
}

static void imp_set_autoresize(GuiObject* obj, const Autoresize& r) {
	// TODO ...
}

static void imp_addChild(GuiObject* obj, GuiObject* child) {
	if(QtApp::isFork()) {
		printf("PyQtGuiObject::imp_addChild called in fork\n");
		return;
	}

	{
		PyScopedGIL gil;
		if(!PyType_IsSubtype(Py_TYPE(child), &QtGuiObject_Type)) {
			PyErr_Format(PyExc_ValueError, "QtGuiObject.addChild: we expect a QtGuiObject");
			return;
		}
	}
	
	execInMainThread_sync([&]() {
		auto childWidget = ((PyQtGuiObject*) child)->widget;
		((PyQtGuiObject*) obj)->addChild(childWidget);
	});
}

static void imp_meth_updateContent(GuiObject* obj) {
	((PyQtGuiObject*) obj)->updateContent();
}

// Called *with* the Python GIL.
static void imp_meth_childIter(GuiObject* obj, boost::function<void(GuiObject* child, bool& stop)> callback) {
	if(QtApp::isFork())
		// I think there is no safe way in a fork to do this.
		// Thus just skip it.
		return;
	
	// XXX: WARNING: If this is called with the Python global module-import lock,
	// and the main thread in the meanwhile waits for the module-import lock,
	// this is a deadlock!
	
	// We can only access the widget from the main thread, thus this becomes a bit
	// more complicated.
	PyScopedGIUnlock unlock;
	execInMainThread_sync([&]() {
		QtBaseWidget* widget = ((PyQtGuiObject*) obj)->widget;
		
		PyScopedGIL gil;
		// Warning: The callback might be called from another (the main) thread
		// here. Not sure if that is a problem. I guess (hope) not.
		widget->childIter(callback);
	});
}

QtBaseWidget* PyQtGuiObject::getParentWidget() {
	if(QtApp::isFork()) {
		printf("PyQtGuiObject::getParentWidget called in fork\n");
		return NULL;
	}

	assert(QApplication::instance()->thread() == QThread::currentThread());
	PyScopedGIL gil;
	if(parent && !PyType_IsSubtype(Py_TYPE(parent), &QtGuiObject_Type)) {
		return ((PyQtGuiObject*) parent)->widget;
	}
	return NULL;
{'fraction_non_alphanumeric': 0.15850388143966126, 'fraction_numerical': 0.0028228652081863093, 'mean_word_length': 4.206465833945628, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7284325', 'n_tokens_mistral': 2753, 'n_tokens_neox': 2573, 'n_words': 606}