changeset 310:5bcfe9e7db7f lifetime

Committing local changes
author maxter <spambox@d-coding.com>
date Wed, 23 Dec 2009 16:10:46 +0200
parents a7b313b8b149
children 8674fd5f34f4
files build/core.txt cpp/qt_core/QMetaObject_shell.cpp demos/deform/main.d demos/deform/pathdeform.d demos/shared/arthurstyle.d demos/shared/arthurwidgets.d demos/shared/hoverpoints.d generator/abstractmetalang.cpp generator/abstractmetalang.h generator/cppgenerator.cpp generator/cppheadergenerator.cpp generator/cppimplgenerator.cpp generator/dgenerator.cpp generator/typesystem.h generator/typesystem_core-java.java generator/typesystem_core.xml mini/test1/build
diffstat 17 files changed, 2356 insertions(+), 2329 deletions(-) [+]
line wrap: on
line diff
--- a/build/core.txt	Tue Sep 22 15:22:37 2009 +0000
+++ b/build/core.txt	Wed Dec 23 16:10:46 2009 +0200
@@ -10,16 +10,18 @@
     qt_core/QModelIndex_shell qt_core/QMetaType_shell
     qt_core/QMetaObject_shell)
 ## Module specific d files.
-set (d_files
-    QGlobal
-    qtd/Array  
+set (d_files    
     qtd/ArrayOpsPrimitive   
     qtd/Traits
     core/QString
     core/QMetaType
     core/QMetaObject)
-set (d_version_files 
+set (d_version_files
+    Core
+    Memory
+    Array    
     QtdObject
+    QGlobal
     Signal qtd/Str
     core/QLine core/QLineF
     core/QModelIndex
--- a/cpp/qt_core/QMetaObject_shell.cpp	Tue Sep 22 15:22:37 2009 +0000
+++ b/cpp/qt_core/QMetaObject_shell.cpp	Wed Dec 23 16:10:46 2009 +0200
@@ -1,7 +1,7 @@
-#include "qtd_core.h"
-#include <qobjectdefs.h>
-
-extern "C" DLL_PUBLIC void* qtd_QMetaObject_superClass(void *nativeId)
-{
-    return (void*)((QMetaObject*)nativeId)->superClass();
+#include "qtd_core.h"
+#include <qobjectdefs.h>
+
+extern "C" DLL_PUBLIC void* qtd_QMetaObject_superClass(void *nativeId)
+{
+    return (void*)((QMetaObject*)nativeId)->superClass();
 }
\ No newline at end of file
--- a/demos/deform/main.d	Tue Sep 22 15:22:37 2009 +0000
+++ b/demos/deform/main.d	Wed Dec 23 16:10:46 2009 +0200
@@ -1,74 +1,74 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the demonstration applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-module main;
-
-
-import qt.gui.QApplication;
-import pathdeform;
-import arthurstyle;
-
-
-int main(string[] args)
-{
-	scope app = new QApplication(args);
-
-	bool smallScreen = false;
-	foreach (arg; args)
-	{
-		if (arg == "-small-screen")
-			smallScreen = true;
-	}
-
-	scope deformWidget = new PathDeformWidget(null, smallScreen);
-
-	QStyle arthurStyle = new ArthurStyle();
-	deformWidget.setWidgetStyle(arthurStyle);
-	QWidget[] widgets = deformWidget.findChildren!(QWidget);
-	foreach (w; widgets)
-		w.setStyle(arthurStyle);
-
-	if (smallScreen)
-		deformWidget.showFullScreen();
-	else
-		deformWidget.show();
-
-	return app.exec();
-}
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+module main;
+
+
+import qt.gui.QApplication;
+import pathdeform;
+import arthurstyle;
+
+
+int main(string[] args)
+{
+	scope app = new QApplication(args);
+
+	bool smallScreen = false;
+	foreach (arg; args)
+	{
+		if (arg == "-small-screen")
+			smallScreen = true;
+	}
+
+	scope deformWidget = new PathDeformWidget(null, smallScreen);
+
+	QStyle arthurStyle = new ArthurStyle();
+	deformWidget.setWidgetStyle(arthurStyle);
+	QWidget[] widgets = deformWidget.findChildren!(QWidget);
+	foreach (w; widgets)
+		w.setStyle(arthurStyle);
+
+	if (smallScreen)
+		deformWidget.showFullScreen();
+	else
+		deformWidget.show();
+
+	return app.exec();
+}
--- a/demos/deform/pathdeform.d	Tue Sep 22 15:22:37 2009 +0000
+++ b/demos/deform/pathdeform.d	Wed Dec 23 16:10:46 2009 +0200
@@ -1,744 +1,744 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the demonstration applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-module pathdeform;
-
-
-import arthurwidgets,
-	qt.gui.QPainterPath,
-	qt.gui.QApplication,
-	qt.gui.QMouseEvent,
-	qt.core.QDateTime,
-	qt.core.QTimerEvent,
-	qt.core.QBasicTimer,
-	qt.gui.QLayout,
-	qt.gui.QLineEdit,
-	qt.gui.QPainter,
-	qt.gui.QSlider,
-	qt.gui.QLabel,
-	qt.gui.QDesktopWidget,
-	qt.gui.QGroupBox,
-	qt.gui.QPushButton,
-	qt.gui.QVBoxLayout,
-	qt.gui.QGridLayout,
-	qt.gui.QHBoxLayout,
-	qt.gui.QRadialGradient,
-	qt.opengl.QGLFormat,
-	tango.math.Math;
-
-
-class PathDeformControls : QWidget
-{
-	private PathDeformRenderer m_renderer;
-
-	mixin Signal!("okPressed");
-	mixin Signal!("quitPressed");
-
-	this(QWidget parent, PathDeformRenderer renderer, bool smallScreen)
-	{
-		super(parent);
-		m_renderer = renderer;
-
-		if (smallScreen)
-			layoutForSmallScreen();
-		else
-			layoutForDesktop();
-	}
-
-	void layoutForDesktop()
-	{
-		QGroupBox mainGroup = new QGroupBox(this);
-		mainGroup.setTitle(tr("Controls"));
-
-		QGroupBox radiusGroup = new QGroupBox(mainGroup);
-		radiusGroup.setTitle(tr("Lens Radius"));
-		QSlider radiusSlider = new QSlider(Qt.Horizontal, radiusGroup);
-		radiusSlider.setRange(15, 150);
-		radiusSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed);
-
-		QGroupBox deformGroup = new QGroupBox(mainGroup);
-		deformGroup.setTitle(tr("Deformation"));
-		QSlider deformSlider = new QSlider(Qt.Horizontal, deformGroup);
-		deformSlider.setRange(-100, 100);
-		deformSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed);
-
-		QGroupBox fontSizeGroup = new QGroupBox(mainGroup);
-		fontSizeGroup.setTitle(tr("Font Size"));
-		QSlider fontSizeSlider = new QSlider(Qt.Horizontal, fontSizeGroup);
-		fontSizeSlider.setRange(16, 200);
-		fontSizeSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed);
-
-		QGroupBox textGroup = new QGroupBox(mainGroup);
-		textGroup.setTitle(tr("Text"));
-		QLineEdit textInput = new QLineEdit(textGroup);
-
-		QPushButton animateButton = new QPushButton(mainGroup);
-		animateButton.setText(tr("Animated"));
-		animateButton.setCheckable(true);
-
-		QPushButton showSourceButton = new QPushButton(mainGroup);
-		showSourceButton.setText(tr("Show Source"));
-
-		version (QT_OPENGL_SUPPORT)
-		{
-			QPushButton enableOpenGLButton = new QPushButton(mainGroup);
-			enableOpenGLButton.setText(tr("Use OpenGL"));
-			enableOpenGLButton.setCheckable(true);
-			enableOpenGLButton.setChecked(m_renderer.usesOpenGL());
-			if (!QGLFormat.hasOpenGL())
-				enableOpenGLButton.hide();
-		}
-
-		QPushButton whatsThisButton = new QPushButton(mainGroup);
-		whatsThisButton.setText(tr("What's This?"));
-		whatsThisButton.setCheckable(true);
-
-		mainGroup.setFixedWidth(180);
-
-		QVBoxLayout mainGroupLayout = new QVBoxLayout(mainGroup);
-		mainGroupLayout.addWidget(radiusGroup);
-		mainGroupLayout.addWidget(deformGroup);
-		mainGroupLayout.addWidget(fontSizeGroup);
-		mainGroupLayout.addWidget(textGroup);
-		mainGroupLayout.addWidget(animateButton);
-		mainGroupLayout.addStretch(1);
-		version (QT_OPENGL_SUPPORT)
-		{
-			mainGroupLayout.addWidget(enableOpenGLButton);
-		}
-		mainGroupLayout.addWidget(showSourceButton);
-		mainGroupLayout.addWidget(whatsThisButton);
-
-		QVBoxLayout radiusGroupLayout = new QVBoxLayout(radiusGroup);
-		radiusGroupLayout.addWidget(radiusSlider);
-
-		QVBoxLayout deformGroupLayout = new QVBoxLayout(deformGroup);
-		deformGroupLayout.addWidget(deformSlider);
-
-		QVBoxLayout fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup);
-		fontSizeGroupLayout.addWidget(fontSizeSlider);
-
-		QVBoxLayout textGroupLayout = new QVBoxLayout(textGroup);
-		textGroupLayout.addWidget(textInput);
-
-		QVBoxLayout mainLayout = new QVBoxLayout(this);
-		mainLayout.addWidget(mainGroup);
-		mainLayout.setMargin(0);
-
-		radiusSlider.valueChanged.connect(&m_renderer.setRadius);
-		deformSlider.valueChanged.connect(&m_renderer.setIntensity);
-		fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize);
-		animateButton.clicked.connect(&m_renderer.setAnimated);
-		version (QT_OPENGL_SUPPORT)
-		{
-			enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL);
-		}
-
-		textInput.textChanged.connect(&m_renderer.setText);
-		m_renderer.descriptionEnabledChanged.connect(&whatsThisButton.setChecked);
-		whatsThisButton.clicked.connect(&m_renderer.setDescriptionEnabled);
-		showSourceButton.clicked.connect(&m_renderer.showSource);
-
-		animateButton.animateClick();
-		deformSlider.setValue(80);
-		fontSizeSlider.setValue(120);
-		radiusSlider.setValue(100);
-		textInput.setText(tr("Qt"));
-	}
-
-	void layoutForSmallScreen()
-	{
-		QGroupBox mainGroup = new QGroupBox(this);
-		mainGroup.setTitle(tr("Controls"));
-
-		QLabel radiusLabel = new QLabel(mainGroup);
-		radiusLabel.setText(tr("Lens Radius:"));
-		QSlider radiusSlider = new QSlider(Qt.Horizontal, mainGroup);
-		radiusSlider.setRange(15, 150);
-		radiusSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed);
-
-		QLabel deformLabel = new QLabel(mainGroup);
-		deformLabel.setText(tr("Deformation:"));
-		QSlider deformSlider = new QSlider(Qt.Horizontal, mainGroup);
-		deformSlider.setRange(-100, 100);
-		deformSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed);
-
-		QLabel fontSizeLabel = new QLabel(mainGroup);
-		fontSizeLabel.setText(tr("Font Size:"));
-		QSlider fontSizeSlider = new QSlider(Qt.Horizontal, mainGroup);
-		fontSizeSlider.setRange(16, 200);
-		fontSizeSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed);
-
-		QPushButton animateButton = new QPushButton(tr("Animated"), mainGroup);
-		animateButton.setCheckable(true);
-
-		version (QT_OPENGL_SUPPORT)
-		{
-			QPushButton enableOpenGLButton = new QPushButton(mainGroup);
-			enableOpenGLButton.setText(tr("Use OpenGL"));
-			enableOpenGLButton.setCheckable(true);
-			enableOpenGLButton.setChecked(m_renderer.usesOpenGL());
-			if (!QGLFormat.hasOpenGL())
-				enableOpenGLButton.hide();
-		}
-
-		QPushButton quitButton = new QPushButton(tr("Quit"), mainGroup);
-		QPushButton okButton = new QPushButton(tr("OK"), mainGroup);
-
-
-		QGridLayout mainGroupLayout = new QGridLayout(mainGroup);
-		mainGroupLayout.setMargin(0);
-		mainGroupLayout.addWidget(radiusLabel, 0, 0, Qt.AlignRight);
-		mainGroupLayout.addWidget(radiusSlider, 0, 1);
-		mainGroupLayout.addWidget(deformLabel, 1, 0, Qt.AlignRight);
-		mainGroupLayout.addWidget(deformSlider, 1, 1);
-		mainGroupLayout.addWidget(fontSizeLabel, 2, 0, Qt.AlignRight);
-		mainGroupLayout.addWidget(fontSizeSlider, 2, 1);
-		mainGroupLayout.addWidget(animateButton, 3,0, 1,2);
-		version (QT_OPENGL_SUPPORT)
-		{
-			mainGroupLayout.addWidget(enableOpenGLButton, 4,0, 1,2);
-		}
-
-		QVBoxLayout mainLayout = new QVBoxLayout(this);
-		mainLayout.addWidget(mainGroup);
-		mainLayout.addStretch(1);
-		mainLayout.addWidget(okButton);
-		mainLayout.addWidget(quitButton);
-
-		quitButton.clicked.connect(&emitQuitSignal);
-		okButton.clicked.connect(&emitOkSignal);
-		radiusSlider.valueChanged.connect(&m_renderer.setRadius);
-		deformSlider.valueChanged.connect(&m_renderer.setIntensity);
-		fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize);
-		animateButton.clicked.connect(&m_renderer.setAnimated);
-		version (QT_OPENGL_SUPPORT)
-		{
-			enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL);
-		}
-
-		animateButton.animateClick();
-		deformSlider.setValue(80);
-		fontSizeSlider.setValue(120);
-
-		QRect screen_size = QApplication.desktop().screenGeometry();
-		radiusSlider.setValue(qMin(screen_size.width(), screen_size.height())/5);
-		m_renderer.setText(tr("Qt"));
-	}
-
-	void emitQuitSignal()
-	{
-		quitPressed.emit;
-	}
-	
-	void emitOkSignal()
-	{
-		okPressed.emit;
-	}
-}
-
-
-class PathDeformWidget : QWidget
-{
-private:
-
-	PathDeformRenderer m_renderer;
-	PathDeformControls m_controls;
-
-public:
-
-	this(QWidget parent, bool smallScreen)
-	{
-		super(parent);
-
-		setWindowTitle(tr("Vector Deformation"));
-
-		m_renderer = new PathDeformRenderer(this, smallScreen);
-		m_renderer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding);
-
-		// Layouts
-		QHBoxLayout mainLayout = new QHBoxLayout(this);
-		mainLayout.addWidget(m_renderer);
-
-		m_controls = new PathDeformControls(null, m_renderer, smallScreen);
-		m_controls.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum);
-
-		if (!smallScreen)
-		mainLayout.addWidget(m_controls);
-
-		m_renderer.loadSourceFile(":res/deform/pathdeform.d");
-		m_renderer.loadDescription(":res/deform/pathdeform.html");
-		m_renderer.setDescriptionEnabled(false);
-
-		m_renderer.clicked.connect(&showControls);
-		m_controls.okPressed.connect(&hideControls);
-
-		m_controls.quitPressed.connect(&QApplication.quit);
-	}
-
-	void showControls()
-	{
-		m_controls.showFullScreen;
-	}
-
-	void hideControls()
-	{
-		m_controls.hide;
-	}
-
-	void setWidgetStyle(QStyle style) // TODO: QWidget.setStyle is not virtual
-	{
-		super.setStyle(style);
-		if (m_controls)
-		{
-			m_controls.setStyle(style);
-
-			QWidget[] widgets = m_controls.findChildren!(QWidget);
-			foreach (w; widgets)
-				w.setStyle(style);
-		}
-	}
-}
-
-private QRect circle_bounds(QPointF center, qreal radius, qreal compensation)
-{
-	return QRect(qRound(center.x() - radius - compensation),
-		qRound(center.y() - radius - compensation),
-		qRound((radius + compensation) * 2),
-		qRound((radius + compensation) * 2));
-}
-
-enum
-{
-	LENS_EXTENT = 10
-}
-
-class PathDeformRenderer : ArthurFrame
-{
-private:
-
-	QBasicTimer m_repaintTimer;
-	//     QBasicTimer m_fpsTimer;
-	//     int m_fpsCounter;
-	QTime m_repaintTracker;
-
-	QPainterPath[] m_paths;
-	QPointF[] m_advances;
-	QRectF m_pathBounds;
-	string m_text;
-
-	QPixmap m_lens_pixmap;
-	QImage m_lens_image;
-
-	int m_fontSize;
-	bool m_animated;
-
-	qreal m_intensity;
-	qreal m_radius;
-	QPointF m_pos;
-	QPointF m_offset;
-	QPointF m_direction;
-	QPointF m_mousePress;
-	bool m_mouseDrag;
-	bool m_smallScreen;
-
-public:
-
-	mixin Signal!("clicked");
-
-	this(QWidget widget, bool smallScreen)
-	{
-		super(widget);
-		m_radius = 100;
-		m_pos = QPointF(m_radius, m_radius);
-		m_direction = QPointF(1, 1);
-		m_fontSize = 24;
-		m_animated = true;
-		m_repaintTimer.start(25, this);
-		m_repaintTracker.start();
-		m_intensity = 100;
-		m_smallScreen = smallScreen;
-
-		//     m_fpsTimer.start(1000, this);
-		//     m_fpsCounter = 0;
-
-		generateLensPixmap();
-	}
-
-	void setFontSize(int fontSize)
-	{
-		m_fontSize = fontSize;
-		setText(m_text);
-	}
-
-	override QSize sizeHint() { return QSize(600, 500); }
-
-	bool animated() { return m_animated; }
-	int radius() { return cast(int) m_radius; }
-	int fontSize() { return m_fontSize; }
-	int intensity() { return cast(int) m_intensity; }
-	string text() { return m_text; }
-
-	void setText(string text)
-	{
-		m_text = text;
-
-		auto f = new QFont("times new roman,utopia");
-		f.setStyleStrategy(QFont.ForceOutline);
-		f.setPointSize(m_fontSize);
-		f.setStyleHint(QFont.Times);
-
-		m_paths = null;
-		m_pathBounds = QRectF();
-
-		QPointF advance;
-		
-		bool do_quick = true;
-		for (int i = 0; i < text.length; ++i) {
-			if (text[i].unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) {
-				do_quick = false;
-				break;
-			}
-		}
-
-		if (do_quick) {
-			for (int i = 0; i < text.length; ++i) {
-				QPainterPath path = new QPainterPath;
-				path.addText(advance, f, text.mid(i, 1));
-				m_pathBounds |= path.boundingRect();
-				m_paths ~= path;
-				advance += QPointF(fm.width(text.mid(i, 1)), 0);
-			}
-		} else {
-			QPainterPath path = new QPainterPath;
-			path.addText(advance, f, text);
-			m_pathBounds |= path.boundingRect();
-			m_paths ~= path;
-		}
-
-		for (int i = 0; i < m_paths.length; ++i)
-			m_paths[i] = m_paths[i] * (new QMatrix(1, 0, 0, 1, -m_pathBounds.x(), -m_pathBounds.y()));
-
-		update();
-	}
-
-	void generateLensPixmap()
-	{
-		qreal rad = m_radius + LENS_EXTENT;
-
-		QRect bounds = circle_bounds(QPointF(), rad, 0);
-
-		QPainter painter = new QPainter;
-
-		if (preferImage()) {
-			m_lens_image = new QImage(bounds.size(), QImage.Format_ARGB32_Premultiplied);
-			m_lens_image.fill(0);
-			painter.begin(m_lens_image);
-		} else {
-			m_lens_pixmap = new QPixmap(bounds.size());
-			m_lens_pixmap.fill(new QColor(Qt.transparent));
-			painter.begin(m_lens_pixmap);
-		}
-
-		auto gr = new QRadialGradient(rad, rad, rad, 3 * rad / 5, 3 * rad / 5);
-		gr.setColorAt(0.0, new QColor(255, 255, 255, 191));
-		gr.setColorAt(0.2, new QColor(255, 255, 127, 191));
-		gr.setColorAt(0.9, new QColor(150, 150, 200, 63));
-		gr.setColorAt(0.95, new QColor(0, 0, 0, 127));
-		gr.setColorAt(1, new QColor(0, 0, 0, 0));
-		painter.setRenderHint(QPainter.Antialiasing);
-		painter.setBrush(gr);
-		painter.setPen(Qt.NoPen);
-		painter.drawEllipse(0, 0, bounds.width(), bounds.height());
-	}
-
-	void setAnimated(bool animated)
-	{
-		m_animated = animated;
-
-		if (m_animated) {
-			//         m_fpsTimer.start(1000, this);
-			//         m_fpsCounter = 0;
-			m_repaintTimer.start(25, this);
-			m_repaintTracker.start();
-		} else {
-			//         m_fpsTimer.stop();
-			m_repaintTimer.stop();
-		}
-	}
-
-	override void timerEvent(QTimerEvent e)
-	{
-		if (e.timerId == m_repaintTimer.timerId) 
-		{
-			if ((QLineF(QPointF(0,0), m_direction)).length() > 1)
-				m_direction *= 0.995;
-			qreal time = m_repaintTracker.restart();
-
-			QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
-
-			qreal dx = m_direction.x();
-			qreal dy = m_direction.y();
-			if (time > 0) {
-				dx = dx * time * .1;
-				dy = dy * time * .1;
-			}
-
-			m_pos += QPointF(dx, dy);
-
-			if (m_pos.x() - m_radius < 0) {
-				m_direction.x = -m_direction.x;
-				m_pos.x = m_radius;
-			} else if (m_pos.x + m_radius > width) {
-				m_direction.x = -m_direction.x;
-				m_pos.x = width - m_radius;
-			}
-
-			if (m_pos.y - m_radius < 0) {
-				m_direction.y = -m_direction.y;
-				m_pos.y = m_radius;
-			} else if (m_pos.y + m_radius > height) {
-				m_direction.y = -m_direction.y;
-				m_pos.y = height - m_radius;
-			}
-
-			void noGLUpdate()
-			{
-				QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
-				update(rectAfter.united(rectBefore));
-				QApplication.syncX();
-			}
-
-			version (QT_OPENGL_SUPPORT)
-			{
-				if (usesOpenGL()) {
-					update;
-				}
-				else
-					noGLUpdate;
-			}
-			else
-				noGLUpdate;
-		}
-		//     else if (e.timerId() == m_fpsTimer.timerId()) {
-		//         printf("fps: %d\n", m_fpsCounter);
-		//         emit frameRate(m_fpsCounter);
-		//         m_fpsCounter = 0;
-
-		//     }
-	}
-
-	override void mousePressEvent(QMouseEvent e)
-	{
-		setDescriptionEnabled(false);
-
-		m_repaintTimer.stop();
-		m_offset = QPointF();
-		if ((QLineF(m_pos, QPointF(e.pos))).length <= m_radius)
-			m_offset = m_pos - QPointF(e.pos);
-
-		m_mousePress = QPointF(e.pos);
-
-		// If we're not running in small screen mode, always assume we're dragging
-		m_mouseDrag = !m_smallScreen;
-
-		mouseMoveEvent(e);
-	}
-
-	override void mouseReleaseEvent(QMouseEvent e)
-	{
-		if (e.buttons() == Qt.NoButton && m_animated) {
-			m_repaintTimer.start(10, this);
-			m_repaintTracker.start();
-		}
-
-		if (!m_mouseDrag && m_smallScreen)
-			clicked.emit;
-	}
-
-	override void mouseMoveEvent(QMouseEvent e)
-	{
-		auto epos = QPointF(e.pos);
-
-		if (!m_mouseDrag && (QLineF(m_mousePress, QPointF(e.pos))).length() > 25.0)
-		m_mouseDrag = true;
-
-		if (m_mouseDrag)
-		{
-			QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
-			if (e.type() == QEvent.MouseMove) {
-				QLineF line = QLineF(m_pos, epos + m_offset);
-				line.setLength(line.length() * .1);
-				auto dir = QPointF(line.dx(), line.dy());
-				m_direction = (m_direction + dir) / 2;
-			}
-			m_pos = epos + m_offset;
-
-			void noGLUpdate()
-			{
-				QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
-				update(rectBefore.united(rectAfter));
-			}
-
-			version (QT_OPENGL_SUPPORT)
-			{
-				if (usesOpenGL()) {
-					update;
-				} else
-					noGLUpdate;
-			}
-			else
-				noGLUpdate;
-		}
-	}
-
-	QPainterPath lensDeform(QPainterPath source, QPointF offset)
-	{
-		auto path = new QPainterPath;
-		path.addPath(source);
-
-		qreal flip = m_intensity / 100.0;
-
-		for (int i=0; i<path.elementCount; ++i)
-		{
-			auto e = path.elementAt(i);
-
-			qreal x = e.x + offset.x();
-			qreal y = e.y + offset.y();
-
-			qreal dx = x - m_pos.x();
-			qreal dy = y - m_pos.y();
-			qreal len = m_radius - sqrt(dx * dx + dy * dy);
-
-			if (len > 0) {
-				path.setElementPositionAt(i,
-					  x + flip * dx * len / m_radius,
-					  y + flip * dy * len / m_radius);
-			} else {
-				path.setElementPositionAt(i, x, y);
-			}
-		}
-
-		return path;
-	}
-
-	override void paint(QPainter painter)
-	{
-		int pad_x = 5;
-		int pad_y = 5;
-
-		int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2);
-		int skip_y = qRound(m_pathBounds.height() + pad_y);
-
-		painter.setPen(Qt.NoPen);
-		painter.setBrush(new QColor(Qt.black));
-
-		auto clip = painter.clipPath().boundingRect();
-
-		int overlap = pad_x / 2;
-
-		for (int start_y=0; start_y < height(); start_y += skip_y)
-		{
-			if (start_y > clip.bottom())
-			break;
-
-			int start_x = -overlap;
-			for (; start_x < width(); start_x += skip_x)
-			{
-				if (start_y + skip_y >= clip.top() &&
-					start_x + skip_x >= clip.left() &&
-					start_x <= clip.right())
-				{
-					for (int i=0; i<m_paths.length; ++i) {
-						QPainterPath path = lensDeform(m_paths[i], QPointF(start_x, start_y));
-						painter.drawPath(path);
-					}
-				}
-			}
-			overlap = skip_x - (start_x - width());
-		}
-
-		if (preferImage) {
-			painter.drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), m_lens_image);
-		} else {
-			painter.drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), m_lens_pixmap);
-		}
-	}
-
-	void setRadius(int radius)
-	{
-		qreal max = max(m_radius, cast(qreal)radius);
-		m_radius = radius;
-		generateLensPixmap();
-		if (!m_animated || m_radius < max)
-		{
-			auto noGLUpdate = (){ update(circle_bounds(m_pos, max, m_fontSize)); };
-
-			version (QT_OPENGL_SUPPORT)
-			{
-				if (usesOpenGL())
-					update();
-				else
-					noGLUpdate();
-			}
-			else
-				noGLUpdate();
-		}
-	}
-
-	void setIntensity(int intensity)
-	{
-		m_intensity = intensity;
-		if (!m_animated)
-		{
-			auto noGLUpdate = (){ update(circle_bounds(m_pos, m_radius, m_fontSize)); };
-
-			version (QT_OPENGL_SUPPORT)
-			{
-				if (usesOpenGL()) {
-					update();
-				} else
-					noGLUpdate();
-			}
-			else
-				noGLUpdate();
-		}
-	}
-}
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+module pathdeform;
+
+
+import arthurwidgets,
+	qt.gui.QPainterPath,
+	qt.gui.QApplication,
+	qt.gui.QMouseEvent,
+	qt.core.QDateTime,
+	qt.core.QTimerEvent,
+	qt.core.QBasicTimer,
+	qt.gui.QLayout,
+	qt.gui.QLineEdit,
+	qt.gui.QPainter,
+	qt.gui.QSlider,
+	qt.gui.QLabel,
+	qt.gui.QDesktopWidget,
+	qt.gui.QGroupBox,
+	qt.gui.QPushButton,
+	qt.gui.QVBoxLayout,
+	qt.gui.QGridLayout,
+	qt.gui.QHBoxLayout,
+	qt.gui.QRadialGradient,
+	qt.opengl.QGLFormat,
+	tango.math.Math;
+
+
+class PathDeformControls : QWidget
+{
+	private PathDeformRenderer m_renderer;
+
+	mixin Signal!("okPressed");
+	mixin Signal!("quitPressed");
+
+	this(QWidget parent, PathDeformRenderer renderer, bool smallScreen)
+	{
+		super(parent);
+		m_renderer = renderer;
+
+		if (smallScreen)
+			layoutForSmallScreen();
+		else
+			layoutForDesktop();
+	}
+
+	void layoutForDesktop()
+	{
+		QGroupBox mainGroup = new QGroupBox(this);
+		mainGroup.setTitle(tr("Controls"));
+
+		QGroupBox radiusGroup = new QGroupBox(mainGroup);
+		radiusGroup.setTitle(tr("Lens Radius"));
+		QSlider radiusSlider = new QSlider(Qt.Horizontal, radiusGroup);
+		radiusSlider.setRange(15, 150);
+		radiusSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed);
+
+		QGroupBox deformGroup = new QGroupBox(mainGroup);
+		deformGroup.setTitle(tr("Deformation"));
+		QSlider deformSlider = new QSlider(Qt.Horizontal, deformGroup);
+		deformSlider.setRange(-100, 100);
+		deformSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed);
+
+		QGroupBox fontSizeGroup = new QGroupBox(mainGroup);
+		fontSizeGroup.setTitle(tr("Font Size"));
+		QSlider fontSizeSlider = new QSlider(Qt.Horizontal, fontSizeGroup);
+		fontSizeSlider.setRange(16, 200);
+		fontSizeSlider.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed);
+
+		QGroupBox textGroup = new QGroupBox(mainGroup);
+		textGroup.setTitle(tr("Text"));
+		QLineEdit textInput = new QLineEdit(textGroup);
+
+		QPushButton animateButton = new QPushButton(mainGroup);
+		animateButton.setText(tr("Animated"));
+		animateButton.setCheckable(true);
+
+		QPushButton showSourceButton = new QPushButton(mainGroup);
+		showSourceButton.setText(tr("Show Source"));
+
+		version (QT_OPENGL_SUPPORT)
+		{
+			QPushButton enableOpenGLButton = new QPushButton(mainGroup);
+			enableOpenGLButton.setText(tr("Use OpenGL"));
+			enableOpenGLButton.setCheckable(true);
+			enableOpenGLButton.setChecked(m_renderer.usesOpenGL());
+			if (!QGLFormat.hasOpenGL())
+				enableOpenGLButton.hide();
+		}
+
+		QPushButton whatsThisButton = new QPushButton(mainGroup);
+		whatsThisButton.setText(tr("What's This?"));
+		whatsThisButton.setCheckable(true);
+
+		mainGroup.setFixedWidth(180);
+
+		QVBoxLayout mainGroupLayout = new QVBoxLayout(mainGroup);
+		mainGroupLayout.addWidget(radiusGroup);
+		mainGroupLayout.addWidget(deformGroup);
+		mainGroupLayout.addWidget(fontSizeGroup);
+		mainGroupLayout.addWidget(textGroup);
+		mainGroupLayout.addWidget(animateButton);
+		mainGroupLayout.addStretch(1);
+		version (QT_OPENGL_SUPPORT)
+		{
+			mainGroupLayout.addWidget(enableOpenGLButton);
+		}
+		mainGroupLayout.addWidget(showSourceButton);
+		mainGroupLayout.addWidget(whatsThisButton);
+
+		QVBoxLayout radiusGroupLayout = new QVBoxLayout(radiusGroup);
+		radiusGroupLayout.addWidget(radiusSlider);
+
+		QVBoxLayout deformGroupLayout = new QVBoxLayout(deformGroup);
+		deformGroupLayout.addWidget(deformSlider);
+
+		QVBoxLayout fontSizeGroupLayout = new QVBoxLayout(fontSizeGroup);
+		fontSizeGroupLayout.addWidget(fontSizeSlider);
+
+		QVBoxLayout textGroupLayout = new QVBoxLayout(textGroup);
+		textGroupLayout.addWidget(textInput);
+
+		QVBoxLayout mainLayout = new QVBoxLayout(this);
+		mainLayout.addWidget(mainGroup);
+		mainLayout.setMargin(0);
+
+		radiusSlider.valueChanged.connect(&m_renderer.setRadius);
+		deformSlider.valueChanged.connect(&m_renderer.setIntensity);
+		fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize);
+		animateButton.clicked.connect(&m_renderer.setAnimated);
+		version (QT_OPENGL_SUPPORT)
+		{
+			enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL);
+		}
+
+		textInput.textChanged.connect(&m_renderer.setText);
+		m_renderer.descriptionEnabledChanged.connect(&whatsThisButton.setChecked);
+		whatsThisButton.clicked.connect(&m_renderer.setDescriptionEnabled);
+		showSourceButton.clicked.connect(&m_renderer.showSource);
+
+		animateButton.animateClick();
+		deformSlider.setValue(80);
+		fontSizeSlider.setValue(120);
+		radiusSlider.setValue(100);
+		textInput.setText(tr("Qt"));
+	}
+
+	void layoutForSmallScreen()
+	{
+		QGroupBox mainGroup = new QGroupBox(this);
+		mainGroup.setTitle(tr("Controls"));
+
+		QLabel radiusLabel = new QLabel(mainGroup);
+		radiusLabel.setText(tr("Lens Radius:"));
+		QSlider radiusSlider = new QSlider(Qt.Horizontal, mainGroup);
+		radiusSlider.setRange(15, 150);
+		radiusSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed);
+
+		QLabel deformLabel = new QLabel(mainGroup);
+		deformLabel.setText(tr("Deformation:"));
+		QSlider deformSlider = new QSlider(Qt.Horizontal, mainGroup);
+		deformSlider.setRange(-100, 100);
+		deformSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed);
+
+		QLabel fontSizeLabel = new QLabel(mainGroup);
+		fontSizeLabel.setText(tr("Font Size:"));
+		QSlider fontSizeSlider = new QSlider(Qt.Horizontal, mainGroup);
+		fontSizeSlider.setRange(16, 200);
+		fontSizeSlider.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed);
+
+		QPushButton animateButton = new QPushButton(tr("Animated"), mainGroup);
+		animateButton.setCheckable(true);
+
+		version (QT_OPENGL_SUPPORT)
+		{
+			QPushButton enableOpenGLButton = new QPushButton(mainGroup);
+			enableOpenGLButton.setText(tr("Use OpenGL"));
+			enableOpenGLButton.setCheckable(true);
+			enableOpenGLButton.setChecked(m_renderer.usesOpenGL());
+			if (!QGLFormat.hasOpenGL())
+				enableOpenGLButton.hide();
+		}
+
+		QPushButton quitButton = new QPushButton(tr("Quit"), mainGroup);
+		QPushButton okButton = new QPushButton(tr("OK"), mainGroup);
+
+
+		QGridLayout mainGroupLayout = new QGridLayout(mainGroup);
+		mainGroupLayout.setMargin(0);
+		mainGroupLayout.addWidget(radiusLabel, 0, 0, Qt.AlignRight);
+		mainGroupLayout.addWidget(radiusSlider, 0, 1);
+		mainGroupLayout.addWidget(deformLabel, 1, 0, Qt.AlignRight);
+		mainGroupLayout.addWidget(deformSlider, 1, 1);
+		mainGroupLayout.addWidget(fontSizeLabel, 2, 0, Qt.AlignRight);
+		mainGroupLayout.addWidget(fontSizeSlider, 2, 1);
+		mainGroupLayout.addWidget(animateButton, 3,0, 1,2);
+		version (QT_OPENGL_SUPPORT)
+		{
+			mainGroupLayout.addWidget(enableOpenGLButton, 4,0, 1,2);
+		}
+
+		QVBoxLayout mainLayout = new QVBoxLayout(this);
+		mainLayout.addWidget(mainGroup);
+		mainLayout.addStretch(1);
+		mainLayout.addWidget(okButton);
+		mainLayout.addWidget(quitButton);
+
+		quitButton.clicked.connect(&emitQuitSignal);
+		okButton.clicked.connect(&emitOkSignal);
+		radiusSlider.valueChanged.connect(&m_renderer.setRadius);
+		deformSlider.valueChanged.connect(&m_renderer.setIntensity);
+		fontSizeSlider.valueChanged.connect(&m_renderer.setFontSize);
+		animateButton.clicked.connect(&m_renderer.setAnimated);
+		version (QT_OPENGL_SUPPORT)
+		{
+			enableOpenGLButton.clicked.connect(&m_renderer.enableOpenGL);
+		}
+
+		animateButton.animateClick();
+		deformSlider.setValue(80);
+		fontSizeSlider.setValue(120);
+
+		QRect screen_size = QApplication.desktop().screenGeometry();
+		radiusSlider.setValue(qMin(screen_size.width(), screen_size.height())/5);
+		m_renderer.setText(tr("Qt"));
+	}
+
+	void emitQuitSignal()
+	{
+		quitPressed.emit;
+	}
+	
+	void emitOkSignal()
+	{
+		okPressed.emit;
+	}
+}
+
+
+class PathDeformWidget : QWidget
+{
+private:
+
+	PathDeformRenderer m_renderer;
+	PathDeformControls m_controls;
+
+public:
+
+	this(QWidget parent, bool smallScreen)
+	{
+		super(parent);
+
+		setWindowTitle(tr("Vector Deformation"));
+
+		m_renderer = new PathDeformRenderer(this, smallScreen);
+		m_renderer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding);
+
+		// Layouts
+		QHBoxLayout mainLayout = new QHBoxLayout(this);
+		mainLayout.addWidget(m_renderer);
+
+		m_controls = new PathDeformControls(null, m_renderer, smallScreen);
+		m_controls.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum);
+
+		if (!smallScreen)
+		mainLayout.addWidget(m_controls);
+
+		m_renderer.loadSourceFile(":res/deform/pathdeform.d");
+		m_renderer.loadDescription(":res/deform/pathdeform.html");
+		m_renderer.setDescriptionEnabled(false);
+
+		m_renderer.clicked.connect(&showControls);
+		m_controls.okPressed.connect(&hideControls);
+
+		m_controls.quitPressed.connect(&QApplication.quit);
+	}
+
+	void showControls()
+	{
+		m_controls.showFullScreen;
+	}
+
+	void hideControls()
+	{
+		m_controls.hide;
+	}
+
+	void setWidgetStyle(QStyle style) // TODO: QWidget.setStyle is not virtual
+	{
+		super.setStyle(style);
+		if (m_controls)
+		{
+			m_controls.setStyle(style);
+
+			QWidget[] widgets = m_controls.findChildren!(QWidget);
+			foreach (w; widgets)
+				w.setStyle(style);
+		}
+	}
+}
+
+private QRect circle_bounds(QPointF center, qreal radius, qreal compensation)
+{
+	return QRect(qRound(center.x() - radius - compensation),
+		qRound(center.y() - radius - compensation),
+		qRound((radius + compensation) * 2),
+		qRound((radius + compensation) * 2));
+}
+
+enum
+{
+	LENS_EXTENT = 10
+}
+
+class PathDeformRenderer : ArthurFrame
+{
+private:
+
+	QBasicTimer m_repaintTimer;
+	//     QBasicTimer m_fpsTimer;
+	//     int m_fpsCounter;
+	QTime m_repaintTracker;
+
+	QPainterPath[] m_paths;
+	QPointF[] m_advances;
+	QRectF m_pathBounds;
+	string m_text;
+
+	QPixmap m_lens_pixmap;
+	QImage m_lens_image;
+
+	int m_fontSize;
+	bool m_animated;
+
+	qreal m_intensity;
+	qreal m_radius;
+	QPointF m_pos;
+	QPointF m_offset;
+	QPointF m_direction;
+	QPointF m_mousePress;
+	bool m_mouseDrag;
+	bool m_smallScreen;
+
+public:
+
+	mixin Signal!("clicked");
+
+	this(QWidget widget, bool smallScreen)
+	{
+		super(widget);
+		m_radius = 100;
+		m_pos = QPointF(m_radius, m_radius);
+		m_direction = QPointF(1, 1);
+		m_fontSize = 24;
+		m_animated = true;
+		m_repaintTimer.start(25, this);
+		m_repaintTracker.start();
+		m_intensity = 100;
+		m_smallScreen = smallScreen;
+
+		//     m_fpsTimer.start(1000, this);
+		//     m_fpsCounter = 0;
+
+		generateLensPixmap();
+	}
+
+	void setFontSize(int fontSize)
+	{
+		m_fontSize = fontSize;
+		setText(m_text);
+	}
+
+	override QSize sizeHint() { return QSize(600, 500); }
+
+	bool animated() { return m_animated; }
+	int radius() { return cast(int) m_radius; }
+	int fontSize() { return m_fontSize; }
+	int intensity() { return cast(int) m_intensity; }
+	string text() { return m_text; }
+
+	void setText(string text)
+	{
+		m_text = text;
+
+		auto f = new QFont("times new roman,utopia");
+		f.setStyleStrategy(QFont.ForceOutline);
+		f.setPointSize(m_fontSize);
+		f.setStyleHint(QFont.Times);
+
+		m_paths = null;
+		m_pathBounds = QRectF();
+
+		QPointF advance;
+		
+		bool do_quick = true;
+		for (int i = 0; i < text.length; ++i) {
+			if (text[i].unicode() >= 0x4ff && text.at(i).unicode() <= 0x1e00) {
+				do_quick = false;
+				break;
+			}
+		}
+
+		if (do_quick) {
+			for (int i = 0; i < text.length; ++i) {
+				QPainterPath path = new QPainterPath;
+				path.addText(advance, f, text.mid(i, 1));
+				m_pathBounds |= path.boundingRect();
+				m_paths ~= path;
+				advance += QPointF(fm.width(text.mid(i, 1)), 0);
+			}
+		} else {
+			QPainterPath path = new QPainterPath;
+			path.addText(advance, f, text);
+			m_pathBounds |= path.boundingRect();
+			m_paths ~= path;
+		}
+
+		for (int i = 0; i < m_paths.length; ++i)
+			m_paths[i] = m_paths[i] * (new QMatrix(1, 0, 0, 1, -m_pathBounds.x(), -m_pathBounds.y()));
+
+		update();
+	}
+
+	void generateLensPixmap()
+	{
+		qreal rad = m_radius + LENS_EXTENT;
+
+		QRect bounds = circle_bounds(QPointF(), rad, 0);
+
+		QPainter painter = new QPainter;
+
+		if (preferImage()) {
+			m_lens_image = new QImage(bounds.size(), QImage.Format_ARGB32_Premultiplied);
+			m_lens_image.fill(0);
+			painter.begin(m_lens_image);
+		} else {
+			m_lens_pixmap = new QPixmap(bounds.size());
+			m_lens_pixmap.fill(new QColor(Qt.transparent));
+			painter.begin(m_lens_pixmap);
+		}
+
+		auto gr = new QRadialGradient(rad, rad, rad, 3 * rad / 5, 3 * rad / 5);
+		gr.setColorAt(0.0, new QColor(255, 255, 255, 191));
+		gr.setColorAt(0.2, new QColor(255, 255, 127, 191));
+		gr.setColorAt(0.9, new QColor(150, 150, 200, 63));
+		gr.setColorAt(0.95, new QColor(0, 0, 0, 127));
+		gr.setColorAt(1, new QColor(0, 0, 0, 0));
+		painter.setRenderHint(QPainter.Antialiasing);
+		painter.setBrush(gr);
+		painter.setPen(Qt.NoPen);
+		painter.drawEllipse(0, 0, bounds.width(), bounds.height());
+	}
+
+	void setAnimated(bool animated)
+	{
+		m_animated = animated;
+
+		if (m_animated) {
+			//         m_fpsTimer.start(1000, this);
+			//         m_fpsCounter = 0;
+			m_repaintTimer.start(25, this);
+			m_repaintTracker.start();
+		} else {
+			//         m_fpsTimer.stop();
+			m_repaintTimer.stop();
+		}
+	}
+
+	override void timerEvent(QTimerEvent e)
+	{
+		if (e.timerId == m_repaintTimer.timerId) 
+		{
+			if ((QLineF(QPointF(0,0), m_direction)).length() > 1)
+				m_direction *= 0.995;
+			qreal time = m_repaintTracker.restart();
+
+			QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
+
+			qreal dx = m_direction.x();
+			qreal dy = m_direction.y();
+			if (time > 0) {
+				dx = dx * time * .1;
+				dy = dy * time * .1;
+			}
+
+			m_pos += QPointF(dx, dy);
+
+			if (m_pos.x() - m_radius < 0) {
+				m_direction.x = -m_direction.x;
+				m_pos.x = m_radius;
+			} else if (m_pos.x + m_radius > width) {
+				m_direction.x = -m_direction.x;
+				m_pos.x = width - m_radius;
+			}
+
+			if (m_pos.y - m_radius < 0) {
+				m_direction.y = -m_direction.y;
+				m_pos.y = m_radius;
+			} else if (m_pos.y + m_radius > height) {
+				m_direction.y = -m_direction.y;
+				m_pos.y = height - m_radius;
+			}
+
+			void noGLUpdate()
+			{
+				QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
+				update(rectAfter.united(rectBefore));
+				QApplication.syncX();
+			}
+
+			version (QT_OPENGL_SUPPORT)
+			{
+				if (usesOpenGL()) {
+					update;
+				}
+				else
+					noGLUpdate;
+			}
+			else
+				noGLUpdate;
+		}
+		//     else if (e.timerId() == m_fpsTimer.timerId()) {
+		//         printf("fps: %d\n", m_fpsCounter);
+		//         emit frameRate(m_fpsCounter);
+		//         m_fpsCounter = 0;
+
+		//     }
+	}
+
+	override void mousePressEvent(QMouseEvent e)
+	{
+		setDescriptionEnabled(false);
+
+		m_repaintTimer.stop();
+		m_offset = QPointF();
+		if ((QLineF(m_pos, QPointF(e.pos))).length <= m_radius)
+			m_offset = m_pos - QPointF(e.pos);
+
+		m_mousePress = QPointF(e.pos);
+
+		// If we're not running in small screen mode, always assume we're dragging
+		m_mouseDrag = !m_smallScreen;
+
+		mouseMoveEvent(e);
+	}
+
+	override void mouseReleaseEvent(QMouseEvent e)
+	{
+		if (e.buttons() == Qt.NoButton && m_animated) {
+			m_repaintTimer.start(10, this);
+			m_repaintTracker.start();
+		}
+
+		if (!m_mouseDrag && m_smallScreen)
+			clicked.emit;
+	}
+
+	override void mouseMoveEvent(QMouseEvent e)
+	{
+		auto epos = QPointF(e.pos);
+
+		if (!m_mouseDrag && (QLineF(m_mousePress, QPointF(e.pos))).length() > 25.0)
+		m_mouseDrag = true;
+
+		if (m_mouseDrag)
+		{
+			QRect rectBefore = circle_bounds(m_pos, m_radius, m_fontSize);
+			if (e.type() == QEvent.MouseMove) {
+				QLineF line = QLineF(m_pos, epos + m_offset);
+				line.setLength(line.length() * .1);
+				auto dir = QPointF(line.dx(), line.dy());
+				m_direction = (m_direction + dir) / 2;
+			}
+			m_pos = epos + m_offset;
+
+			void noGLUpdate()
+			{
+				QRect rectAfter = circle_bounds(m_pos, m_radius, m_fontSize);
+				update(rectBefore.united(rectAfter));
+			}
+
+			version (QT_OPENGL_SUPPORT)
+			{
+				if (usesOpenGL()) {
+					update;
+				} else
+					noGLUpdate;
+			}
+			else
+				noGLUpdate;
+		}
+	}
+
+	QPainterPath lensDeform(QPainterPath source, QPointF offset)
+	{
+		auto path = new QPainterPath;
+		path.addPath(source);
+
+		qreal flip = m_intensity / 100.0;
+
+		for (int i=0; i<path.elementCount; ++i)
+		{
+			auto e = path.elementAt(i);
+
+			qreal x = e.x + offset.x();
+			qreal y = e.y + offset.y();
+
+			qreal dx = x - m_pos.x();
+			qreal dy = y - m_pos.y();
+			qreal len = m_radius - sqrt(dx * dx + dy * dy);
+
+			if (len > 0) {
+				path.setElementPositionAt(i,
+					  x + flip * dx * len / m_radius,
+					  y + flip * dy * len / m_radius);
+			} else {
+				path.setElementPositionAt(i, x, y);
+			}
+		}
+
+		return path;
+	}
+
+	override void paint(QPainter painter)
+	{
+		int pad_x = 5;
+		int pad_y = 5;
+
+		int skip_x = qRound(m_pathBounds.width() + pad_x + m_fontSize/2);
+		int skip_y = qRound(m_pathBounds.height() + pad_y);
+
+		painter.setPen(Qt.NoPen);
+		painter.setBrush(new QColor(Qt.black));
+
+		auto clip = painter.clipPath().boundingRect();
+
+		int overlap = pad_x / 2;
+
+		for (int start_y=0; start_y < height(); start_y += skip_y)
+		{
+			if (start_y > clip.bottom())
+			break;
+
+			int start_x = -overlap;
+			for (; start_x < width(); start_x += skip_x)
+			{
+				if (start_y + skip_y >= clip.top() &&
+					start_x + skip_x >= clip.left() &&
+					start_x <= clip.right())
+				{
+					for (int i=0; i<m_paths.length; ++i) {
+						QPainterPath path = lensDeform(m_paths[i], QPointF(start_x, start_y));
+						painter.drawPath(path);
+					}
+				}
+			}
+			overlap = skip_x - (start_x - width());
+		}
+
+		if (preferImage) {
+			painter.drawImage(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), m_lens_image);
+		} else {
+			painter.drawPixmap(m_pos - QPointF(m_radius + LENS_EXTENT, m_radius + LENS_EXTENT), m_lens_pixmap);
+		}
+	}
+
+	void setRadius(int radius)
+	{
+		qreal max = max(m_radius, cast(qreal)radius);
+		m_radius = radius;
+		generateLensPixmap();
+		if (!m_animated || m_radius < max)
+		{
+			auto noGLUpdate = (){ update(circle_bounds(m_pos, max, m_fontSize)); };
+
+			version (QT_OPENGL_SUPPORT)
+			{
+				if (usesOpenGL())
+					update();
+				else
+					noGLUpdate();
+			}
+			else
+				noGLUpdate();
+		}
+	}
+
+	void setIntensity(int intensity)
+	{
+		m_intensity = intensity;
+		if (!m_animated)
+		{
+			auto noGLUpdate = (){ update(circle_bounds(m_pos, m_radius, m_fontSize)); };
+
+			version (QT_OPENGL_SUPPORT)
+			{
+				if (usesOpenGL()) {
+					update();
+				} else
+					noGLUpdate();
+			}
+			else
+				noGLUpdate();
+		}
+	}
+}
--- a/demos/shared/arthurstyle.d	Tue Sep 22 15:22:37 2009 +0000
+++ b/demos/shared/arthurstyle.d	Wed Dec 23 16:10:46 2009 +0200
@@ -1,450 +1,450 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the demonstration applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-module arthurstyle;
-
-
-import
-	qt.gui.QLayout,
-	qt.gui.QWindowsStyle,
-	qt.gui.QPainter,
-	qt.gui.QPainterPath,
-	qt.gui.QPixmapCache,
-	qt.gui.QRadioButton,
-	qt.gui.QPushButton,
-	qt.gui.QGroupBox,
-	qt.gui.QLinearGradient,
-	qt.gui.QStyleOption,
-	qt.gui.QStyleOptionFrameV2;
-
-
-class ArthurStyle : QWindowsStyle
-{
-    QPixmap cached(string img)
-    {
-        QPixmap pm = new QPixmap;
-        if (QPixmapCache.find(img, pm))
-            return pm;
-
-        pm = QPixmap.fromImage(new QImage(img), Qt.OrderedDither | Qt.OrderedAlphaDither);
-        if (pm.isNull)
-            return new QPixmap;
-
-        QPixmapCache.insert(img, pm);
-        return pm;
-    }
-
-    this()
-    {
-        //Q_INIT_RESOURCE(shared);
-    }
-    
-    void drawHoverRect(QPainter painter, QRect r)
-    {
-        qreal h = r.height();
-        qreal h2 = r.height() / 2.0;
-        QPainterPath path = new QPainterPath;
-        path.addRect(r.x() + h2, r.y() + 0, r.width() - h2 * 2, r.height());
-        path.addEllipse(r.x(), r.y(), h, h);
-        path.addEllipse(r.x() + r.width() - h, r.y(), h, h);
-        path.setFillRule(Qt.WindingFill);
-        painter.setPen(Qt.NoPen);
-        painter.setBrush(new QColor(191, 215, 191));
-        painter.setRenderHint(QPainter.Antialiasing);
-        painter.drawPath(path);
-    }
-
-    override void drawPrimitive(PrimitiveElement element, QStyleOption option, QPainter painter, QWidget widget)
-    {
-        assert(option);
-        switch (element)
-        {
-        case PE_FrameFocusRect:
-            break;
-
-        case PE_IndicatorRadioButton:
-            if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) {
-                bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver);
-                painter.save;
-                QPixmap radio;
-                if (hover)
-                    drawHoverRect(painter, widget.rect);
-
-                if (button.state & State_Sunken)
-                    radio = cached(":res/images/radiobutton-on.png");
-                else if (button.state & State_On)
-                    radio = cached(":res/images/radiobutton_on.png");
-                else
-                    radio = cached(":res/images/radiobutton_off.png");
-                painter.drawPixmap(button.rect.topLeft, radio);
-
-                painter.restore();
-            }
-            break;
-
-        case PE_PanelButtonCommand:
-            if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) {
-                bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver);
-
-                painter.save();
-                QPushButton pushButton = cast(QPushButton)(widget);
-                assert(pushButton);
-                auto parent = pushButton.parentWidget;
-                if (parent && cast(QGroupBox)(parent)) {
-                    auto lg = new QLinearGradient(0, 0, 0, parent.height);
-                    lg.setColorAt(0, new QColor(224,224,224));
-                    lg.setColorAt(1, new QColor(255,255,255));
-                    painter.setPen(Qt.NoPen);
-                    painter.setBrush(lg);
-                    painter.setBrushOrigin(QPoint() - widget.mapToParent(QPoint(0,0)));
-                    painter.drawRect(button.rect);
-                    painter.setBrushOrigin(0, 0);
-                }
-
-                bool down = (button.state & State_Sunken) || (button.state & State_On);
-
-                QPixmap left, right, mid;
-                if (down) {
-                    left = cached(":res/images/button_pressed_cap_left.png");
-                    right = cached(":res/images/button_pressed_cap_right.png");
-                    mid = cached(":res/images/button_pressed_stretch.png");
-                } else {
-                    left = cached(":res/images/button_normal_cap_left.png");
-                    right = cached(":res/images/button_normal_cap_right.png");
-                    mid = cached(":res/images/button_normal_stretch.png");
-                }
-                painter.drawPixmap(button.rect.topLeft, left);
-                painter.drawTiledPixmap(QRect(button.rect.x + left.width,
-                                               button.rect.y,
-                                               button.rect.width - left.width - right.width,
-                                               left.height),
-                                         mid);
-                painter.drawPixmap(button.rect.x + button.rect.width - right.width,
-                                    button.rect.y,
-                                    right);
-                if (hover)
-                    painter.fillRect(widget.rect.adjusted(3,5,-3,-5), new QColor(31,127,31,63));
-                painter.restore;
-            }
-            break;
-
-        case PE_FrameGroupBox:
-            if (QStyleOptionFrameV2 group = cast(QStyleOptionFrameV2)(option)) {
-                auto r = group.rect;
-
-                painter.save();
-                int radius = 14;
-                int radius2 = radius*2;
-                QPainterPath clipPath;
-                clipPath.moveTo(radius, 0);
-                clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90);
-                clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90);
-                clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90);
-                clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90);
-                painter.setClipPath(clipPath);
-                QPixmap titleStretch = cached(":res/images/title_stretch.png");
-                QPixmap topLeft = cached(":res/images/groupframe_topleft.png");
-                QPixmap topRight = cached(":res/images/groupframe_topright.png");
-                QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png");
-                QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png");
-                QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png");
-                QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png");
-                QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png");
-                QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png");
-                auto lg = new QLinearGradient(0, 0, 0, r.height());
-                lg.setColorAt(0, new QColor(224,224,224));
-                lg.setColorAt(1, new QColor(255,255,255));
-                painter.setPen(Qt.NoPen);
-                painter.setBrush(lg);
-                painter.drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0));
-                painter.setClipping(false);
-
-                int topFrameOffset = titleStretch.height()/2 - 2;
-                painter.drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft);
-                painter.drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0) + QPoint(0, topFrameOffset), topRight);
-                painter.drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft);
-                painter.drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1, bottomRight.height()-1), bottomRight);
-
-                QRect left = r;
-                left.setY(r.y() + topLeft.height() + topFrameOffset);
-                left.setWidth(leftStretch.width());
-                left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset);
-                painter.drawTiledPixmap(left, leftStretch);
-
-                QRect top = r;
-                top.setX(r.x() + topLeft.width());
-                top.setY(r.y() + topFrameOffset);
-                top.setWidth(r.width() - topLeft.width() - topRight.width());
-                top.setHeight(topLeft.height());
-                painter.drawTiledPixmap(top, topStretch);
-
-                QRect right = r;
-                right.setX(r.right() - rightStretch.width()+1);
-                right.setY(r.y() + topRight.height() + topFrameOffset);
-                right.setWidth(rightStretch.width());
-                right.setHeight(r.height() - topRight.height() - bottomRight.height() - topFrameOffset);
-                painter.drawTiledPixmap(right, rightStretch);
-
-                QRect bottom = r;
-                bottom.setX(r.x() + bottomLeft.width());
-                bottom.setY(r.bottom() - bottomStretch.height()+1);
-                bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width());
-                bottom.setHeight(bottomLeft.height());
-                painter.drawTiledPixmap(bottom, bottomStretch);
-                painter.restore();
-            }
-            break;
-
-        default:
-            QWindowsStyle.drawPrimitive(element, option, painter, widget);
-            break;
-        }
-        return;
-    }
-
-    override void drawComplexControl(ComplexControl control, QStyleOptionComplex option,
-                                         QPainter painter, QWidget widget)
-    {
-        switch (control) {
-        case CC_Slider:
-            if (QStyleOptionSlider slider = cast(QStyleOptionSlider)(option)) {
-                QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
-                QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);
-
-                painter.save;
-
-                bool hover = (slider.state & State_Enabled) && (slider.state & State_MouseOver);
-                if (hover) {
-                    QRect moderated = widget.rect().adjusted(0, 4, 0, -4);
-                    drawHoverRect(painter, moderated);
-                }
-
-                if ((option.subControls & SC_SliderGroove) && groove.isValid()) {
-                    QPixmap grv = cached(":res/images/slider_bar.png");
-                    painter.drawPixmap(QRect(groove.x() + 5, groove.y(),
-                                              groove.width() - 10, grv.height()),
-                                        grv);
-                }
-                if ((option.subControls & SC_SliderHandle) && handle.isValid()) {
-                    QPixmap hndl = cached(":res/images/slider_thumb_on.png");
-                    painter.drawPixmap(handle.topLeft(), hndl);
-                }
-
-                painter.restore();
-            }
-            break;
-        case CC_GroupBox:
-            if (QStyleOptionGroupBox groupBox
-                    = cast(QStyleOptionGroupBox)(option)) {
-                auto groupBoxCopy = new QStyleOptionGroupBox(groupBox);
-                groupBoxCopy.setSubControls = groupBoxCopy.subControls & ~SC_GroupBoxLabel;
-                QWindowsStyle.drawComplexControl(control, groupBoxCopy, painter, widget);
-
-                if (groupBox.subControls & SC_GroupBoxLabel) {
-                    QRect r = groupBox.rect;
-                    QPixmap titleLeft = cached(":res/images/title_cap_left.png");
-                    QPixmap titleRight = cached(":res/images/title_cap_right.png");
-                    QPixmap titleStretch = cached(":res/images/title_stretch.png");
-                    int txt_width = groupBox.fontMetrics.width(groupBox.text) + 20;
-                    painter.drawPixmap(r.center().x() - txt_width/2, 0, titleLeft);
-                    QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget);
-                    painter.drawTiledPixmap(tileRect, titleStretch);
-                    painter.drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight);
-                    int opacity = 31;
-                    painter.setPen(new QColor(0, 0, 0, opacity));
-                    painter.drawText(tileRect.translated(0, 1),
-                                      cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
-                    painter.drawText(tileRect.translated(2, 1),
-                                      cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
-                    painter.setPen(new QColor(0, 0, 0, opacity * 2));
-                    painter.drawText(tileRect.translated(1, 1),
-                                      cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
-                    painter.setPen(new QColor(Qt.white));
-                    painter.drawText(tileRect, cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
-                }
-            }
-            break;
-        default:
-            QWindowsStyle.drawComplexControl(control, option, painter, widget);
-            break;
-        }
-        return;
-    }
-
-    override QRect subControlRect(QStyle_ComplexControl control, QStyleOptionComplex option,
-                                      int sc, QWidget widget = null)
-    {
-        QRect rect;
-
-        auto subControl = cast(SubControl)sc;
-
-        switch (control) {
-        default:
-            rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
-            break;
-        case CC_GroupBox:
-            if (QStyleOptionGroupBox group
-                    = cast(QStyleOptionGroupBox)(option)) {
-                switch (subControl) {
-                default:
-                    rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
-                    break;
-                case SC_GroupBoxContents:
-                    rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
-                    rect.adjust(0, -8, 0, 0);
-                    break;
-                case SC_GroupBoxFrame:
-                    rect = group.rect;
-                    break;
-                case SC_GroupBoxLabel:
-                    QPixmap titleLeft = cached(":res/images/title_cap_left.png");
-                    QPixmap titleRight = cached(":res/images/title_cap_right.png");
-                    QPixmap titleStretch = cached(":res/images/title_stretch.png");
-                    int txt_width = group.fontMetrics.width(group.text) + 20;
-                    rect = QRect(group.rect.center().x() - txt_width/2 + titleLeft.width(), 0,
-                                 txt_width - titleLeft.width() - titleRight.width(),
-                                 titleStretch.height());
-                    break;
-                }
-            }
-            break;
-        }
-
-        if (control == CC_Slider && subControl == SC_SliderHandle) {
-            rect.setWidth(13);
-            rect.setHeight(27);
-        } else if (control == CC_Slider && subControl == SC_SliderGroove) {
-            rect.setHeight(9);
-            rect.moveTop(27/2 - 9/2);
-        }
-        return rect;
-    }
-
-    override QSize sizeFromContents(ContentsType type, QStyleOption option,
-                                        QSize size, QWidget widget)
-    {
-        QSize newSize = QWindowsStyle.sizeFromContents(type, option, size, widget);
-
-        switch (type) {
-        case CT_RadioButton:
-            newSize += QSize(20, 0);
-            break;
-
-        case CT_PushButton:
-            newSize.setHeight(26);
-            break;
-
-        case CT_Slider:
-            newSize.setHeight(27);
-            break;
-
-        default:
-            break;
-        }
-
-        return newSize;
-    }
-
-    override int pixelMetric(PixelMetric pm, QStyleOption opt, QWidget widget)
-    {
-        if (pm == PM_SliderLength)
-            return 13;
-        return QWindowsStyle.pixelMetric(pm, opt, widget);
-    }
-
-    override void polish(QWidget widget)
-    {
-        if (widget.layout() && cast(QGroupBox)(widget)) {
-            if (widget.findChildren!(QGroupBox).length == 0) {
-                widget.layout().setWidgetSpacing(0); // Why setSpacing was renamed to setWidgetSpacing?
-                widget.layout().setMargin(12);
-            } else {
-                widget.layout().setMargin(13);
-            }
-        }
-
-        if (cast(QPushButton)(widget)
-            || cast(QRadioButton)(widget)
-            || cast(QSlider)(widget)) {
-            widget.setAttribute(Qt.WA_Hover);
-        }
-
-        QPalette pal = widget.palette();
-        if (widget.isWindow()) {
-            pal.setColor(QPalette.Window, new QColor(241, 241, 241));
-            widget.setPalette(pal);
-        }
-    }
-
-    override void unpolish(QWidget widget)
-    {
-        if (cast(QPushButton)(widget)
-            || cast(QRadioButton)(widget)
-            || cast(QSlider)(widget)) {
-            widget.setAttribute(Qt.WA_Hover, false);
-        }
-    }
-
-    override void polish(QPalette palette)
-    {
-        palette.setColor(QPalette.Window, new QColor(241, 241, 241));
-    }
-
-    override QRect subElementRect(SubElement element, QStyleOption option, QWidget widget)
-    {
-        QRect r;
-        switch(element) {
-        case SE_RadioButtonClickRect:
-            r = widget.rect();
-            break;
-        case SE_RadioButtonContents:
-            r = widget.rect().adjusted(20, 0, 0, 0);
-            break;
-        default:
-            r = QWindowsStyle.subElementRect(element, option, widget);
-            break;
-        }
-
-        if (cast(QRadioButton)(widget))
-            r = r.adjusted(5, 0, -5, 0);
-
-        return r;
-    }
-}
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+module arthurstyle;
+
+
+import
+	qt.gui.QLayout,
+	qt.gui.QWindowsStyle,
+	qt.gui.QPainter,
+	qt.gui.QPainterPath,
+	qt.gui.QPixmapCache,
+	qt.gui.QRadioButton,
+	qt.gui.QPushButton,
+	qt.gui.QGroupBox,
+	qt.gui.QLinearGradient,
+	qt.gui.QStyleOption,
+	qt.gui.QStyleOptionFrameV2;
+
+
+class ArthurStyle : QWindowsStyle
+{
+    QPixmap cached(string img)
+    {
+        QPixmap pm = new QPixmap;
+        if (QPixmapCache.find(img, pm))
+            return pm;
+
+        pm = QPixmap.fromImage(new QImage(img), Qt.OrderedDither | Qt.OrderedAlphaDither);
+        if (pm.isNull)
+            return new QPixmap;
+
+        QPixmapCache.insert(img, pm);
+        return pm;
+    }
+
+    this()
+    {
+        //Q_INIT_RESOURCE(shared);
+    }
+    
+    void drawHoverRect(QPainter painter, QRect r)
+    {
+        qreal h = r.height();
+        qreal h2 = r.height() / 2.0;
+        QPainterPath path = new QPainterPath;
+        path.addRect(r.x() + h2, r.y() + 0, r.width() - h2 * 2, r.height());
+        path.addEllipse(r.x(), r.y(), h, h);
+        path.addEllipse(r.x() + r.width() - h, r.y(), h, h);
+        path.setFillRule(Qt.WindingFill);
+        painter.setPen(Qt.NoPen);
+        painter.setBrush(new QColor(191, 215, 191));
+        painter.setRenderHint(QPainter.Antialiasing);
+        painter.drawPath(path);
+    }
+
+    override void drawPrimitive(PrimitiveElement element, QStyleOption option, QPainter painter, QWidget widget)
+    {
+        assert(option);
+        switch (element)
+        {
+        case PE_FrameFocusRect:
+            break;
+
+        case PE_IndicatorRadioButton:
+            if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) {
+                bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver);
+                painter.save;
+                QPixmap radio;
+                if (hover)
+                    drawHoverRect(painter, widget.rect);
+
+                if (button.state & State_Sunken)
+                    radio = cached(":res/images/radiobutton-on.png");
+                else if (button.state & State_On)
+                    radio = cached(":res/images/radiobutton_on.png");
+                else
+                    radio = cached(":res/images/radiobutton_off.png");
+                painter.drawPixmap(button.rect.topLeft, radio);
+
+                painter.restore();
+            }
+            break;
+
+        case PE_PanelButtonCommand:
+            if (QStyleOptionButton button = cast(QStyleOptionButton)(option)) {
+                bool hover = (button.state & State_Enabled) && (button.state & State_MouseOver);
+
+                painter.save();
+                QPushButton pushButton = cast(QPushButton)(widget);
+                assert(pushButton);
+                auto parent = pushButton.parentWidget;
+                if (parent && cast(QGroupBox)(parent)) {
+                    auto lg = new QLinearGradient(0, 0, 0, parent.height);
+                    lg.setColorAt(0, new QColor(224,224,224));
+                    lg.setColorAt(1, new QColor(255,255,255));
+                    painter.setPen(Qt.NoPen);
+                    painter.setBrush(lg);
+                    painter.setBrushOrigin(QPoint() - widget.mapToParent(QPoint(0,0)));
+                    painter.drawRect(button.rect);
+                    painter.setBrushOrigin(0, 0);
+                }
+
+                bool down = (button.state & State_Sunken) || (button.state & State_On);
+
+                QPixmap left, right, mid;
+                if (down) {
+                    left = cached(":res/images/button_pressed_cap_left.png");
+                    right = cached(":res/images/button_pressed_cap_right.png");
+                    mid = cached(":res/images/button_pressed_stretch.png");
+                } else {
+                    left = cached(":res/images/button_normal_cap_left.png");
+                    right = cached(":res/images/button_normal_cap_right.png");
+                    mid = cached(":res/images/button_normal_stretch.png");
+                }
+                painter.drawPixmap(button.rect.topLeft, left);
+                painter.drawTiledPixmap(QRect(button.rect.x + left.width,
+                                               button.rect.y,
+                                               button.rect.width - left.width - right.width,
+                                               left.height),
+                                         mid);
+                painter.drawPixmap(button.rect.x + button.rect.width - right.width,
+                                    button.rect.y,
+                                    right);
+                if (hover)
+                    painter.fillRect(widget.rect.adjusted(3,5,-3,-5), new QColor(31,127,31,63));
+                painter.restore;
+            }
+            break;
+
+        case PE_FrameGroupBox:
+            if (QStyleOptionFrameV2 group = cast(QStyleOptionFrameV2)(option)) {
+                auto r = group.rect;
+
+                painter.save();
+                int radius = 14;
+                int radius2 = radius*2;
+                QPainterPath clipPath;
+                clipPath.moveTo(radius, 0);
+                clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90);
+                clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90);
+                clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90);
+                clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90);
+                painter.setClipPath(clipPath);
+                QPixmap titleStretch = cached(":res/images/title_stretch.png");
+                QPixmap topLeft = cached(":res/images/groupframe_topleft.png");
+                QPixmap topRight = cached(":res/images/groupframe_topright.png");
+                QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png");
+                QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png");
+                QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png");
+                QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png");
+                QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png");
+                QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png");
+                auto lg = new QLinearGradient(0, 0, 0, r.height());
+                lg.setColorAt(0, new QColor(224,224,224));
+                lg.setColorAt(1, new QColor(255,255,255));
+                painter.setPen(Qt.NoPen);
+                painter.setBrush(lg);
+                painter.drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0));
+                painter.setClipping(false);
+
+                int topFrameOffset = titleStretch.height()/2 - 2;
+                painter.drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft);
+                painter.drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0) + QPoint(0, topFrameOffset), topRight);
+                painter.drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft);
+                painter.drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1, bottomRight.height()-1), bottomRight);
+
+                QRect left = r;
+                left.setY(r.y() + topLeft.height() + topFrameOffset);
+                left.setWidth(leftStretch.width());
+                left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset);
+                painter.drawTiledPixmap(left, leftStretch);
+
+                QRect top = r;
+                top.setX(r.x() + topLeft.width());
+                top.setY(r.y() + topFrameOffset);
+                top.setWidth(r.width() - topLeft.width() - topRight.width());
+                top.setHeight(topLeft.height());
+                painter.drawTiledPixmap(top, topStretch);
+
+                QRect right = r;
+                right.setX(r.right() - rightStretch.width()+1);
+                right.setY(r.y() + topRight.height() + topFrameOffset);
+                right.setWidth(rightStretch.width());
+                right.setHeight(r.height() - topRight.height() - bottomRight.height() - topFrameOffset);
+                painter.drawTiledPixmap(right, rightStretch);
+
+                QRect bottom = r;
+                bottom.setX(r.x() + bottomLeft.width());
+                bottom.setY(r.bottom() - bottomStretch.height()+1);
+                bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width());
+                bottom.setHeight(bottomLeft.height());
+                painter.drawTiledPixmap(bottom, bottomStretch);
+                painter.restore();
+            }
+            break;
+
+        default:
+            QWindowsStyle.drawPrimitive(element, option, painter, widget);
+            break;
+        }
+        return;
+    }
+
+    override void drawComplexControl(ComplexControl control, QStyleOptionComplex option,
+                                         QPainter painter, QWidget widget)
+    {
+        switch (control) {
+        case CC_Slider:
+            if (QStyleOptionSlider slider = cast(QStyleOptionSlider)(option)) {
+                QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
+                QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);
+
+                painter.save;
+
+                bool hover = (slider.state & State_Enabled) && (slider.state & State_MouseOver);
+                if (hover) {
+                    QRect moderated = widget.rect().adjusted(0, 4, 0, -4);
+                    drawHoverRect(painter, moderated);
+                }
+
+                if ((option.subControls & SC_SliderGroove) && groove.isValid()) {
+                    QPixmap grv = cached(":res/images/slider_bar.png");
+                    painter.drawPixmap(QRect(groove.x() + 5, groove.y(),
+                                              groove.width() - 10, grv.height()),
+                                        grv);
+                }
+                if ((option.subControls & SC_SliderHandle) && handle.isValid()) {
+                    QPixmap hndl = cached(":res/images/slider_thumb_on.png");
+                    painter.drawPixmap(handle.topLeft(), hndl);
+                }
+
+                painter.restore();
+            }
+            break;
+        case CC_GroupBox:
+            if (QStyleOptionGroupBox groupBox
+                    = cast(QStyleOptionGroupBox)(option)) {
+                auto groupBoxCopy = new QStyleOptionGroupBox(groupBox);
+                groupBoxCopy.setSubControls = groupBoxCopy.subControls & ~SC_GroupBoxLabel;
+                QWindowsStyle.drawComplexControl(control, groupBoxCopy, painter, widget);
+
+                if (groupBox.subControls & SC_GroupBoxLabel) {
+                    QRect r = groupBox.rect;
+                    QPixmap titleLeft = cached(":res/images/title_cap_left.png");
+                    QPixmap titleRight = cached(":res/images/title_cap_right.png");
+                    QPixmap titleStretch = cached(":res/images/title_stretch.png");
+                    int txt_width = groupBox.fontMetrics.width(groupBox.text) + 20;
+                    painter.drawPixmap(r.center().x() - txt_width/2, 0, titleLeft);
+                    QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget);
+                    painter.drawTiledPixmap(tileRect, titleStretch);
+                    painter.drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight);
+                    int opacity = 31;
+                    painter.setPen(new QColor(0, 0, 0, opacity));
+                    painter.drawText(tileRect.translated(0, 1),
+                                      cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
+                    painter.drawText(tileRect.translated(2, 1),
+                                      cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
+                    painter.setPen(new QColor(0, 0, 0, opacity * 2));
+                    painter.drawText(tileRect.translated(1, 1),
+                                      cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
+                    painter.setPen(new QColor(Qt.white));
+                    painter.drawText(tileRect, cast(int)(Qt.AlignVCenter | Qt.AlignHCenter), groupBox.text, null);
+                }
+            }
+            break;
+        default:
+            QWindowsStyle.drawComplexControl(control, option, painter, widget);
+            break;
+        }
+        return;
+    }
+
+    override QRect subControlRect(QStyle_ComplexControl control, QStyleOptionComplex option,
+                                      int sc, QWidget widget = null)
+    {
+        QRect rect;
+
+        auto subControl = cast(SubControl)sc;
+
+        switch (control) {
+        default:
+            rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
+            break;
+        case CC_GroupBox:
+            if (QStyleOptionGroupBox group
+                    = cast(QStyleOptionGroupBox)(option)) {
+                switch (subControl) {
+                default:
+                    rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
+                    break;
+                case SC_GroupBoxContents:
+                    rect = QWindowsStyle.subControlRect(control, option, subControl, widget);
+                    rect.adjust(0, -8, 0, 0);
+                    break;
+                case SC_GroupBoxFrame:
+                    rect = group.rect;
+                    break;
+                case SC_GroupBoxLabel:
+                    QPixmap titleLeft = cached(":res/images/title_cap_left.png");
+                    QPixmap titleRight = cached(":res/images/title_cap_right.png");
+                    QPixmap titleStretch = cached(":res/images/title_stretch.png");
+                    int txt_width = group.fontMetrics.width(group.text) + 20;
+                    rect = QRect(group.rect.center().x() - txt_width/2 + titleLeft.width(), 0,
+                                 txt_width - titleLeft.width() - titleRight.width(),
+                                 titleStretch.height());
+                    break;
+                }
+            }
+            break;
+        }
+
+        if (control == CC_Slider && subControl == SC_SliderHandle) {
+            rect.setWidth(13);
+            rect.setHeight(27);
+        } else if (control == CC_Slider && subControl == SC_SliderGroove) {
+            rect.setHeight(9);
+            rect.moveTop(27/2 - 9/2);
+        }
+        return rect;
+    }
+
+    override QSize sizeFromContents(ContentsType type, QStyleOption option,
+                                        QSize size, QWidget widget)
+    {
+        QSize newSize = QWindowsStyle.sizeFromContents(type, option, size, widget);
+
+        switch (type) {
+        case CT_RadioButton:
+            newSize += QSize(20, 0);
+            break;
+
+        case CT_PushButton:
+            newSize.setHeight(26);
+            break;
+
+        case CT_Slider:
+            newSize.setHeight(27);
+            break;
+
+        default:
+            break;
+        }
+
+        return newSize;
+    }
+
+    override int pixelMetric(PixelMetric pm, QStyleOption opt, QWidget widget)
+    {
+        if (pm == PM_SliderLength)
+            return 13;
+        return QWindowsStyle.pixelMetric(pm, opt, widget);
+    }
+
+    override void polish(QWidget widget)
+    {
+        if (widget.layout() && cast(QGroupBox)(widget)) {
+            if (widget.findChildren!(QGroupBox).length == 0) {
+                widget.layout().setWidgetSpacing(0); // Why setSpacing was renamed to setWidgetSpacing?
+                widget.layout().setMargin(12);
+            } else {
+                widget.layout().setMargin(13);
+            }
+        }
+
+        if (cast(QPushButton)(widget)
+            || cast(QRadioButton)(widget)
+            || cast(QSlider)(widget)) {
+            widget.setAttribute(Qt.WA_Hover);
+        }
+
+        QPalette pal = widget.palette();
+        if (widget.isWindow()) {
+            pal.setColor(QPalette.Window, new QColor(241, 241, 241));
+            widget.setPalette(pal);
+        }
+    }
+
+    override void unpolish(QWidget widget)
+    {
+        if (cast(QPushButton)(widget)
+            || cast(QRadioButton)(widget)
+            || cast(QSlider)(widget)) {
+            widget.setAttribute(Qt.WA_Hover, false);
+        }
+    }
+
+    override void polish(QPalette palette)
+    {
+        palette.setColor(QPalette.Window, new QColor(241, 241, 241));
+    }
+
+    override QRect subElementRect(SubElement element, QStyleOption option, QWidget widget)
+    {
+        QRect r;
+        switch(element) {
+        case SE_RadioButtonClickRect:
+            r = widget.rect();
+            break;
+        case SE_RadioButtonContents:
+            r = widget.rect().adjusted(20, 0, 0, 0);
+            break;
+        default:
+            r = QWindowsStyle.subElementRect(element, option, widget);
+            break;
+        }
+
+        if (cast(QRadioButton)(widget))
+            r = r.adjusted(5, 0, -5, 0);
+
+        return r;
+    }
+}
--- a/demos/shared/arthurwidgets.d	Tue Sep 22 15:22:37 2009 +0000
+++ b/demos/shared/arthurwidgets.d	Wed Dec 23 16:10:46 2009 +0200
@@ -1,414 +1,414 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the demonstration applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-module arthurwidgets;
-
-
-import qt.core.QFile,
-    qt.gui.QApplication,
-    qt.gui.QPainter,
-    qt.gui.QPainterPath,
-    qt.gui.QPixmapCache,
-    qt.gui.QTextDocument,
-    qt.gui.QAbstractTextDocumentLayout,
-    qt.gui.QLinearGradient,
-    qt.gui.QTextBrowser,
-    qt.gui.QBoxLayout,
-    qt.opengl.QGL,
-    qt.Signal,
-    tango.text.Util;
-
-import tango.text.Regex : Regex;
-
-//#include <private/qpixmapdata_p.h>
-
-//extern QPixmap cached(const QString &img);
-
-version (QT_OPENGL_SUPPORT)
-{
-    import qt.opengl.QGLWidget;
-    class GLWidget : QGLWidget
-    {
-        this(QWidget parent)
-        {
-            super(new QGLFormat(QGL.SampleBuffers), parent);
-        }
-
-        void disableAutoBufferSwap() { setAutoBufferSwap(false); }
-        override void paintEvent(QPaintEvent) { parentWidget().update(); }
-    }
-}
-
-class ArthurFrame : QWidget
-{
-protected:
-
-    version(QT_OPENGL_SUPPORT)
-    {
-        GLWidget glw;
-        bool m_use_opengl;
-    }
-
-    QPixmap m_tile;
-
-    bool m_show_doc;
-    bool m_prefer_image;
-    QTextDocument m_document;
-
-    string m_sourceFileName;
-
-public:
-    mixin Signal!("descriptionEnabledChanged", bool);
-
-    bool preferImage() { return m_prefer_image; }
-
-    void paint(QPainter) {}
-
-    this(QWidget parent)
-    {
-        super(parent);
-
-        version (QT_OPENGL_SUPPORT)
-        {
-            QGLFormat f = QGLFormat.defaultFormat();
-            f.setSampleBuffers(true);
-            f.setStencil(true);
-            f.setAlpha(true);
-            f.setAlphaBufferSize(8);
-            QGLFormat.setDefaultFormat(f);
-        }
-
-        m_tile = new QPixmap(128, 128);
-        m_tile.fill(new QColor(Qt.white));
-        scope pt = new QPainter(m_tile);
-        auto color = new QColor(230, 230, 230);
-        pt.fillRect(0, 0, 64, 64, color);
-        pt.fillRect(64, 64, 64, 64, color);
-        pt.end();
-
-    //     QPalette pal = palette();
-    //     pal.setBrush(backgroundRole(), m_tile);
-    //     setPalette(pal);
-
-        version (Q_WS_X11)
-        {
-            auto xRenderPixmap = new QPixmap(1, 1);
-            m_prefer_image = xRenderPixmap.pixmapData().classId() == QPixmapData.X11Class && !xRenderPixmap.x11PictureHandle();
-        }
-    }
-
-    version (QT_OPENGL_SUPPORT)
-    {
-        void enableOpenGL(bool use_opengl)
-        {
-            m_use_opengl = use_opengl;
-
-            if (!glw) {
-                glw = new GLWidget(this);
-                glw.setAutoFillBackground(false);
-                glw.disableAutoBufferSwap();
-                QApplication.postEvent(this, new QResizeEvent(size(), size()));
-            }
-
-            if (use_opengl) {
-                glw.show();
-            } else {
-                glw.hide();
-            }
-
-            update();
-        }
-
-        bool usesOpenGL() { return m_use_opengl; }
-        QGLWidget glWidget(){ return glw; }
-    }
-
-    override void paintEvent(QPaintEvent e)
-    {
-        version (Q_WS_QWS)
-            static QPixmap static_image;
-        else
-            static QImage static_image;
-
-        auto painter = new QPainter;
-
-        version (QT_OPENGL_SUPPORT)
-            auto prefImage = preferImage && !m_use_opengl;
-        else
-            auto prefImage = preferImage;
-
-        if (prefImage) {
-            if (!static_image || static_image.size() != size()) {
-                delete static_image;
-                version (Q_WS_QWS)
-                    static_image = new QPixmap(size());
-                else
-                    static_image = new QImage(size(), QImage.Format_RGB32);
-            }
-            painter.begin(static_image);
-
-            int o = 10;
-
-            QBrush bg = palette().brush(QPalette.Window);
-            painter.fillRect(0, 0, o, o, bg);
-            painter.fillRect(width() - o, 0, o, o, bg);
-            painter.fillRect(0, height() - o, o, o, bg);
-            painter.fillRect(width() - o, height() - o, o, o, bg);
-        } else {
-            version (QT_OPENGL_SUPPORT)
-            {
-                if (m_use_opengl) {
-                    painter.begin(glw);
-                    painter.fillRect(new QRectF(0, 0, glw.width(), glw.height()), palette().color(backgroundRole()));
-                } else {
-                    painter.begin(this);
-                }
-            }
-            else
-                painter.begin(this);
-        }
-
-        painter.setClipRect(e.rect());
-
-        painter.setRenderHint(QPainter.Antialiasing);
-
-        auto clipPath = new QPainterPath;
-
-        QRect r = rect();
-        qreal left = r.x() + 1;
-        qreal top = r.y() + 1;
-        qreal right = r.right();
-        qreal bottom = r.bottom();
-        qreal radius2 = 8 * 2;
-
-        clipPath.moveTo(right - radius2, top);
-        clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90);
-        clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90);
-        clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90);
-        clipPath.arcTo(left, top, radius2, radius2, 180, -90);
-        clipPath.closeSubpath();
-
-        painter.save();
-        painter.setClipPath(clipPath, Qt.IntersectClip);
-
-        painter.drawTiledPixmap(rect(), m_tile);
-
-        // client painting
-
-        paint(painter);
-        painter.restore();
-
-        painter.save();
-        if (m_show_doc)
-            paintDescription(painter);
-        painter.restore();
-
-        int level = 180;
-        painter.setPen(new QPen(new QBrush(new QColor(level, level, level)), 2));
-        painter.setBrush(Qt.NoBrush);
-        painter.drawPath(clipPath);
-
-        if (prefImage) {
-            painter.end();
-            painter.begin(this);
-            version (Q_WS_QWS)
-                painter.drawPixmap(e.rect(), static_image, e.rect());
-            else
-                painter.drawImage(e.rect(), static_image, e.rect());
-        }
-
-        // TODO: this sucks
-        version (QT_OPENGL_SUPPORT) {
-            if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc))
-                glw.swapBuffers();
-        }
-    }
-
-    void resizeEvent(QResizeEvent e)
-    {
-        version (QT_OPENGL_SUPPORT)
-        {
-            if (glw)
-                glw.setGeometry(0, 0, e.size().width()-1, e.size().height()-1);
-        }
-        super.resizeEvent(e);
-    }
-
-    void setDescriptionEnabled(bool enabled)
-    {
-        if (m_show_doc != enabled) {
-            m_show_doc = enabled;
-            descriptionEnabledChanged.emit(m_show_doc);
-            update();
-        }
-    }
-
-    void loadDescription(string fileName)
-    {
-        auto textFile = new QFile(fileName);
-        string text;
-        if (!textFile.open(QFile.ReadOnly))
-            text = "Unable to load resource file: " ~ fileName;
-        else
-            text = textFile.readAll().toString; // TODO: excessive copying
-        setDescription(text);
-    }
-
-    void setDescription(string text)
-    {
-        m_document = new QTextDocument(this);
-        m_document.setHtml(text);
-    }
-
-    void paintDescription(QPainter painter)
-    {
-        if (!m_document)
-            return;
-
-        int pageWidth = qMax(width() - 100, 100);
-        int pageHeight = qMax(height() - 100, 100);
-        if (pageWidth != m_document.pageSize().width()) {
-            m_document.setPageSize(QSizeF(pageWidth, pageHeight));
-        }
-
-        auto textRect = new QRect(width() / 2 - pageWidth / 2,
-                       height() / 2 - pageHeight / 2,
-                       pageWidth,
-                       pageHeight);
-        int pad = 10;
-        QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad);
-        painter.setPen(Qt.NoPen);
-        painter.setBrush(new QColor(0, 0, 0, 63));
-        int shade = 10;
-        painter.drawRect(clearRect.x() + clearRect.width() + 1,
-                          clearRect.y() + shade,
-                          shade,
-                          clearRect.height() + 1);
-        painter.drawRect(clearRect.x() + shade,
-                          clearRect.y() + clearRect.height() + 1,
-                          clearRect.width() - shade + 1,
-                          shade);
-
-        painter.setRenderHint(QPainter.Antialiasing, false);
-        painter.setBrush(new QColor(255, 255, 255, 220));
-        painter.setPen(new QColor(Qt.black));
-        painter.drawRect(clearRect);
-
-        painter.setClipRect(textRect, Qt.IntersectClip);
-        painter.translate(textRect.topLeft());
-
-        auto ctx = new QAbstractTextDocumentLayout_PaintContext;
-
-        auto g = new QLinearGradient(0, 0, 0, textRect.height());
-        g.setColorAt(0, new QColor(Qt.black));
-        g.setColorAt(0.9, new QColor(Qt.black));
-        g.setColorAt(1, new QColor(Qt.transparent));
-
-        QPalette pal = palette();
-        pal.setBrush(QPalette.Text, new QBrush(g));
-
-        ctx.setPalette(pal);
-        ctx.setClip(new QRectF(0, 0, textRect.width(), textRect.height()));
-        m_document.documentLayout().draw(painter, ctx);
-    }
-
-    void loadSourceFile(string sourceName)
-    {
-        m_sourceFileName = sourceName;
-    }
-
-    void showSource()
-    {
-        // Check for existing source
-        if (findChild!(QTextBrowser))
-            return;
-
-        string contents;
-        if (!m_sourceFileName.length) {
-            contents = "No source for widget: " ~ objectName();
-        } else {
-            auto f = new QFile(m_sourceFileName);
-            if (!f.open(QFile.ReadOnly))
-                contents = "Could not open file: " ~ m_sourceFileName;
-            else
-                contents = f.readAll.toString;
-        }
-
-        contents = contents.substitute("&", "&amp;");
-        contents = contents.substitute("<", "&lt;");
-        contents = contents.substitute(">", "&gt;");
-
-        static const string[] keywords =
-            ["for ", "if ", "switch ", " int ", "#include ", "const"
-                , "void ", "uint ", "case ", "double ", "#define ", "static"
-                , "new", "this"];
-
-        foreach (keyword; keywords)
-            contents = contents.substitute(keyword, "<font color=olive>" ~ keyword ~ "</font>");
-        contents = contents.substitute("(int ", "(<font color=olive><b>int </b></font>");
-
-        static const string[] ppKeywords =
-            ["#ifdef", "#ifndef", "#if", "#endif", "#else"];
-
-        foreach (keyword; ppKeywords)
-            contents = contents.substitute(keyword, "<font color=navy>" ~ keyword ~ "</font>");
-
-        auto ddRe = new Regex("(\\d\\d?)");
-        contents = ddRe.replaceAll(contents, "<font color=navy>\\1</font>");
-
-        auto commentRe = new Regex("(//.+?)\\n");
-        contents = commentRe.replaceAll(contents, "<font color=red>\\1</font>\n");
-
-        auto stringLiteralRe = new Regex("(\".+?\")");
-        contents = stringLiteralRe.replaceAll(contents, "<font color=green>\\1</font>");
-
-        auto html = contents.dup;
-        html = "<html><pre>" ~ html ~ "</pre></html>";
-
-        QTextBrowser sourceViewer = new QTextBrowser(null);
-        sourceViewer.setWindowTitle("Source: " ~ m_sourceFileName[5..$]);
-        sourceViewer.setParent(this, Qt.Dialog);
-        sourceViewer.setAttribute(Qt.WA_DeleteOnClose);
-        sourceViewer.setLineWrapMode(QTextEdit.NoWrap);
-        sourceViewer.setHtml(html);
-        sourceViewer.resize(600, 600);
-        sourceViewer.show();
-    }
-}
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+module arthurwidgets;
+
+
+import qt.core.QFile,
+    qt.gui.QApplication,
+    qt.gui.QPainter,
+    qt.gui.QPainterPath,
+    qt.gui.QPixmapCache,
+    qt.gui.QTextDocument,
+    qt.gui.QAbstractTextDocumentLayout,
+    qt.gui.QLinearGradient,
+    qt.gui.QTextBrowser,
+    qt.gui.QBoxLayout,
+    qt.opengl.QGL,
+    qt.Signal,
+    tango.text.Util;
+
+import tango.text.Regex : Regex;
+
+//#include <private/qpixmapdata_p.h>
+
+//extern QPixmap cached(const QString &img);
+
+version (QT_OPENGL_SUPPORT)
+{
+    import qt.opengl.QGLWidget;
+    class GLWidget : QGLWidget
+    {
+        this(QWidget parent)
+        {
+            super(new QGLFormat(QGL.SampleBuffers), parent);
+        }
+
+        void disableAutoBufferSwap() { setAutoBufferSwap(false); }
+        override void paintEvent(QPaintEvent) { parentWidget().update(); }
+    }
+}
+
+class ArthurFrame : QWidget
+{
+protected:
+
+    version(QT_OPENGL_SUPPORT)
+    {
+        GLWidget glw;
+        bool m_use_opengl;
+    }
+
+    QPixmap m_tile;
+
+    bool m_show_doc;
+    bool m_prefer_image;
+    QTextDocument m_document;
+
+    string m_sourceFileName;
+
+public:
+    mixin Signal!("descriptionEnabledChanged", bool);
+
+    bool preferImage() { return m_prefer_image; }
+
+    void paint(QPainter) {}
+
+    this(QWidget parent)
+    {
+        super(parent);
+
+        version (QT_OPENGL_SUPPORT)
+        {
+            QGLFormat f = QGLFormat.defaultFormat();
+            f.setSampleBuffers(true);
+            f.setStencil(true);
+            f.setAlpha(true);
+            f.setAlphaBufferSize(8);
+            QGLFormat.setDefaultFormat(f);
+        }
+
+        m_tile = new QPixmap(128, 128);
+        m_tile.fill(new QColor(Qt.white));
+        scope pt = new QPainter(m_tile);
+        auto color = new QColor(230, 230, 230);
+        pt.fillRect(0, 0, 64, 64, color);
+        pt.fillRect(64, 64, 64, 64, color);
+        pt.end();
+
+    //     QPalette pal = palette();
+    //     pal.setBrush(backgroundRole(), m_tile);
+    //     setPalette(pal);
+
+        version (Q_WS_X11)
+        {
+            auto xRenderPixmap = new QPixmap(1, 1);
+            m_prefer_image = xRenderPixmap.pixmapData().classId() == QPixmapData.X11Class && !xRenderPixmap.x11PictureHandle();
+        }
+    }
+
+    version (QT_OPENGL_SUPPORT)
+    {
+        void enableOpenGL(bool use_opengl)
+        {
+            m_use_opengl = use_opengl;
+
+            if (!glw) {
+                glw = new GLWidget(this);
+                glw.setAutoFillBackground(false);
+                glw.disableAutoBufferSwap();
+                QApplication.postEvent(this, new QResizeEvent(size(), size()));
+            }
+
+            if (use_opengl) {
+                glw.show();
+            } else {
+                glw.hide();
+            }
+
+            update();
+        }
+
+        bool usesOpenGL() { return m_use_opengl; }
+        QGLWidget glWidget(){ return glw; }
+    }
+
+    override void paintEvent(QPaintEvent e)
+    {
+        version (Q_WS_QWS)
+            static QPixmap static_image;
+        else
+            static QImage static_image;
+
+        auto painter = new QPainter;
+
+        version (QT_OPENGL_SUPPORT)
+            auto prefImage = preferImage && !m_use_opengl;
+        else
+            auto prefImage = preferImage;
+
+        if (prefImage) {
+            if (!static_image || static_image.size() != size()) {
+                delete static_image;
+                version (Q_WS_QWS)
+                    static_image = new QPixmap(size());
+                else
+                    static_image = new QImage(size(), QImage.Format_RGB32);
+            }
+            painter.begin(static_image);
+
+            int o = 10;
+
+            QBrush bg = palette().brush(QPalette.Window);
+            painter.fillRect(0, 0, o, o, bg);
+            painter.fillRect(width() - o, 0, o, o, bg);
+            painter.fillRect(0, height() - o, o, o, bg);
+            painter.fillRect(width() - o, height() - o, o, o, bg);
+        } else {
+            version (QT_OPENGL_SUPPORT)
+            {
+                if (m_use_opengl) {
+                    painter.begin(glw);
+                    painter.fillRect(new QRectF(0, 0, glw.width(), glw.height()), palette().color(backgroundRole()));
+                } else {
+                    painter.begin(this);
+                }
+            }
+            else
+                painter.begin(this);
+        }
+
+        painter.setClipRect(e.rect());
+
+        painter.setRenderHint(QPainter.Antialiasing);
+
+        auto clipPath = new QPainterPath;
+
+        QRect r = rect();
+        qreal left = r.x() + 1;
+        qreal top = r.y() + 1;
+        qreal right = r.right();
+        qreal bottom = r.bottom();
+        qreal radius2 = 8 * 2;
+
+        clipPath.moveTo(right - radius2, top);
+        clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90);
+        clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90);
+        clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90);
+        clipPath.arcTo(left, top, radius2, radius2, 180, -90);
+        clipPath.closeSubpath();
+
+        painter.save();
+        painter.setClipPath(clipPath, Qt.IntersectClip);
+
+        painter.drawTiledPixmap(rect(), m_tile);
+
+        // client painting
+
+        paint(painter);
+        painter.restore();
+
+        painter.save();
+        if (m_show_doc)
+            paintDescription(painter);
+        painter.restore();
+
+        int level = 180;
+        painter.setPen(new QPen(new QBrush(new QColor(level, level, level)), 2));
+        painter.setBrush(Qt.NoBrush);
+        painter.drawPath(clipPath);
+
+        if (prefImage) {
+            painter.end();
+            painter.begin(this);
+            version (Q_WS_QWS)
+                painter.drawPixmap(e.rect(), static_image, e.rect());
+            else
+                painter.drawImage(e.rect(), static_image, e.rect());
+        }
+
+        // TODO: this sucks
+        version (QT_OPENGL_SUPPORT) {
+            if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc))
+                glw.swapBuffers();
+        }
+    }
+
+    void resizeEvent(QResizeEvent e)
+    {
+        version (QT_OPENGL_SUPPORT)
+        {
+            if (glw)
+                glw.setGeometry(0, 0, e.size().width()-1, e.size().height()-1);
+        }
+        super.resizeEvent(e);
+    }
+
+    void setDescriptionEnabled(bool enabled)
+    {
+        if (m_show_doc != enabled) {
+            m_show_doc = enabled;
+            descriptionEnabledChanged.emit(m_show_doc);
+            update();
+        }
+    }
+
+    void loadDescription(string fileName)
+    {
+        auto textFile = new QFile(fileName);
+        string text;
+        if (!textFile.open(QFile.ReadOnly))
+            text = "Unable to load resource file: " ~ fileName;
+        else
+            text = textFile.readAll().toString; // TODO: excessive copying
+        setDescription(text);
+    }
+
+    void setDescription(string text)
+    {
+        m_document = new QTextDocument(this);
+        m_document.setHtml(text);
+    }
+
+    void paintDescription(QPainter painter)
+    {
+        if (!m_document)
+            return;
+
+        int pageWidth = qMax(width() - 100, 100);
+        int pageHeight = qMax(height() - 100, 100);
+        if (pageWidth != m_document.pageSize().width()) {
+            m_document.setPageSize(QSizeF(pageWidth, pageHeight));
+        }
+
+        auto textRect = new QRect(width() / 2 - pageWidth / 2,
+                       height() / 2 - pageHeight / 2,
+                       pageWidth,
+                       pageHeight);
+        int pad = 10;
+        QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad);
+        painter.setPen(Qt.NoPen);
+        painter.setBrush(new QColor(0, 0, 0, 63));
+        int shade = 10;
+        painter.drawRect(clearRect.x() + clearRect.width() + 1,
+                          clearRect.y() + shade,
+                          shade,
+                          clearRect.height() + 1);
+        painter.drawRect(clearRect.x() + shade,
+                          clearRect.y() + clearRect.height() + 1,
+                          clearRect.width() - shade + 1,
+                          shade);
+
+        painter.setRenderHint(QPainter.Antialiasing, false);
+        painter.setBrush(new QColor(255, 255, 255, 220));
+        painter.setPen(new QColor(Qt.black));
+        painter.drawRect(clearRect);
+
+        painter.setClipRect(textRect, Qt.IntersectClip);
+        painter.translate(textRect.topLeft());
+
+        auto ctx = new QAbstractTextDocumentLayout_PaintContext;
+
+        auto g = new QLinearGradient(0, 0, 0, textRect.height());
+        g.setColorAt(0, new QColor(Qt.black));
+        g.setColorAt(0.9, new QColor(Qt.black));
+        g.setColorAt(1, new QColor(Qt.transparent));
+
+        QPalette pal = palette();
+        pal.setBrush(QPalette.Text, new QBrush(g));
+
+        ctx.setPalette(pal);
+        ctx.setClip(new QRectF(0, 0, textRect.width(), textRect.height()));
+        m_document.documentLayout().draw(painter, ctx);
+    }
+
+    void loadSourceFile(string sourceName)
+    {
+        m_sourceFileName = sourceName;
+    }
+
+    void showSource()
+    {
+        // Check for existing source
+        if (findChild!(QTextBrowser))
+            return;
+
+        string contents;
+        if (!m_sourceFileName.length) {
+            contents = "No source for widget: " ~ objectName();
+        } else {
+            auto f = new QFile(m_sourceFileName);
+            if (!f.open(QFile.ReadOnly))
+                contents = "Could not open file: " ~ m_sourceFileName;
+            else
+                contents = f.readAll.toString;
+        }
+
+        contents = contents.substitute("&", "&amp;");
+        contents = contents.substitute("<", "&lt;");
+        contents = contents.substitute(">", "&gt;");
+
+        static const string[] keywords =
+            ["for ", "if ", "switch ", " int ", "#include ", "const"
+                , "void ", "uint ", "case ", "double ", "#define ", "static"
+                , "new", "this"];
+
+        foreach (keyword; keywords)
+            contents = contents.substitute(keyword, "<font color=olive>" ~ keyword ~ "</font>");
+        contents = contents.substitute("(int ", "(<font color=olive><b>int </b></font>");
+
+        static const string[] ppKeywords =
+            ["#ifdef", "#ifndef", "#if", "#endif", "#else"];
+
+        foreach (keyword; ppKeywords)
+            contents = contents.substitute(keyword, "<font color=navy>" ~ keyword ~ "</font>");
+
+        auto ddRe = new Regex("(\\d\\d?)");
+        contents = ddRe.replaceAll(contents, "<font color=navy>\\1</font>");
+
+        auto commentRe = new Regex("(//.+?)\\n");
+        contents = commentRe.replaceAll(contents, "<font color=red>\\1</font>\n");
+
+        auto stringLiteralRe = new Regex("(\".+?\")");
+        contents = stringLiteralRe.replaceAll(contents, "<font color=green>\\1</font>");
+
+        auto html = contents.dup;
+        html = "<html><pre>" ~ html ~ "</pre></html>";
+
+        QTextBrowser sourceViewer = new QTextBrowser(null);
+        sourceViewer.setWindowTitle("Source: " ~ m_sourceFileName[5..$]);
+        sourceViewer.setParent(this, Qt.Dialog);
+        sourceViewer.setAttribute(Qt.WA_DeleteOnClose);
+        sourceViewer.setLineWrapMode(QTextEdit.NoWrap);
+        sourceViewer.setHtml(html);
+        sourceViewer.resize(600, 600);
+        sourceViewer.show();
+    }
+}
--- a/demos/shared/hoverpoints.d	Tue Sep 22 15:22:37 2009 +0000
+++ b/demos/shared/hoverpoints.d	Wed Dec 23 16:10:46 2009 +0200
@@ -1,440 +1,440 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the demonstration applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-module hoverpoints;
-
-version (QT_OPENGL_SUPPORT)
-    import qt.opengl.QGLWidget;
-
-version (D_Version2) {}
-else
-    import tango.core.Array : sort;
-
-import
-    qt.gui.QWidget,
-    qt.qtd.Array,
-    arthurwidgets;
-
-final class HoverPoints : QObject
-{
-public:
-    enum PointShape {
-        CircleShape,
-        RectangleShape
-    }
-
-    enum LockType {
-        LockToLeft   = 0x01,
-        LockToRight  = 0x02,
-        LockToTop    = 0x04,
-        LockToBottom = 0x08
-    }
-
-    enum SortType {
-        NoSort,
-        XSort,
-        YSort
-    }
-
-    enum ConnectionType {
-        NoConnection,
-        LineConnection,
-        CurveConnection
-    }
-
-private:
-    QWidget m_widget;
-
-    QPolygonF m_points;
-    QRectF m_bounds;
-    PointShape m_shape;
-    SortType m_sortType;
-    ConnectionType m_connectionType;
-
-    uint[] m_locks;
-
-    QSizeF m_pointSize;
-    int m_currentIndex;
-    bool m_editable;
-    bool m_enabled;
-
-    QPen m_pointPen;
-    QBrush m_pointBrush;
-    QPen m_connectionPen;
-
-public:
-    mixin Signal!("pointsChanged", QPolygonF /*points*/);
-
-    this(QWidget widget, PointShape shape)
-    {
-        super(widget);
-
-        m_widget = widget;
-        widget.installEventFilter(this);
-
-        m_connectionType = ConnectionType.CurveConnection;
-        m_sortType = SortType.NoSort;
-        m_shape = shape;
-        m_pointPen = new QPen(new QBrush(new QColor(255, 255, 255, 191)), 1);
-        m_connectionPen = new QPen(new QBrush(new QColor(255, 255, 255, 127)), 2);
-        m_pointBrush = new QBrush(new QColor(191, 191, 191, 127));
-        m_pointSize = QSizeF(11, 11);
-        m_currentIndex = -1;
-        m_editable = true;
-        m_enabled = true;
-
-        pointsChanged.connect(&m_widget.update);
-    }
-
-    void setBoundingRect(QRectF boundingRect) { m_bounds = boundingRect; }
-
-
-    QRectF pointBoundingRect(int i)
-    {
-        QPointF p = m_points.at(i);
-        qreal w = m_pointSize.width();
-        qreal h = m_pointSize.height();
-        qreal x = p.x() - w / 2;
-        qreal y = p.y() - h / 2;
-        return new QRectF(x, y, w, h);
-    }
-
-    QRectF boundingRect()
-    {
-        if (m_bounds.isEmpty())
-            return new QRectF(m_widget.rect());
-        else
-            return m_bounds;
-    }
-
-    QPolygonF points() { return m_points; }
-
-    QSizeF pointSize() { return m_pointSize; }
-    void setPointSize(QSizeF size) { m_pointSize = size; }
-
-    SortType sortType() { return m_sortType; }
-    void setSortType(SortType sortType) { m_sortType = sortType; }
-
-    ConnectionType connectionType() { return m_connectionType; }
-    void setConnectionType(ConnectionType connectionType) { m_connectionType = connectionType; }
-
-    void setConnectionPen(QPen pen) { m_connectionPen = pen; }
-    void setShapePen(QPen pen) { m_pointPen = pen; }
-    void setShapeBrush(QBrush brush) { m_pointBrush = brush; }
-
-    void setPointLock(int pos, LockType lock) { m_locks[pos] = lock; }
-
-    void setEditable(bool editable) { m_editable = editable; }
-    bool editable() { return m_editable; }
-
-    void setEnabled(bool enabled)
-    {
-        if (m_enabled != enabled) {
-            m_enabled = enabled;
-            m_widget.update();
-        }
-    }
-
-
-    override bool eventFilter(QObject object, QEvent event)
-    {
-        if ((object == m_widget) && m_enabled) {
-        switch (event.type()) {
-
-            case QEvent.MouseButtonPress:
-            {
-                QMouseEvent me = cast(QMouseEvent) event;
-
-                QPointF clickPos = me.pos();
-                int index = -1;
-                for (int i=0; i<m_points.size(); ++i) {
-                    auto path = new QPainterPath;
-                    if (m_shape == PointShape.CircleShape)
-                        path.addEllipse(pointBoundingRect(i));
-                    else
-                        path.addRect(pointBoundingRect(i));
-
-                    if (path.contains(clickPos)) {
-                        index = i;
-                        break;
-                    }
-                }
-
-                if (me.button() == Qt.LeftButton) {
-                    if (index == -1) {
-                        if (!m_editable)
-                            return false;
-                        int pos = 0;
-                        // Insert sort for x or y
-                        if (m_sortType == SortType.XSort) {
-                            for (int i=0; i<m_points.size(); ++i)
-                                if (m_points.at(i).x() > clickPos.x()) {
-                                    pos = i;
-                                    break;
-                                }
-                        } else if (m_sortType == SortType.YSort) {
-                            for (int i=0; i<m_points.size(); ++i)
-                                if (m_points.at(i).y() > clickPos.y()) {
-                                    pos = i;
-                                    break;
-                                }
-                        }
-
-                        // TODO: implement QPoligon(F).insert
-                        auto tmpPoints = m_points.toList;
-                        tmpPoints.insert(pos, clickPos);
-                        m_points = new QPolygonF(tmpPoints);
-
-                        m_locks.insert(pos, 0u);
-                        m_currentIndex = pos;
-                        firePointChange();
-                    } else {
-                        m_currentIndex = index;
-                    }
-                    return true;
-
-                } else if (me.button() == Qt.RightButton) {
-                    if ((index >= 0) && m_editable) {
-                        if (m_locks[index] == 0) {
-                            m_locks.removeAt(index);
-                            m_points.remove(index);
-                        }
-                        firePointChange();
-                        return true;
-                    }
-                }
-
-            }
-            break;
-
-            case QEvent.MouseButtonRelease:
-                m_currentIndex = -1;
-                break;
-
-            case QEvent.MouseMove:
-                if (m_currentIndex >= 0)
-                    movePoint(m_currentIndex, QPointF((cast(QMouseEvent)event).pos));
-                break;
-
-            case QEvent.Resize:
-            {
-                QResizeEvent e = cast(QResizeEvent) event;
-                if (e.oldSize().width() == 0 || e.oldSize().height() == 0)
-                    break;
-                qreal stretch_x = e.size().width() / cast(qreal)e.oldSize.width;
-                qreal stretch_y = e.size().height() / cast(qreal)e.oldSize.height;
-                for (int i=0; i<m_points.size(); ++i) {
-                    QPointF p = m_points.at(i);
-                    movePoint(i, QPointF(p.x() * stretch_x, p.y() * stretch_y), false);
-                }
-
-                firePointChange();
-                break;
-            }
-
-            case QEvent.Paint:
-            {
-                QWidget that_widget = m_widget;
-                m_widget = null;
-                QApplication.sendEvent(object, event);
-                m_widget = that_widget;
-                paintPoints();
-                version (QT_OPENGL_SUPPORT)
-                {
-                    ArthurFrame af = cast(ArthurFrame)(that_widget);
-                    if (af && af.usesOpenGL())
-                        af.glWidget().swapBuffers();
-                }
-
-                return true;
-            }
-            default:
-                break;
-            }
-        }
-
-        return false;
-    }
-
-
-    void paintPoints()
-    {
-        scope p = new QPainter;
-        version (QT_OPENGL_SUPPORT)
-        {
-            ArthurFrame af = cast(ArthurFrame)(m_widget);
-            if (af && af.usesOpenGL())
-                p.begin(af.glWidget());
-            else
-                p.begin(m_widget);
-        }
-        else
-            p.begin(m_widget);
-
-        p.setRenderHint(QPainter.Antialiasing);
-
-        if (m_connectionPen.style() != Qt.NoPen && m_connectionType != ConnectionType.NoConnection) {
-            p.setPen(m_connectionPen);
-
-            if (m_connectionType == ConnectionType.CurveConnection) {
-                auto path = new QPainterPath;
-                path.moveTo(m_points.at(0));
-                for (int i=1; i<m_points.size(); ++i) {
-                    QPointF p1 = m_points.at(i-1);
-                    QPointF p2 = m_points.at(i);
-                    qreal distance = p2.x() - p1.x();
-
-                    path.cubicTo(p1.x() + distance / 2, p1.y(),
-                                 p1.x() + distance / 2, p2.y(),
-                                 p2.x(), p2.y());
-                }
-                p.drawPath(path);
-            } else {
-                p.drawPolyline(m_points);
-            }
-        }
-
-        p.setPen(m_pointPen);
-        p.setBrush(m_pointBrush);
-
-        for (int i=0; i<m_points.size(); ++i) {
-            QRectF bounds = pointBoundingRect(i);
-            if (m_shape == PointShape.CircleShape)
-                p.drawEllipse(bounds);
-            else
-                p.drawRect(bounds);
-        }
-    }
-
-
-    void setPoints(QPolygonF points)
-    {
-        delete m_points;
-        for (int i=0; i<points.size; ++i)
-            m_points.append(bound_point(points.at(i), boundingRect(), 0));
-
-        delete m_locks;
-        if (m_points.size > 0) {
-            m_locks.length = m_points.size;
-
-            m_locks[] = 0;
-        }
-    }
-
-    void movePoint(int index, QPointF point, bool emitUpdate = true)
-    {
-        m_points.replace(index, bound_point(point, boundingRect(), m_locks[index]));
-        if (emitUpdate)
-            firePointChange();
-    }
-
-    void firePointChange()
-    {
-    //    printf("HoverPoints.firePointChange(), current=%d\n", m_currentIndex);
-
-        if (m_sortType != SortType.NoSort) {
-
-            QPointF oldCurrent;
-            if (m_currentIndex != -1) {
-                oldCurrent = m_points.at(m_currentIndex);
-            }
-
-            if (m_sortType == SortType.XSort)
-            {
-                auto tmpPoints = m_points.toList;
-                sort(tmpPoints, &x_less_than);
-                m_points = new QPolygonF(tmpPoints);
-            }
-            else if (m_sortType == SortType.YSort)
-            {
-                auto tmpPoints = m_points.toList;
-                sort(tmpPoints, &y_less_than);
-                m_points = new QPolygonF(tmpPoints);
-            }
-
-            // Compensate for changed order...
-            if (m_currentIndex != -1) {
-                for (int i=0; i<m_points.size; ++i) {
-                    if (m_points.at(i) == oldCurrent) {
-                        m_currentIndex = i;
-                        break;
-                    }
-                }
-            }
-
-    //         printf(" - firePointChange(), current=%d\n", m_currentIndex);
-        }
-
-    //     for (int i=0; i<m_points.size(); ++i) {
-    //         printf(" - point(%2d)=[%.2f, %.2f], lock=%d\n",
-    //                i, m_points.at(i).x(), m_points.at(i).y(), m_locks.at(i));
-    //     }
-
-        pointsChanged.emit(m_points);
-    }
-}
-
-private QPointF bound_point(QPointF point, QRectF bounds, int lock)
-{
-    QPointF p = point;
-
-    qreal left = bounds.left();
-    qreal right = bounds.right();
-    qreal top = bounds.top();
-    qreal bottom = bounds.bottom();
-
-    if (p.x() < left || (lock & HoverPoints.LockType.LockToLeft)) p.x = left;
-    else if (p.x() > right || (lock & HoverPoints.LockType.LockToRight)) p.x = right;
-
-    if (p.y() < top || (lock & HoverPoints.LockType.LockToTop)) p.y = top;
-    else if (p.y() > bottom || (lock & HoverPoints.LockType.LockToBottom)) p.y = bottom;
-
-    return p;
-}
-
-private bool x_less_than(QPointF p1, QPointF p2)
-{
-    return p1.x() < p2.x();
-}
-
-private bool y_less_than(QPointF p1, QPointF p2)
-{
-    return p1.y() < p2.y();
-}
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+module hoverpoints;
+
+version (QT_OPENGL_SUPPORT)
+    import qt.opengl.QGLWidget;
+
+version (D_Version2) {}
+else
+    import tango.core.Array : sort;
+
+import
+    qt.gui.QWidget,
+    qt.qtd.Array,
+    arthurwidgets;
+
+final class HoverPoints : QObject
+{
+public:
+    enum PointShape {
+        CircleShape,
+        RectangleShape
+    }
+
+    enum LockType {
+        LockToLeft   = 0x01,
+        LockToRight  = 0x02,
+        LockToTop    = 0x04,
+        LockToBottom = 0x08
+    }
+
+    enum SortType {
+        NoSort,
+        XSort,
+        YSort
+    }
+
+    enum ConnectionType {
+        NoConnection,
+        LineConnection,
+        CurveConnection
+    }
+
+private:
+    QWidget m_widget;
+
+    QPolygonF m_points;
+    QRectF m_bounds;
+    PointShape m_shape;
+    SortType m_sortType;
+    ConnectionType m_connectionType;
+
+    uint[] m_locks;
+
+    QSizeF m_pointSize;
+    int m_currentIndex;
+    bool m_editable;
+    bool m_enabled;
+
+    QPen m_pointPen;
+    QBrush m_pointBrush;
+    QPen m_connectionPen;
+
+public:
+    mixin Signal!("pointsChanged", QPolygonF /*points*/);
+
+    this(QWidget widget, PointShape shape)
+    {
+        super(widget);
+
+        m_widget = widget;
+        widget.installEventFilter(this);
+
+        m_connectionType = ConnectionType.CurveConnection;
+        m_sortType = SortType.NoSort;
+        m_shape = shape;
+        m_pointPen = new QPen(new QBrush(new QColor(255, 255, 255, 191)), 1);
+        m_connectionPen = new QPen(new QBrush(new QColor(255, 255, 255, 127)), 2);
+        m_pointBrush = new QBrush(new QColor(191, 191, 191, 127));
+        m_pointSize = QSizeF(11, 11);
+        m_currentIndex = -1;
+        m_editable = true;
+        m_enabled = true;
+
+        pointsChanged.connect(&m_widget.update);
+    }
+
+    void setBoundingRect(QRectF boundingRect) { m_bounds = boundingRect; }
+
+
+    QRectF pointBoundingRect(int i)
+    {
+        QPointF p = m_points.at(i);
+        qreal w = m_pointSize.width();
+        qreal h = m_pointSize.height();
+        qreal x = p.x() - w / 2;
+        qreal y = p.y() - h / 2;
+        return new QRectF(x, y, w, h);
+    }
+
+    QRectF boundingRect()
+    {
+        if (m_bounds.isEmpty())
+            return new QRectF(m_widget.rect());
+        else
+            return m_bounds;
+    }
+
+    QPolygonF points() { return m_points; }
+
+    QSizeF pointSize() { return m_pointSize; }
+    void setPointSize(QSizeF size) { m_pointSize = size; }
+
+    SortType sortType() { return m_sortType; }
+    void setSortType(SortType sortType) { m_sortType = sortType; }
+
+    ConnectionType connectionType() { return m_connectionType; }
+    void setConnectionType(ConnectionType connectionType) { m_connectionType = connectionType; }
+
+    void setConnectionPen(QPen pen) { m_connectionPen = pen; }
+    void setShapePen(QPen pen) { m_pointPen = pen; }
+    void setShapeBrush(QBrush brush) { m_pointBrush = brush; }
+
+    void setPointLock(int pos, LockType lock) { m_locks[pos] = lock; }
+
+    void setEditable(bool editable) { m_editable = editable; }
+    bool editable() { return m_editable; }
+
+    void setEnabled(bool enabled)
+    {
+        if (m_enabled != enabled) {
+            m_enabled = enabled;
+            m_widget.update();
+        }
+    }
+
+
+    override bool eventFilter(QObject object, QEvent event)
+    {
+        if ((object == m_widget) && m_enabled) {
+        switch (event.type()) {
+
+            case QEvent.MouseButtonPress:
+            {
+                QMouseEvent me = cast(QMouseEvent) event;
+
+                QPointF clickPos = me.pos();
+                int index = -1;
+                for (int i=0; i<m_points.size(); ++i) {
+                    auto path = new QPainterPath;
+                    if (m_shape == PointShape.CircleShape)
+                        path.addEllipse(pointBoundingRect(i));
+                    else
+                        path.addRect(pointBoundingRect(i));
+
+                    if (path.contains(clickPos)) {
+                        index = i;
+                        break;
+                    }
+                }
+
+                if (me.button() == Qt.LeftButton) {
+                    if (index == -1) {
+                        if (!m_editable)
+                            return false;
+                        int pos = 0;
+                        // Insert sort for x or y
+                        if (m_sortType == SortType.XSort) {
+                            for (int i=0; i<m_points.size(); ++i)
+                                if (m_points.at(i).x() > clickPos.x()) {
+                                    pos = i;
+                                    break;
+                                }
+                        } else if (m_sortType == SortType.YSort) {
+                            for (int i=0; i<m_points.size(); ++i)
+                                if (m_points.at(i).y() > clickPos.y()) {
+                                    pos = i;
+                                    break;
+                                }
+                        }
+
+                        // TODO: implement QPoligon(F).insert
+                        auto tmpPoints = m_points.toList;
+                        tmpPoints.insert(pos, clickPos);
+                        m_points = new QPolygonF(tmpPoints);
+
+                        m_locks.insert(pos, 0u);
+                        m_currentIndex = pos;
+                        firePointChange();
+                    } else {
+                        m_currentIndex = index;
+                    }
+                    return true;
+
+                } else if (me.button() == Qt.RightButton) {
+                    if ((index >= 0) && m_editable) {
+                        if (m_locks[index] == 0) {
+                            m_locks.removeAt(index);
+                            m_points.remove(index);
+                        }
+                        firePointChange();
+                        return true;
+                    }
+                }
+
+            }
+            break;
+
+            case QEvent.MouseButtonRelease:
+                m_currentIndex = -1;
+                break;
+
+            case QEvent.MouseMove:
+                if (m_currentIndex >= 0)
+                    movePoint(m_currentIndex, QPointF((cast(QMouseEvent)event).pos));
+                break;
+
+            case QEvent.Resize:
+            {
+                QResizeEvent e = cast(QResizeEvent) event;
+                if (e.oldSize().width() == 0 || e.oldSize().height() == 0)
+                    break;
+                qreal stretch_x = e.size().width() / cast(qreal)e.oldSize.width;
+                qreal stretch_y = e.size().height() / cast(qreal)e.oldSize.height;
+                for (int i=0; i<m_points.size(); ++i) {
+                    QPointF p = m_points.at(i);
+                    movePoint(i, QPointF(p.x() * stretch_x, p.y() * stretch_y), false);
+                }
+
+                firePointChange();
+                break;
+            }
+
+            case QEvent.Paint:
+            {
+                QWidget that_widget = m_widget;
+                m_widget = null;
+                QApplication.sendEvent(object, event);
+                m_widget = that_widget;
+                paintPoints();
+                version (QT_OPENGL_SUPPORT)
+                {
+                    ArthurFrame af = cast(ArthurFrame)(that_widget);
+                    if (af && af.usesOpenGL())
+                        af.glWidget().swapBuffers();
+                }
+
+                return true;
+            }
+            default:
+                break;
+            }
+        }
+
+        return false;
+    }
+
+
+    void paintPoints()
+    {
+        scope p = new QPainter;
+        version (QT_OPENGL_SUPPORT)
+        {
+            ArthurFrame af = cast(ArthurFrame)(m_widget);
+            if (af && af.usesOpenGL())
+                p.begin(af.glWidget());
+            else
+                p.begin(m_widget);
+        }
+        else
+            p.begin(m_widget);
+
+        p.setRenderHint(QPainter.Antialiasing);
+
+        if (m_connectionPen.style() != Qt.NoPen && m_connectionType != ConnectionType.NoConnection) {
+            p.setPen(m_connectionPen);
+
+            if (m_connectionType == ConnectionType.CurveConnection) {
+                auto path = new QPainterPath;
+                path.moveTo(m_points.at(0));
+                for (int i=1; i<m_points.size(); ++i) {
+                    QPointF p1 = m_points.at(i-1);
+                    QPointF p2 = m_points.at(i);
+                    qreal distance = p2.x() - p1.x();
+
+                    path.cubicTo(p1.x() + distance / 2, p1.y(),
+                                 p1.x() + distance / 2, p2.y(),
+                                 p2.x(), p2.y());
+                }
+                p.drawPath(path);
+            } else {
+                p.drawPolyline(m_points);
+            }
+        }
+
+        p.setPen(m_pointPen);
+        p.setBrush(m_pointBrush);
+
+        for (int i=0; i<m_points.size(); ++i) {
+            QRectF bounds = pointBoundingRect(i);
+            if (m_shape == PointShape.CircleShape)
+                p.drawEllipse(bounds);
+            else
+                p.drawRect(bounds);
+        }
+    }
+
+
+    void setPoints(QPolygonF points)
+    {
+        delete m_points;
+        for (int i=0; i<points.size; ++i)
+            m_points.append(bound_point(points.at(i), boundingRect(), 0));
+
+        delete m_locks;
+        if (m_points.size > 0) {
+            m_locks.length = m_points.size;
+
+            m_locks[] = 0;
+        }
+    }
+
+    void movePoint(int index, QPointF point, bool emitUpdate = true)
+    {
+        m_points.replace(index, bound_point(point, boundingRect(), m_locks[index]));
+        if (emitUpdate)
+            firePointChange();
+    }
+
+    void firePointChange()
+    {
+    //    printf("HoverPoints.firePointChange(), current=%d\n", m_currentIndex);
+
+        if (m_sortType != SortType.NoSort) {
+
+            QPointF oldCurrent;
+            if (m_currentIndex != -1) {
+                oldCurrent = m_points.at(m_currentIndex);
+            }
+
+            if (m_sortType == SortType.XSort)
+            {
+                auto tmpPoints = m_points.toList;
+                sort(tmpPoints, &x_less_than);
+                m_points = new QPolygonF(tmpPoints);
+            }
+            else if (m_sortType == SortType.YSort)
+            {
+                auto tmpPoints = m_points.toList;
+                sort(tmpPoints, &y_less_than);
+                m_points = new QPolygonF(tmpPoints);
+            }
+
+            // Compensate for changed order...
+            if (m_currentIndex != -1) {
+                for (int i=0; i<m_points.size; ++i) {
+                    if (m_points.at(i) == oldCurrent) {
+                        m_currentIndex = i;
+                        break;
+                    }
+                }
+            }
+
+    //         printf(" - firePointChange(), current=%d\n", m_currentIndex);
+        }
+
+    //     for (int i=0; i<m_points.size(); ++i) {
+    //         printf(" - point(%2d)=[%.2f, %.2f], lock=%d\n",
+    //                i, m_points.at(i).x(), m_points.at(i).y(), m_locks.at(i));
+    //     }
+
+        pointsChanged.emit(m_points);
+    }
+}
+
+private QPointF bound_point(QPointF point, QRectF bounds, int lock)
+{
+    QPointF p = point;
+
+    qreal left = bounds.left();
+    qreal right = bounds.right();
+    qreal top = bounds.top();
+    qreal bottom = bounds.bottom();
+
+    if (p.x() < left || (lock & HoverPoints.LockType.LockToLeft)) p.x = left;
+    else if (p.x() > right || (lock & HoverPoints.LockType.LockToRight)) p.x = right;
+
+    if (p.y() < top || (lock & HoverPoints.LockType.LockToTop)) p.y = top;
+    else if (p.y() > bottom || (lock & HoverPoints.LockType.LockToBottom)) p.y = bottom;
+
+    return p;
+}
+
+private bool x_less_than(QPointF p1, QPointF p2)
+{
+    return p1.x() < p2.x();
+}
+
+private bool y_less_than(QPointF p1, QPointF p2)
+{
+    return p1.y() < p2.y();
+}
--- a/generator/abstractmetalang.cpp	Tue Sep 22 15:22:37 2009 +0000
+++ b/generator/abstractmetalang.cpp	Wed Dec 23 16:10:46 2009 +0200
@@ -1159,13 +1159,15 @@
 
 bool AbstractMetaClass::generateShellClass() const
 {
-    return m_force_shell_class ||
-        m_has_virtual_destructor ||
-    (!isFinal()
-        && (hasVirtualFunctions()
+    return m_force_shell_class ||         
+    ( /*!isFinal()
+        && ( */
+        isPolymorphic()
         || hasProtectedFunctions()
         || hasFieldAccessors()
-        || typeEntry()->isObject())); // qtd2 for being more consistent
+        //|| typeEntry()->isObject() // qtd2 for being more consistent
+        /*)*/
+        );
 }
 
 QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const
@@ -1340,7 +1342,7 @@
     f->setImplementingClass(this);
     f->setOriginalAttributes(f->attributes());
 
-    /*addFunction*/(f);
+    addFunction(f);
 }
 
 bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const
--- a/generator/abstractmetalang.h	Tue Sep 22 15:22:37 2009 +0000
+++ b/generator/abstractmetalang.h	Wed Dec 23 16:10:46 2009 +0200
@@ -784,12 +784,49 @@
     void setForceShellClass(bool on) { m_force_shell_class = on; }
     bool generateShellClass() const;
 
-    bool hasVirtualSlots() const { return m_has_virtual_slots; }       
-    bool hasVirtualFunctions() const { return !isFinal() && (m_has_virtuals || hasVirtualDestructor()); }
+    bool hasVirtualSlots() const { return m_has_virtual_slots; }
+
+    // returns true if this class has overridable virtual functions other than
+    // the virtual destructor if one exists.
+    bool hasVirtualFunctions() const { return !isFinal() && m_has_virtuals;  }
+
+    // returns true if this class or its base classes define a
+    // virtual destructor
     bool hasVirtualDestructor() const { return m_has_virtual_destructor
-        || (m_base_class && m_base_class->hasVirtualDestructor()); }
+        || m_base_class && m_base_class->hasVirtualDestructor(); }
+
+    // returns the uppermost base class having virtual functions
+    const AbstractMetaClass* polymorphicBase() const
+    {
+        const AbstractMetaClass*  ret = this;
+        for (const AbstractMetaClass* base = this->m_base_class; base; base = base->m_base_class)
+        {
+            if (base->m_has_virtuals || base->m_has_virtual_destructor)
+                ret = base;
+        }
+        return ret;
+    }
+
+    // returns true if this class or its base classes have any virtual functions
+    bool isPolymorphic() const { return m_has_virtuals
+                             || m_has_virtual_destructor
+                             || m_base_class && m_base_class->isPolymorphic();
+    }
+
+    // returns the uppermost base class with virtual destructors
+    const AbstractMetaClass* virtualDestructorBase() const
+    {
+        const AbstractMetaClass* ret = NULL;
+        for (const AbstractMetaClass* base = this; base; base = base->m_base_class)
+        {
+            if (base->m_has_virtual_destructor)
+                ret = base;
+        }
+        return ret;
+    }
+
     bool setHasVirtualDestructor(bool value) { m_has_virtual_destructor = value; }
-    bool isPolymorphic() const { return typeEntry()->isObject() && (hasVirtualFunctions() || hasVirtualDestructor()); }
+
     bool hasProtectedFunctions() const;
 
     QList<TypeEntry *> templateArguments() const { return m_template_args; }
--- a/generator/cppgenerator.cpp	Tue Sep 22 15:22:37 2009 +0000
+++ b/generator/cppgenerator.cpp	Wed Dec 23 16:10:46 2009 +0200
@@ -230,7 +230,7 @@
     s << "(";
     const AbstractMetaClass *owner = java_function->ownerClass();
 
-    bool has_d_ptr = java_function->isConstructor() && owner && owner->typeEntry()->isObject();
+    bool has_d_ptr = java_function->isConstructor() && owner && owner->isPolymorphic();
     const AbstractMetaArgumentList arg_list = java_function->arguments();
     if (has_d_ptr) {
         s << "void *d_ptr";
--- a/generator/cppheadergenerator.cpp	Tue Sep 22 15:22:37 2009 +0000
+++ b/generator/cppheadergenerator.cpp	Wed Dec 23 16:10:46 2009 +0200
@@ -250,7 +250,7 @@
     s  << "};" << endl << endl;
     
     if (!java_class->isQObject() && java_class->isPolymorphic() && java_class->baseClass())
-        s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->rootClass()->name() << "_dId(void *nativeId);" << endl;
+        s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->polymorphicBase()->name() << "_dId(void *nativeId);" << endl;
    
     s << "#endif // " << include_block << endl;
 
--- a/generator/cppimplgenerator.cpp	Tue Sep 22 15:22:37 2009 +0000
+++ b/generator/cppimplgenerator.cpp	Wed Dec 23 16:10:46 2009 +0200
@@ -589,7 +589,7 @@
 
     if (hasCustomDestructor(java_class)) */
    
-    if (java_class->hasPublicDestructor() && (!java_class->baseClass() || !java_class->hasVirtualFunctions()))
+    if (java_class->hasPublicDestructor() && !java_class->hasVirtualDestructor())
         writeDestructor(s, java_class);
 
     if (java_class->isQObject())
@@ -601,7 +601,7 @@
                 writeShellConstructor(s, function);
         }
         
-        if (java_class->hasVirtualFunctions())
+        if (java_class->isPolymorphic())
             writeShellDestructor(s, java_class);
 
         if (java_class->isQObject())
@@ -618,6 +618,7 @@
             // qtd            writeShellFunction(s, function, java_class, pos);
             writeShellVirtualFunction(s, function, java_class, pos);
         }
+        s << "// end ------------------------" << endl << endl;
 
         if (cpp_shared)
             writeInitCallbacks(s, java_class);
@@ -629,6 +630,7 @@
             const AbstractMetaFunction *function = shellFunctions.at(i);
             writeShellFunction(s, function, java_class, -1);
         }
+        s << "// end ------------------------" << endl << endl;
 
         // Write public overrides for functions that are protected in the base class
         // so they can be accessed from the native callback
@@ -639,6 +641,7 @@
                 continue;
             writePublicFunctionOverride(s, function, java_class);
         }
+        s << "// end ------------------------" << endl << endl;
 
         // Write virtual function overries used to decide on static/virtual calls
         s << "// Write virtual function overries used to decide on static/virtual calls" << endl;
@@ -648,6 +651,7 @@
                 continue;
             writeVirtualFunctionOverride(s, function, java_class);
         }
+        s << "// end ------------------------" << endl << endl;;
     }
 
     writeExtraFunctions(s, java_class);
@@ -663,15 +667,14 @@
     for (int i=0; i<signal_functions.size(); ++i)
         writeSignalFunction(s, signal_functions.at(i), java_class, i);
 */
-    s << "// ---externC---" << endl;
-
+    s << "// extern C" << endl;
     // Native callbacks (all java functions require native callbacks)
     AbstractMetaFunctionList class_funcs = java_class->functionsInTargetLang();
     foreach (AbstractMetaFunction *function, class_funcs) {
         if (!function->isEmptyFunction())
             writeFinalFunction(s, function, java_class);
     }
-    s << "// ---externC---end" << endl;
+    s << "// end ------------------------" << endl << endl;
 
 
     class_funcs = java_class->queryFunctions(AbstractMetaClass::NormalFunctions | AbstractMetaClass::AbstractFunctions | AbstractMetaClass::NotRemovedFromTargetLang);
@@ -687,6 +690,8 @@
         if (field->wasPublic() || (field->wasProtected() && !java_class->isFinal()))
             writeFieldAccessors(s, field);
     }
+    s << "// end ------------------------" << endl << endl;
+
 /*
     s << "// writeFromNativeFunction" << endl;
     writeFromNativeFunction(s, java_class);
@@ -711,7 +716,7 @@
     if (java_class->isQObject())
     {
         s << endl << endl
-          << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_staticMetaObject() {" << endl
+          << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_staticTypeId() {" << endl
           << "    return (void*)&" << java_class->name() << "::staticMetaObject;" << endl
           << "}" << endl;
     }
@@ -1391,7 +1396,7 @@
     
     if (cls->isQObject())
         s << "," << endl << "      QtD_QObjectEntity(this, d_ptr)";
-    else if (cls->hasVirtualFunctions())
+    else if (cls->isPolymorphic())
         s << "," << endl << "      QtD_Entity(d_ptr)";
 /* qtd        s << "    m_meta_object(0)," << endl;
     s << "      m_vtable(0)," << endl
@@ -1736,7 +1741,27 @@
 
 void CppImplGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *java_class)
 {
-    if (java_class->isPolymorphic())
+    if (java_class == java_class->polymorphicBase())
+    {
+        if (java_class->isPolymorphic())
+        {
+            s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_dId(void *nativeId)" << endl
+              << "{" << endl
+              << "    QtD_Entity *e = dynamic_cast<QtD_Entity*>((" << java_class->qualifiedCppName() << "*)nativeId);" << endl
+              << "    return e ? e->dId : NULL;" << endl
+              << "}" << endl << endl;
+        }
+
+        if (!java_class->isQObject())
+        {
+            s << "extern \"C\" DLL_PUBLIC const void* qtd_" << java_class->name() << "_typeId(void *nativeId)" << endl
+              << "{" << endl
+              << "    return &typeid((" << java_class->qualifiedCppName() << "*)nativeId);" << endl
+              << "}" << endl << endl;
+        }
+    }
+
+    if (!java_class->isQObject())
     {
         s << "extern \"C\" DLL_PUBLIC const void* qtd_" << java_class->name() << "_staticTypeId()" << endl;
         s << "{" << endl;
@@ -1745,20 +1770,6 @@
                 s << INDENT << "return &typeid(" << java_class->qualifiedCppName() << ");" << endl;
         }
         s << "}" << endl << endl;
-        
-        if (!java_class->baseClass())
-        {
-            s << "extern \"C\" DLL_PUBLIC void* qtd_" << java_class->name() << "_dId(void *nativeId)" << endl
-              << "{" << endl
-              << "    QtD_Entity *a = dynamic_cast<QtD_Entity*>((" << java_class->qualifiedCppName() << "*)nativeId);" << endl
-              << "    return a ? a->dId : NULL;" << endl
-              << "}" << endl << endl
-            
-              << "extern \"C\" DLL_PUBLIC const void* qtd_" << java_class->name() << "_typeId(void *nativeId)" << endl
-              << "{" << endl
-              << "    return &typeid((" << java_class->qualifiedCppName() << "*)nativeId);" << endl
-              << "}" << endl << endl;
-        }       
     }
 }
 
@@ -1883,7 +1894,7 @@
     const AbstractMetaClass *cls = java_function->ownerClass();
           
     if (java_function->isConstructor() &&
-        cls->hasVirtualFunctions())
+        cls->isPolymorphic())
     {
         s << "void *d_ptr";
         nativeArgCount++;
@@ -2104,7 +2115,7 @@
                 if (java_class->isQObject())
                     s << "QtD_QObjectEntity::getQObjectEntity((QObject*)__this_nativeId) : false;" << endl;
                 else
-                    s << "qtd_" << java_class->rootClass()->name() << "_dId(__this_nativeId) : false;" << endl;
+                    s << "qtd_" << java_class->polymorphicBase()->name() << "_dId(__this_nativeId) : false;" << endl;
             } else {
                 option = OriginalName;
             }
@@ -2312,14 +2323,13 @@
     if (!cls->hasConstructors())
         return;
 
-    s << INDENT << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_destructor(void *ptr)" << endl
-        << INDENT << "{" << endl;
+    if (cls->polymorphicBase() == cls)
     {
-        QString className = cls->hasVirtualFunctions() ? cls->typeEntry()->name() : shellClassName(cls);
-        s << INDENT << "delete (" << className << " *)ptr;" << endl;
+        s << "extern \"C\" DLL_PUBLIC void qtd_" << cls->name() << "_delete(void *ptr){" << endl;
+        QString className = cls->generateShellClass() ? shellClassName(cls) : cls->typeEntry()->name();
+        s << "    delete (" << className << " *)ptr;" << endl
+          << "}" << endl << endl;
     }
-
-    s << INDENT << "}" << endl << endl;
 }
 
 void CppImplGenerator::writeFinalConstructor(QTextStream &s,
@@ -2666,6 +2676,8 @@
                                      const AbstractMetaFunction *java_function,
                                      int argument_index)
 {
+    s << "//writeJavaToQt" << endl; // TMP
+
     // Conversion to C++: Shell code for return values, native code for arguments
     TypeSystem::Language lang = argument_index == 0 ? TypeSystem::ShellCode : TypeSystem::NativeCode;
     if (writeConversionRule(s, lang, java_function, argument_index, qt_name, java_name))
@@ -2694,6 +2706,8 @@
                                      int argument_index,
                                      Option options)
 {
+    s << "//writeJavaToQt 2" << endl; // TMP
+
     // Conversion to C++: Shell code for return values, native code for arguments
     TypeSystem::Language lang = argument_index == 0 ? TypeSystem::ShellCode : TypeSystem::NativeCode;
     if (java_function && writeConversionRule(s, lang, java_function, argument_index, qt_name, java_name))
@@ -2930,6 +2944,7 @@
                                      int argument_index,
                                      Option option)
 {
+    s << "writeQtToJava" << endl;
 
     // Conversion to Java: Native code for return values, shell code for arguments
     TypeSystem::Language lang = argument_index == 0 ? TypeSystem::NativeCode : TypeSystem::ShellCode;
@@ -3531,7 +3546,7 @@
 
     int written_arguments = 0;
     const AbstractMetaClass *cls = java_function->ownerClass();
-    if (java_function->isConstructor() && cls->hasVirtualFunctions()) {
+    if (java_function->isConstructor() && cls->isPolymorphic()) {
         s << "d_ptr";
         written_arguments++;
     }
--- a/generator/dgenerator.cpp	Tue Sep 22 15:22:37 2009 +0000
+++ b/generator/dgenerator.cpp	Wed Dec 23 16:10:46 2009 +0200
@@ -23,7 +23,7 @@
 * are described in the Nokia Qt GPL Exception version 1.2, included in
 * the file GPL_EXCEPTION.txt in this package.
 *
-* Qt for Windows(R) Licensees
+* Qt for Win1782dows(R) Licensees
 * As a special exception, Nokia, as the sole copyright holder for Qt
 * Designer, grants users of the Qt/Eclipse Integration plug-in the
 * right for the Qt/Eclipse Integration to link to functionality
@@ -772,7 +772,7 @@
 
     if (d_function->isConstructor() &&
         ( d_function->implementingClass()->isPolymorphic()
-        || d_function->implementingClass()->typeEntry()->isObject() ) ) { // qtd
+        /*|| d_function->implementingClass()->typeEntry()->isObject()*/ ) ) { // qtd
         s << "cast(void*) this";
         if (arguments.count() > 0)
             s << ", ";
@@ -1680,18 +1680,23 @@
     if (!d_class->hasConstructors())
         return;
 
-    s << "    override void __deleteNative() {" << endl
-        << "        qtd_" << d_class->name() << "_destructor(__nativeId);" << endl
-        << "    }" << endl;
+    if (d_class->polymorphicBase() == d_class)
+    {
+        s << "    override void __deleteNative() {" << endl
+            << "        qtd_" << d_class->polymorphicBase()->name() << "_delete(__nativeId);" << endl
+            << "    }" << endl;
+    }
 }
 
 void DGenerator::writeOwnershipSetter(QTextStream &s, const AbstractMetaClass *d_class)
 {
     if (d_class->isInterface() || d_class->isNamespace())
-        s << INDENT << "void __nativeOwnership(bool value);";
+    {
+        //s << INDENT << "void __nativeOwnership(bool value);";
+    }
     else if (d_class->typeEntry()->isObject())
     {// COMPILER BUG:
-        s << INDENT << "void __nativeOwnership(bool value) { super.__nativeOwnership = value; }";
+        //s << INDENT << "void __nativeOwnership(bool value) { super.__nativeOwnership = value; }";
     }
 }
 
@@ -1756,30 +1761,12 @@
                 {
                     bool resetAfterUse = !type->isQObject() && signal->resetObjectAfterUse(argument->argumentIndex() + 1);
 
-                    if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->isPolymorphic())
-                    {
-                        QString flags;
-                        if (resetAfterUse)
-                            flags = "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete";
-                        else
-                            flags = "QtdObjectFlags.none";
-                        
-                        s << INDENT << "auto " << arg_name << " = " << type->typeEntry()->name() << ".__wrap(" << arg_name
-                            << ", cast(QtdObjectFlags)(" << flags << "));" << endl;
-
-                        if (resetAfterUse)
-                        {
-                            s << INDENT << "scope(exit) {" << endl
-                              << INDENT << "    if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl
-                              << INDENT << "        delete " << arg_name << ";" << endl
-                              << INDENT << "}" << endl;
-                        }
-                    }
+                    if (resetAfterUse)
+                        s << "auto " << arg_name << " = scopeObject!(" << type->typeEntry()->name() << ")(" << arg_name << ");";
                     else
                     {
-                        s << INDENT << (resetAfterUse ? "scope " : "auto ")
-                          << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags."
-                          << (resetAtferUse ? "skipNativeDelete" : "none") << ");" << endl;
+                        s << INDENT << "auto " << arg_name << " = " << type->typeEntry()->name() << ".__wrap(" << arg_name
+                          << ");" << endl;
                     }
                 }
 
@@ -1813,7 +1800,7 @@
     auxFile.isDone = true;
     auxFile.stream << "module " << auxModName << ";" << endl << endl;
 
-    bool staticInit = (d_class->typeEntry()->isObject() && d_class->isPolymorphic()) || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface());
+    bool staticInit = d_class->isPolymorphic() || (cpp_shared && d_class->generateShellClass() && !d_class->isInterface());
     if (staticInit)
     {
         auxFile.isDone = false;
@@ -1921,7 +1908,7 @@
           << "public import qt.core.Qt;" << endl
           << "public import qt.QtdObject;" << endl
           << "private import qt.core.QString;" << endl
-          << "private import qt.qtd.Array;" << endl;
+          << "private import qt.Array;" << endl;
         if (d_class->isQObject()) {
             s << "public import qt.core.QMetaObject;" << endl;
             s << "public import qt.Signal;" << endl;
@@ -1952,7 +1939,8 @@
             s << "import std.stdio;" << endl
               << "import std.string;" << endl
               << "import std.utf;" << endl
-              << "import core.memory;" << endl;
+              << "import core.memory;" << endl
+              << "import qt.Core;" << endl;
         }
         else
         {
@@ -2023,11 +2011,10 @@
         if (d_class->baseClass()) {
             s << d_class->baseClass()->name();
         } else {
-            if (d_class->typeEntry()->isValue())
+            if (d_class->isQObject())
                 s << "QtdObjectBase";
-            else if (d_class->typeEntry()->isObject())
+            else
                 s << "QtdObject";
-
         }
     }/* qtd else if (d_class->isInterface()) {
         s << " extends QtJambiInterface";
@@ -2109,18 +2096,17 @@
                 s << INDENT << "@SuppressWarnings(\"unused\")" << endl;
 */
             if (actions != ReferenceCount::Set && actions != ReferenceCount::Ignore) { // qtd2
-
-            s << INDENT;
-            switch (access) {
-            case ReferenceCount::Private:
-                s << "package "; break; // qtd
-            case ReferenceCount::Protected:
-                s << "protected "; break;
-            case ReferenceCount::Public:
-                s << "public "; break;
-            default: // friendly
-            }
-
+                s << INDENT;
+                switch (access) {
+                case ReferenceCount::Private:
+                    s << "package "; break; // qtd
+                case ReferenceCount::Protected:
+                    s << "protected "; break;
+                case ReferenceCount::Public:
+                    s << "public "; break;
+                default: // friendly
+                    break;
+                }
             } // qtd2
 
             if (isStatic)
@@ -2220,36 +2206,13 @@
             writeFieldAccessors(s, field);
     }
 
-    if (d_class->typeEntry()->isObject())
-    {
-        if (d_class->isQObject())
-            writeQObjectFunctions(s, d_class);
-        else
-            writeObjectFunctions(s, d_class);
-
-        if (d_class->isPolymorphic())
-        {
-            s << "    static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl;
-
-            QString className = d_class->name();
-            if (d_class->isAbstract())
-                className += "_ConcreteWrapper";
-
-            s << "        auto obj = new(flags) " << className << "(nativeId, flags);" << endl;
-
-            if (d_class->isQObject())
-               s << "        qtd_" << d_class->name() << "_createEntity(nativeId, cast(void*)obj);" << endl;
-
-          s << "        return obj;" << endl
-            << "    }" << endl << endl;
-        }
-    }
-
-    if (d_class->hasPublicDestructor() && (!d_class->baseClass() || !d_class->hasVirtualFunctions()))
-        writeDestructor(s, d_class);
+    writeDestructor(s, d_class);
 
     // Add dummy constructor for use when constructing subclasses
     if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass) {
+
+        writeObjectFunctions(s, d_class);
+
         s << endl
           << INDENT << "public "
           << "this";
@@ -2485,21 +2448,19 @@
         s  << INDENT << "}" << endl << endl;
     }
 
-    if (d_class->isPolymorphic())
+
+    if (d_class->isPolymorphic() && d_class->polymorphicBase() == d_class)
     {
-        if (!d_class->typeEntry()->isQObject())
-        {
-            s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *q_ptr);" << endl << endl;
-            s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl;
-        }
-
-        s << "extern(C) void* qtd_" << d_class->name() << "_staticTypeId();" << endl;
+        s << "extern(C) void* qtd_" << d_class->name() << "_dId(void *nativeId);" << endl << endl;
+        s << "extern(C) void* qtd_" << d_class->name() << "_typeId(void* nativeId);" << endl;
     }
 
+    s << "extern(C) void* qtd_" << d_class->name() << "_staticTypeId();" << endl;
+
 //    if (d_class->needsConversionFunc)
 //        writeConversionFunction(s, d_class);
 
-    if (d_class->hasConstructors())
+    if (d_class->hasConstructors() && d_class->polymorphicBase() == d_class)
         s << "extern(C) void qtd_" << d_class->name() << "_destructor(void *ptr);" << endl << endl;
 
     // qtd
@@ -2558,10 +2519,8 @@
 
         s << "extern(C) void static_init_" << d_class->name() << "() {" << endl;
 
-        if (d_class->isPolymorphic()) {
-            s << INDENT << "if (!" << d_class->name() << "._staticMetaObject) " << endl
-            << INDENT << "    " << d_class->name() << ".createStaticMetaObject;" << endl << endl;
-        }
+          if (!d_class->isNamespace() && !d_class->isInterface() && !fakeClass)
+              s << "    " << d_class->name() << ".__createMetaObject;" << endl << endl;
 
         if (cpp_shared) {
              // virtual functions
@@ -2614,10 +2573,7 @@
 
 
     if (d_class->isQObject())
-    {
-      s << "private extern(C) void* qtd_" << d_class->name() << "_staticMetaObject();" << endl << endl
-        << "private extern(C) void qtd_" << d_class->name() << "_createEntity(void* nativeId, void* dId);" <<  endl << endl;
-    }
+        s << "private extern(C) void qtd_" << d_class->name() << "_createEntity(void* nativeId, void* dId);" <<  endl << endl;
 }
 
 /*
@@ -2657,6 +2613,7 @@
 }
 */
 
+/*
 void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
 {
     // polymorphic
@@ -2703,47 +2660,80 @@
         << "    }" << endl << endl;
     }
     else
-    {
-      s << "    static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
-        << "        return new " << d_class->name() << "(nativeId, flags);"
-        << "    }" << endl << endl;
+    {      
     }
 }
-
-void DGenerator::writeQObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
+*/
+
+void DGenerator::writeObjectFunctions(QTextStream &s, const AbstractMetaClass *d_class)
 {
     QString concreteArg;
     if (d_class->isAbstract())
         concreteArg += ", " + d_class->name() + "_ConcreteWrapper";
 
-  s << "    private static QMetaObject _staticMetaObject;" << endl
-    << "    protected static void createStaticMetaObject() {" << endl
-    << "        assert(!_staticMetaObject);" << endl
-    << "        QMetaObject base;" << endl;
-
-    if (d_class->name() != "QObject")
-    {
-        QString baseName = d_class->baseClassName();
-      s << "        if (!" << baseName << "._staticMetaObject)" << endl
-        << "            " << baseName << ".createStaticMetaObject;" << endl
-        << "        base = " << baseName << "._staticMetaObject;" << endl;
+    bool isQObject = d_class->isQObject();
+    QString moName = isQObject ? "QMetaObject" : "QtdMetaObject";
+
+    s << "    private static __gshared " << moName << " _staticMetaObject;" << endl
+      << "    static void __createMetaObject(){" << endl
+      << "        if (!_staticMetaObject){" << endl
+      << "            QtdMetaObjectBase base;" << endl
+      << "            static if (is(typeof(super.__createMetaObject))) {" << endl
+      << "                alias typeof(super) Base;" << endl
+      << "                Base.__createMetaObject();" << endl
+      << "                base = Base._staticMetaObject;" << endl
+      << "            }" << endl
+      << "            _staticMetaObject = new " << moName << "(qtd_" << d_class->name() << "_staticTypeId, base, &__createWrapper);" << endl
+      << "        }" << endl
+      << "    }" << endl << endl
+
+      << "    " << moName << " metaObject(){" << endl
+      << "        return _staticMetaObject;" << endl
+      << "    }" << endl << endl
+      << "    static " << moName << " staticMetaObject() {" << endl
+      << "        return _staticMetaObject;" << endl
+      << "    }" << endl << endl
+
+      << "    static QtdObjectBase __createWrapper(void* nativeId, QtdObjectFlags flags) {" << endl;
+
+    QString className = d_class->name();
+    if (d_class->isAbstract())
+        className += "_ConcreteWrapper";
+
+    s << "        auto obj = new(flags) " << className << "(nativeId, flags);" << endl;
+
+    if (d_class->isQObject())
+        s << "        qtd_" << d_class->name() << "_createEntity(nativeId, cast(void*)obj);" << endl;
+
+    s << "        return obj;" << endl
+      << "    }" << endl << endl;
+
+    if (!isQObject)
+    {        
+        if (d_class->isPolymorphic())
+        {
+            const AbstractMetaClass* polyBase = d_class->polymorphicBase();
+            s << "    static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
+              << "        auto obj = cast("  << d_class->name() << ") qtd_" << polyBase->name() << "_dId(nativeId);" << endl
+              << "        if (!obj)" << endl
+              << "            obj = static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, "
+                                "qtd_" << polyBase->name() << "_typeId(nativeId), flags));" << endl
+              << "        return obj;" << endl
+              << "    }" << endl << endl;
+        }
+        else
+        {
+            s << "    static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
+              << "        return new(flags) " << d_class->name() << "(nativeId, flags);" << endl
+              << "    }" << endl << endl;
+        }
     }
-
-  s << "        _staticMetaObject = new QMetaObject(qtd_" << d_class->name() << "_staticMetaObject, base);"   << endl
-    << "        _staticMetaObject.construct!(" << d_class->name() << concreteArg << ");" << endl
-    << "    }" << endl << endl
-
-    << "    QMetaObject metaObject() {" << endl
-    << "        return _staticMetaObject;" << endl
-    << "    }" << endl << endl
-
-    << "    static QMetaObject staticMetaObject() {" << endl
-    << "        return _staticMetaObject;" << endl
-    << "    }" << endl << endl
-
-    << "    static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
-    << "        return static_cast!(" << d_class->name() << ")(_staticMetaObject.wrap(nativeId, flags));" << endl
-    << "    }" << endl << endl;
+    else
+    {
+        s << "    static " << d_class->name() << " __wrap(void* nativeId, QtdObjectFlags flags = QtdObjectFlags.none) {" << endl
+          << "        return static_cast!" << d_class->name() << "(" << d_class->name() << "._staticMetaObject.wrap(nativeId, flags));" << endl
+          << "    }" << endl << endl;
+    }    
 }
 
 /*
@@ -2908,30 +2898,13 @@
                 {
                     bool resetAfterUse = !type->isQObject() && d_function->resetObjectAfterUse(argument->argumentIndex() + 1);
 
-                    if ((static_cast<const ComplexTypeEntry*>(type->typeEntry()))->isPolymorphic())
-                    {
-                        QString flags;
-                        if (resetAfterUse)
-                            flags = "QtdObjectFlags.stackAllocated | QtdObjectFlags.skipNativeDelete";
-                        else
-                            flags = "QtdObjectFlags.none";
-                        
-                        s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name
-                            << ", cast(QtdObjectFlags)(" << flags << "));" << endl;
-
-                        if (resetAfterUse)
-                        {
-                            s << INDENT << "scope(exit) {" << endl
-                              << INDENT << "    if (" << arg_name << "_d_ref.__flags & QtdObjectFlags.stackAllocated)" << endl
-                              << INDENT << "        delete " << arg_name << ";" << endl
-                              << INDENT << "}" << endl;
-                        }
-                    }
+
+                    if (resetAfterUse)
+                        s << INDENT << "auto " << arg_name << "_d_ref = scopeObject!(" << type->typeEntry()->name() << ")(" << arg_name << ");";
                     else
                     {
-                        s << INDENT << (resetAfterUse ? "scope " : "auto ")
-                          << arg_name << "_d_ref = new " << type->typeEntry()->name() << "(" << arg_name << ", QtdObjectFlags."
-                          << (resetAtferUse ? "skipNativeDelete" : "none") << ");" << endl;
+                        s << INDENT << "auto " << arg_name << "_d_ref = " << type->typeEntry()->name() << ".__wrap(" << arg_name
+                              << ");" << endl;                        
                     }
                 }
                 else
--- a/generator/typesystem.h	Tue Sep 22 15:22:37 2009 +0000
+++ b/generator/typesystem.h	Wed Dec 23 16:10:46 2009 +0200
@@ -912,7 +912,7 @@
     uint m_polymorphic_base : 1;
     uint m_generic_class : 1;
 
-    QString m_polymorphic_id_value;e
+    QString m_polymorphic_id_value;
     QString m_lookup_name;
     QString m_target_type;
     ExpensePolicy m_expense_policy;
--- a/generator/typesystem_core-java.java	Tue Sep 22 15:22:37 2009 +0000
+++ b/generator/typesystem_core-java.java	Wed Dec 23 16:10:46 2009 +0200
@@ -72,8 +72,8 @@
         }
     }
     */
-       
-    override void onSignalHandlerCreated(ref SignalHandler sh)
+
+    void onSignalHandlerCreated(ref SignalHandler sh)
     {
         sh.signalEvent = &onSignalEvent;
     }
@@ -135,7 +135,7 @@
         
         find(children);
         return result;
-    }  
+    }
 }// class
 
 abstract class QAbstractItemModel___ extends QAbstractItemModel {
--- a/generator/typesystem_core.xml	Tue Sep 22 15:22:37 2009 +0000
+++ b/generator/typesystem_core.xml	Wed Dec 23 16:10:46 2009 +0200
@@ -2374,7 +2374,7 @@
 	new QtD_QObjectEntity((QObject*)nativeId, dId);
 }
 
-extern "C" DLL_PUBLIC void* qtd_QObject_metaObject(void* nativeId)
+extern "C" DLL_PUBLIC void* qtd_QObject_typeId(void* nativeId)
 {
     return (void*)((QObject*)nativeId)->metaObject();
 }
@@ -2402,10 +2402,8 @@
 	<inject-code class="java-free">
 extern(C) void* qtd_get_d_qobject(void* nativeId);
 extern(C) void* qtd_create_qobject_entity(void* nativeId, void* dId);
-extern(C) void* qtd_QObject_metaObject(void* nativeId);
 extern(C) void qtd_connect(void *nativeId, cstringz signal, int id, bool hasDId);
 extern(C) void qtd_disconnect(void *nativeId, cstringz signal, int id, bool hasDId);
-
 	</inject-code>
 
     <modify-function signature="childEvent(QChildEvent*)">
--- a/mini/test1/build	Tue Sep 22 15:22:37 2009 +0000
+++ b/mini/test1/build	Wed Dec 23 16:10:46 2009 +0200
@@ -1,3 +1,3 @@
 #! /bin/bash
 
-dmd main.d -gc -debug -debug=QtdVerbose -L-L../../output/build/lib -L-lqtdcore -I../../output/build -I../../ -I../../qt/d1 -L-lQtCore -L-lQtGui
\ No newline at end of file
+dmd main.d -gc -debug -debug=QtdVerbose -L-L../../output/build/lib -L-lqtdcore -L-lqtdgui -I../../output/build -I../../ -I../../qt/d1 -L-lQtCore -L-lQtGui
\ No newline at end of file