changeset 282:256ab6cb8e85

Signals look-up andNew syntax for connect. The old one will not work from now on. This will allow for the signals overload. Although changes are done for both D1 and D2 versions, D1 won't work because of compiler bugs. I am tired of waiting for fixes.
author eldar
date Fri, 16 Oct 2009 02:43:59 +0000
parents 7f2e3ffa1c33
children b61a413fc2f5
files CMakeLists.txt examples/desktop/screenshot/screenshot.d examples/desktop/systray/window.d examples/dialogs/classwizard/classwizard.d examples/dialogs/classwizard/classwizard_d1.d examples/dialogs/standarddialogs/dialog.d examples/dialogs/standarddialogs/dialog_d1.d examples/draganddrop/dropsite/dropsitewindow.d examples/draganddrop/dropsite/dropsitewindow_d1.d examples/itemviews/customsortfiltermodel/window.d examples/layouts/basiclayouts/dialog.d examples/layouts/dynamiclayouts/dialog.d examples/mainwindows/dockwidgets/mainwindow.d examples/mainwindows/sdi/mainwindow.d examples/opengl/hellogl/window.d examples/tutorials/tutorial/t2/main.d examples/tutorials/tutorial/t3/main.d examples/tutorials/tutorial/t4/main.d examples/tutorials/tutorial/t5/main.d examples/tutorials/tutorial/t6/main.d examples/widgets/analogclock/AnalogClock.d examples/widgets/calculator/calculator.d examples/widgets/calculator/calculator_d1.d qt/d1/qt/Signal.d qt/d2/qt/Signal.d
diffstat 25 files changed, 402 insertions(+), 285 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sun Oct 11 05:23:41 2009 +0000
+++ b/CMakeLists.txt	Fri Oct 16 02:43:59 2009 +0000
@@ -49,9 +49,9 @@
 
 # Check D compiler version
 if(D_VERSION EQUAL "1")
-    if (D_FRONTEND LESS "041")
-	message(STATUS "Minimum required version of D compiler is 1.041 (or compiler based on this version)")
-    endif(D_FRONTEND LESS "041")
+    if (D_FRONTEND LESS "050")
+	message(STATUS "Minimum required version of D compiler is 1.050 (or compiler based on this version)")
+    endif(D_FRONTEND LESS "050")
     set(D_TARGET d1-tango CACHE INTERNAL "")   
 elseif(D_VERSION EQUAL "2")
     set(D_TARGET d2-phobos CACHE INTERNAL "")
--- a/examples/desktop/screenshot/screenshot.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/desktop/screenshot/screenshot.d	Fri Oct 16 02:43:59 2009 +0000
@@ -153,7 +153,7 @@
 		delaySpinBox = new QSpinBox;
 		delaySpinBox.setSuffix(tr(" s"));
 		delaySpinBox.setMaximum(60);
-		delaySpinBox.valueChanged.connect(&this.updateCheckBox);
+		connect!("valueChanged")(delaySpinBox, &this.updateCheckBox);
 		
 		delaySpinBoxLabel = new QLabel(tr("Screenshot Delay:"));
 
@@ -184,7 +184,7 @@
 	QPushButton createButton(string text, void delegate() slot)
 	{
 		QPushButton button = new QPushButton(text);
-		button.clicked.connect(slot);
+		connect!("clicked")(button, slot);
 		return button;
 	}
 
--- a/examples/desktop/systray/window.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/desktop/systray/window.d	Fri Oct 16 02:43:59 2009 +0000
@@ -72,11 +72,11 @@
 		createActions();
 		createTrayIcon();
 
-		showMessageButton.clicked.connect(&this.showMessage);
-		showIconCheckBox.toggled.connect(&trayIcon.setVisible);
-		iconComboBox.currentIndexChanged.connect(&this.setIcon);
-		trayIcon.messageClicked.connect(&this.messageClicked);
-		trayIcon.activated.connect(&this.iconActivated);
+		connect!("clicked")(showMessageButton, &this.showMessage);
+		connect!("toggled")(showIconCheckBox, &trayIcon.setVisible);
+		connect!("currentIndexChanged")(iconComboBox, &this.setIcon);
+		connect!("messageClicked")(trayIcon, &this.messageClicked);
+		connect!("activated")(trayIcon, &this.iconActivated);
 
 		QVBoxLayout mainLayout = new QVBoxLayout;
 		mainLayout.addWidget(iconGroupBox);
@@ -233,16 +233,16 @@
 	void createActions()
 	{
 		minimizeAction = new QAction(tr("Mi&nimize"), this);
-		minimizeAction.triggered.connect(&this.hide);
+		connect!("triggered")(minimizeAction, &this.hide);
 
 		maximizeAction = new QAction(tr("Ma&ximize"), this);
-		maximizeAction.triggered.connect(&this.showMaximized);
+		connect!("triggered")(maximizeAction, &this.showMaximized);
 
 		restoreAction = new QAction(tr("&Restore"), this);
-		restoreAction.triggered.connect(&this.showNormal);
+		connect!("triggered")(restoreAction, &this.showNormal);
 
 		quitAction = new QAction(tr("&Quit"), this);
-		quitAction.triggered.connect(&QApplication.quit);
+		connect!("triggered")(quitAction, &QApplication.quit);
 	}
 
 	void createTrayIcon()
--- a/examples/dialogs/classwizard/classwizard.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/dialogs/classwizard/classwizard.d	Fri Oct 16 02:43:59 2009 +0000
@@ -263,7 +263,7 @@
 		copyCtorCheckBox = new QCheckBox(tr("&Generate copy constructor and operator="));
 
 		defaultCtorRadioButton.setChecked(true);
-		defaultCtorRadioButton.toggled.connect(&copyCtorCheckBox.setEnabled);
+		connect!("toggled")(defaultCtorRadioButton, &copyCtorCheckBox.setEnabled);
 
 		registerField("className*", classNameLineEdit);
 		registerField("baseClass", baseClassLineEdit);
@@ -331,10 +331,10 @@
 		baseIncludeLineEdit = new QLineEdit;
 		baseIncludeLabel.setBuddy(baseIncludeLineEdit);
 
-		protectCheckBox.toggled.connect(&macroNameLabel.setEnabled);
-		protectCheckBox.toggled.connect(&macroNameLabel.setEnabled);
-		includeBaseCheckBox.toggled.connect(&macroNameLabel.setEnabled);
-		includeBaseCheckBox.toggled.connect(&macroNameLabel.setEnabled);
+		connect!("toggled")(protectCheckBox, &macroNameLabel.setEnabled);
+// ?	connect!("toggled")(protectCheckBox, &macroNameLabel.setEnabled);
+		connect!("toggled")(includeBaseCheckBox, &macroNameLabel.setEnabled);
+// ?	connect!("toggled")(includeBaseCheckBox, &macroNameLabel.setEnabled);
 
 		registerField("comment", commentCheckBox);
 		registerField("protect", protectCheckBox);
--- a/examples/dialogs/classwizard/classwizard_d1.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/dialogs/classwizard/classwizard_d1.d	Fri Oct 16 02:43:59 2009 +0000
@@ -264,7 +264,7 @@
 		copyCtorCheckBox = new QCheckBox(tr("&Generate copy constructor and operator="));
 
 		defaultCtorRadioButton.setChecked(true);
-		defaultCtorRadioButton.toggled.connect(&copyCtorCheckBox.setEnabled);
+        connect!("toggled")(defaultCtorRadioButton, &copyCtorCheckBox.setEnabled);
 
 		registerField("className*", classNameLineEdit);
 		registerField("baseClass", baseClassLineEdit);
@@ -332,10 +332,10 @@
 		baseIncludeLineEdit = new QLineEdit;
 		baseIncludeLabel.setBuddy(baseIncludeLineEdit);
 
-		protectCheckBox.toggled.connect(&macroNameLabel.setEnabled);
-		protectCheckBox.toggled.connect(&macroNameLabel.setEnabled);
-		includeBaseCheckBox.toggled.connect(&macroNameLabel.setEnabled);
-		includeBaseCheckBox.toggled.connect(&macroNameLabel.setEnabled);
+        connect!("toggled")(protectCheckBox, &macroNameLabel.setEnabled);
+// ?    connect!("toggled")(protectCheckBox, &macroNameLabel.setEnabled);
+        connect!("toggled")(includeBaseCheckBox, &macroNameLabel.setEnabled);
+// ?    connect!("toggled")(includeBaseCheckBox, &macroNameLabel.setEnabled);
 
 		registerField("comment", commentCheckBox);
 		registerField("protect", protectCheckBox);
--- a/examples/dialogs/standarddialogs/dialog.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/dialogs/standarddialogs/dialog.d	Fri Oct 16 02:43:59 2009 +0000
@@ -135,21 +135,21 @@
 		errorLabel.setFrameStyle(frameStyle);
 		QPushButton errorButton = new QPushButton(tr("QErrorMessage.show&M&essage()"));
 
-		integerButton.clicked.connect(&this.setInteger);
-		doubleButton.clicked.connect(&this.setDouble);
-		itemButton.clicked.connect(&this.setItem);
-		textButton.clicked.connect(&this.setText);
-		colorButton.clicked.connect(&this.setColor);
-		fontButton.clicked.connect(&this.setFont);
-		directoryButton.clicked.connect(&this.setExistingDirectory);
-		openFileNameButton.clicked.connect(&this.setOpenFileName);
-		openFileNamesButton.clicked.connect(&this.setOpenFileNames);
-		saveFileNameButton.clicked.connect(&this.setSaveFileName);
-		criticalButton.clicked.connect(&this.criticalMessage);
-		informationButton.clicked.connect(&this.informationMessage);
-		questionButton.clicked.connect(&this.questionMessage);
-		warningButton.clicked.connect(&this.warningMessage);
-		errorButton.clicked.connect(&this.errorMessage);
+		connect!("clicked")(integerButton, &this.setInteger);
+		connect!("clicked")(doubleButton, &this.setDouble);
+		connect!("clicked")(itemButton, &this.setItem);
+		connect!("clicked")(textButton, &this.setText);
+		connect!("clicked")(colorButton, &this.setColor);
+		connect!("clicked")(fontButton, &this.setFont);
+		connect!("clicked")(directoryButton, &this.setExistingDirectory);
+		connect!("clicked")(openFileNameButton, &this.setOpenFileName);
+		connect!("clicked")(openFileNamesButton, &this.setOpenFileNames);
+		connect!("clicked")(saveFileNameButton, &this.setSaveFileName);
+		connect!("clicked")(criticalButton, &this.criticalMessage);
+		connect!("clicked")(informationButton, &this.informationMessage);
+		connect!("clicked")(questionButton, &this.questionMessage);
+		connect!("clicked")(warningButton, &this.warningMessage);
+		connect!("clicked")(errorButton, &this.errorMessage);
 
 		native = new QCheckBox(this);
 		native.setText("Use native file dialog.");
--- a/examples/dialogs/standarddialogs/dialog_d1.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/dialogs/standarddialogs/dialog_d1.d	Fri Oct 16 02:43:59 2009 +0000
@@ -135,21 +135,21 @@
 		errorLabel.setFrameStyle(frameStyle);
 		QPushButton errorButton = new QPushButton(tr("QErrorMessage.show&M&essage()"));
 
-		integerButton.clicked.connect(&this.setInteger);
-		doubleButton.clicked.connect(&this.setDouble);
-		itemButton.clicked.connect(&this.setItem);
-		textButton.clicked.connect(&this.setText);
-		colorButton.clicked.connect(&this.setColor);
-		fontButton.clicked.connect(&this.setFont);
-		directoryButton.clicked.connect(&this.setExistingDirectory);
-		openFileNameButton.clicked.connect(&this.setOpenFileName);
-		openFileNamesButton.clicked.connect(&this.setOpenFileNames);
-		saveFileNameButton.clicked.connect(&this.setSaveFileName);
-		criticalButton.clicked.connect(&this.criticalMessage);
-		informationButton.clicked.connect(&this.informationMessage);
-		questionButton.clicked.connect(&this.questionMessage);
-		warningButton.clicked.connect(&this.warningMessage);
-		errorButton.clicked.connect(&this.errorMessage);
+        connect!("clicked")(integerButton, &this.setInteger);
+        connect!("clicked")(doubleButton, &this.setDouble);
+        connect!("clicked")(itemButton, &this.setItem);
+        connect!("clicked")(textButton, &this.setText);
+        connect!("clicked")(colorButton, &this.setColor);
+        connect!("clicked")(fontButton, &this.setFont);
+        connect!("clicked")(directoryButton, &this.setExistingDirectory);
+        connect!("clicked")(openFileNameButton, &this.setOpenFileName);
+        connect!("clicked")(openFileNamesButton, &this.setOpenFileNames);
+        connect!("clicked")(saveFileNameButton, &this.setSaveFileName);
+        connect!("clicked")(criticalButton, &this.criticalMessage);
+        connect!("clicked")(informationButton, &this.informationMessage);
+        connect!("clicked")(questionButton, &this.questionMessage);
+        connect!("clicked")(warningButton, &this.warningMessage);
+        connect!("clicked")(errorButton, &this.errorMessage);
 
 		native = new QCheckBox(this);
 		native.setText("Use native file dialog.");
--- a/examples/draganddrop/dropsite/dropsitewindow.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/draganddrop/dropsite/dropsitewindow.d	Fri Oct 16 02:43:59 2009 +0000
@@ -67,7 +67,7 @@
 		abstractLabel.adjustSize();
 
 		dropArea = new DropArea;
-		dropArea.changed.connect(&updateFormatsTable);
+		connect!("changed")(dropArea, &updateFormatsTable);
 
 		string[] labels;
 		labels ~= tr("Format");
@@ -86,8 +86,8 @@
 		buttonBox.addButton(clearButton, QDialogButtonBox.ActionRole);
 		buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole);
 
-		quitButton.pressed.connect(&close);
-		clearButton.pressed.connect(&dropArea.clearArea);
+		connect!("pressed")(quitButton, &close);
+		connect!("pressed")(clearButton, &dropArea.clearArea);
 
 		QVBoxLayout mainLayout = new QVBoxLayout;
 		mainLayout.addWidget(abstractLabel);
--- a/examples/draganddrop/dropsite/dropsitewindow_d1.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/draganddrop/dropsite/dropsitewindow_d1.d	Fri Oct 16 02:43:59 2009 +0000
@@ -69,7 +69,7 @@
 		abstractLabel.adjustSize();
 
 		dropArea = new DropArea;
-		dropArea.changed.connect(&updateFormatsTable);
+        connect!("changed")(dropArea, &updateFormatsTable);
 
 		string[] labels;
 		labels ~= tr("Format");
@@ -88,8 +88,8 @@
 		buttonBox.addButton(clearButton, QDialogButtonBox.ActionRole);
 		buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole);
 
-		quitButton.pressed.connect(&close);
-		clearButton.pressed.connect(&dropArea.clearArea);
+        connect!("pressed")(quitButton, &close);
+        connect!("pressed")(clearButton, &dropArea.clearArea);
 
 		QVBoxLayout mainLayout = new QVBoxLayout;
 		mainLayout.addWidget(abstractLabel);
--- a/examples/itemviews/customsortfiltermodel/window.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/itemviews/customsortfiltermodel/window.d	Fri Oct 16 02:43:59 2009 +0000
@@ -102,11 +102,11 @@
 		toLabel = new QLabel(tr("&To:"));
 		toLabel.setBuddy(toDateEdit);
 
-		filterPatternLineEdit.textChanged.connect(&this.textFilterChanged);
-		filterSyntaxComboBox.currentIndexChanged.connect(&this.textFilterChanged);
-		filterCaseSensitivityCheckBox.toggled.connect(&this.textFilterChanged);
-		fromDateEdit.dateChanged.connect(&this.dateFilterChanged);
-		toDateEdit.dateChanged.connect(&this.dateFilterChanged);
+		connect!("textChanged")(filterPatternLineEdit, &this.textFilterChanged);
+		connect!("currentIndexChanged")(filterSyntaxComboBox, &this.textFilterChanged);
+		connect!("toggled")(filterCaseSensitivityCheckBox, &this.textFilterChanged);
+		connect!("dateChanged")(fromDateEdit, &this.dateFilterChanged);
+		connect!("dateChanged")(toDateEdit, &this.dateFilterChanged);
 
 		proxyView = new QTreeView;
 		proxyView.setRootIsDecorated(false);
--- a/examples/layouts/basiclayouts/dialog.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/layouts/basiclayouts/dialog.d	Fri Oct 16 02:43:59 2009 +0000
@@ -75,8 +75,8 @@
 
         buttonBox = new QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel);
 
-        buttonBox.accepted.connect(&this.accept);
-        buttonBox.rejected.connect(&this.reject);
+        connect!("accepted")(buttonBox, &this.accept);
+        connect!("rejected")(buttonBox, &this.reject);
 
         QVBoxLayout mainLayout = new QVBoxLayout;
 
@@ -101,7 +101,7 @@
         exitAction = fileMenu.addAction(tr("E&xit"));
         menuBar.addMenu(fileMenu);
 
-        exitAction.triggered.connect(&this.accept);
+        connect!("triggered")(exitAction, &this.accept);
     }
 
     void createHorizontalGroupBox()
--- a/examples/layouts/dynamiclayouts/dialog.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/layouts/dynamiclayouts/dialog.d	Fri Oct 16 02:43:59 2009 +0000
@@ -145,10 +145,10 @@
 		rotableWidgets ~= a2;
 		rotableWidgets ~= a3;
 
-		a0.valueChanged.connect(&a1.setValue);
-		a1.valueChanged.connect(&a2.setValue);
-		a2.valueChanged.connect(&a3.setValue);
-		a3.valueChanged.connect(&a0.setValue);
+		connect!("valueChanged")(a0, &a1.setValue);
+		connect!("valueChanged")(a1, &a2.setValue);
+		connect!("valueChanged")(a2, &a3.setValue);
+		connect!("valueChanged")(a3, &a0.setValue);
 
 		/*
 		int n = rotableWidgets.length;
@@ -172,7 +172,7 @@
 		buttonsOrientationComboBox.addItem(tr("Horizontal"), new QVariant(cast(ulong) Qt.Horizontal));
 		buttonsOrientationComboBox.addItem(tr("Vertical"), new QVariant(cast(ulong) Qt.Vertical));
 
-		buttonsOrientationComboBox.currentIndexChanged.connect(&this.buttonsOrientationChanged);
+		connect!("currentIndexChanged")(buttonsOrientationComboBox, &this.buttonsOrientationChanged);
 
 		optionsLayout = new QGridLayout;
 		optionsLayout.addWidget(buttonsOrientationLabel, 0, 0);
@@ -189,9 +189,9 @@
 		helpButton = buttonBox.addButton(QDialogButtonBox.Help);
 		rotateWidgetsButton = buttonBox.addButton(tr("Rotate &Widgets"), QDialogButtonBox.ActionRole);
 
-		rotateWidgetsButton.clicked.connect(&this.rotateWidgets);
-		closeButton.clicked.connect(&this.close);
-		helpButton.clicked.connect(&this.help);
+		connect!("clicked")(rotateWidgetsButton, &this.rotateWidgets);
+		connect!("clicked")(closeButton, &this.close);
+		connect!("clicked")(helpButton, &this.help);
 	}
 
 	QGroupBox rotableGroupBox;
--- a/examples/mainwindows/dockwidgets/mainwindow.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/mainwindows/dockwidgets/mainwindow.d	Fri Oct 16 02:43:59 2009 +0000
@@ -214,7 +214,7 @@
             newLetterAct = new QAction(new QIcon(":images/new.png"), tr("&New Letter"), this);
             newLetterAct.setShortcut(tr("Ctrl+N"));
             newLetterAct.setStatusTip(tr("Create a new form letter"));
-            newLetterAct.triggered.connect(&this.newLetter);
+            connect!("triggered")(newLetterAct, &this.newLetter);
 
             saveAct = new QAction(new QIcon(":images/save.png"), tr("&Save..."), this);
             saveAct.setShortcut(tr("Ctrl+S"));
@@ -229,16 +229,16 @@
             undoAct = new QAction(new QIcon(":images/undo.png"), tr("&Undo"), this);
             undoAct.setShortcut(tr("Ctrl+Z"));
             undoAct.setStatusTip(tr("Undo the last editing action"));
-            undoAct.triggered.connect(&undo);
+            connect!("triggered")(undoAct, &undo);
 
             quitAct = new QAction(tr("&Quit"), this);
             quitAct.setShortcut(tr("Ctrl+Q"));
             quitAct.setStatusTip(tr("Quit the application"));
-            quitAct.triggered.connect(&this.close);
+            connect!("triggered")(quitAct, &this.close);
 
             aboutAct = new QAction(tr("&About"), this);
             aboutAct.setStatusTip(tr("Show the application's About box"));
-            aboutAct.triggered.connect(&about);
+            connect!("triggered")(aboutAct, &about);
 
             aboutQtAct = new QAction(tr("About &Qt"), this);
             aboutQtAct.setStatusTip(tr("Show the Qt library's About box"));
@@ -327,8 +327,8 @@
             addDockWidget(Qt.RightDockWidgetArea, dock);
             viewMenu.addAction(dock.toggleViewAction());
 
-            customerList.currentTextChanged.connect(&this.insertCustomer);
-            paragraphsList.currentTextChanged.connect(&this.addParagraph);
+            connect!("currentTextChanged")(customerList, &this.insertCustomer);
+            connect!("currentTextChanged")(paragraphsList, &this.addParagraph);
         }
 
         QTextEdit textEdit;
--- a/examples/mainwindows/sdi/mainwindow.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/mainwindows/sdi/mainwindow.d	Fri Oct 16 02:43:59 2009 +0000
@@ -180,7 +180,7 @@
 
     readSettings();
 
-    textEdit.document().contentsChanged.connect(&this.documentWasModified);
+    connect!("contentsChanged")(textEdit.document(), &this.documentWasModified);
 
     setUnifiedTitleAndToolBarOnMac(true);
   }
@@ -190,67 +190,64 @@
     newAct = new QAction(new QIcon(":/images/new.png"), tr("&New"), this);
     newAct.setShortcuts(QKeySequence.New);
     newAct.setStatusTip(tr("Create a new file"));
-    newAct.triggered.connect(&this.newFile);
+    connect!("triggered")(newAct, &this.newFile);
 
     openAct = new QAction(new QIcon(":/images/open.png"), tr("&Open..."), this);
     openAct.setShortcuts(QKeySequence.Open);
     openAct.setStatusTip(tr("Open an existing file"));
-    openAct.triggered.connect(&this.open);
+    connect!("triggered")(openAct, &this.open);
 
     saveAct = new QAction(new QIcon(":/images/save.png"), tr("&Save"), this);
     saveAct.setShortcuts(QKeySequence.Save);
     saveAct.setStatusTip(tr("Save the document to disk"));
-    saveAct.triggered.connect(&this.save);
+    connect!("triggered")(saveAct, &this.save);
 
     saveAsAct = new QAction(tr("Save &As..."), this);
     saveAsAct.setShortcuts(QKeySequence.SaveAs);
     saveAsAct.setStatusTip(tr("Save the document under a new name"));
-    saveAsAct.triggered.connect(&this.saveAs);
+    connect!("triggered")(saveAsAct, &this.saveAs);
 
     closeAct = new QAction(tr("&Close"), this);
     closeAct.setShortcut(tr("Ctrl+W"));
     closeAct.setStatusTip(tr("Close this window"));
-    closeAct.triggered.connect(&this.close);
+    connect!("triggered")(closeAct, &this.close);
 
     exitAct = new QAction(tr("E&xit"), this);
     exitAct.setShortcut(tr("Ctrl+Q"));
     exitAct.setStatusTip(tr("Exit the application"));
-    exitAct.triggered.connect(&QApplication.closeAllWindows);
+    connect!("triggered")(exitAct, &QApplication.closeAllWindows);
 
     cutAct = new QAction(new QIcon(":/images/cut.png"), tr("Cu&t"), this);
     cutAct.setShortcuts(QKeySequence.Cut);
     cutAct.setStatusTip(tr("Cut the current selection's contents to the " ~
                            "clipboard"));
-    cutAct.triggered.connect(&textEdit.cut);
+    connect!("triggered")(cutAct, &textEdit.cut);
 
     copyAct = new QAction(new QIcon(":/images/copy.png"), tr("&Copy"), this);
     copyAct.setShortcuts(QKeySequence.Copy);
     copyAct.setStatusTip(tr("Copy the current selection's contents to the " ~
                             "clipboard"));
-    copyAct.triggered.connect(&textEdit.copy);
+    connect!("triggered")(copyAct, &textEdit.copy);
 
     pasteAct = new QAction(new QIcon(":/images/paste.png"), tr("&Paste"), this);
     pasteAct.setShortcuts(QKeySequence.Paste);
     pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current " ~
                              "selection"));
-    pasteAct.triggered.connect(&textEdit.paste);
+    connect!("triggered")(pasteAct, &textEdit.paste);
 
     aboutAct = new QAction(tr("&About"), this);
     aboutAct.setStatusTip(tr("Show the application's About box"));
-    aboutAct.triggered.connect(&this.about);
+    connect!("triggered")(aboutAct, &this.about);
 
     aboutQtAct = new QAction(tr("About &Qt"), this);
     aboutQtAct.setStatusTip(tr("Show the Qt library's About box"));
-    aboutQtAct.triggered.connect(&QApplication.aboutQt);
+    connect!("triggered")(aboutQtAct, &QApplication.aboutQt);
 
     cutAct.setEnabled(false);
     copyAct.setEnabled(false);
 
-    // QtD bug????
-    // only one of the following statements can be included
-    // otherwise the app crashes when a MainWindow is closeda
-    textEdit.copyAvailable.connect(&cutAct.setEnabled);
-    textEdit.copyAvailable.connect(&copyAct.setEnabled);
+    connect!("copyAvailable")(textEdit, &cutAct.setEnabled);
+    connect!("copyAvailable")(textEdit, &copyAct.setEnabled);
   }
 
   void createMenus()
--- a/examples/opengl/hellogl/window.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/opengl/hellogl/window.d	Fri Oct 16 02:43:59 2009 +0000
@@ -57,12 +57,12 @@
 			ySlider = createSlider();
 			zSlider = createSlider();
 			
-            xSlider.valueChanged.connect(&glWidget.setXRotation);
-            glWidget.xRotationChanged.connect(&xSlider.setValue);
-            ySlider.valueChanged.connect(&glWidget.setYRotation);
-            glWidget.yRotationChanged.connect(&ySlider.setValue);
-            zSlider.valueChanged.connect(&glWidget.setZRotation);
-            glWidget.zRotationChanged.connect(&zSlider.setValue);
+            connect!("valueChanged")(xSlider, &glWidget.setXRotation);
+            connect!("xRotationChanged")(glWidget, &xSlider.setValue);
+            connect!("valueChanged")(ySlider, &glWidget.setYRotation);
+            connect!("yRotationChanged")(glWidget, &ySlider.setValue);
+            connect!("valueChanged")(zSlider,&glWidget.setZRotation);
+            connect!("zRotationChanged")(glWidget, &zSlider.setValue);
 			
 			QHBoxLayout mainLayout = new QHBoxLayout;
 			mainLayout.addWidget(glWidget);
--- a/examples/tutorials/tutorial/t2/main.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/tutorials/tutorial/t2/main.d	Fri Oct 16 02:43:59 2009 +0000
@@ -47,7 +47,7 @@
 
     quit.resize(75, 30);
     quit.setFont(new QFont("Times", 18, QFont.Bold));
-    quit.clicked.connect(&QApplication.quit);
+    QObject.connect!("clicked")(quit, &QApplication.quit);
 
     quit.show();
     return app.exec();
--- a/examples/tutorials/tutorial/t3/main.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/tutorials/tutorial/t3/main.d	Fri Oct 16 02:43:59 2009 +0000
@@ -51,7 +51,7 @@
     quit.setFont(new QFont("Times", 18, QFont.Light));
     quit.setGeometry(10, 40, 180, 40);
 
-    quit.clicked.connect(&QApplication.quit);
+    QObject.connect!("clicked")(quit, &QApplication.quit);
 
     window.show();
     return app.exec();
--- a/examples/tutorials/tutorial/t4/main.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/tutorials/tutorial/t4/main.d	Fri Oct 16 02:43:59 2009 +0000
@@ -51,7 +51,7 @@
 		auto quit = new QPushButton("Quit", this);
 		quit.setGeometry(62, 40, 75, 30);
 		quit.setFont(new QFont("Times", 18, QFont.Bold));
-		quit.clicked.connect(&QApplication.quit);
+		connect!("clicked")(quit, &QApplication.quit);
 	}
 }
 
--- a/examples/tutorials/tutorial/t5/main.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/tutorials/tutorial/t5/main.d	Fri Oct 16 02:43:59 2009 +0000
@@ -60,8 +60,8 @@
         slider.setRange(0, 99);
         slider.setValue(0);
 
-        quit.clicked.connect(&QApplication.quit);
-        slider.valueChanged.connect(cast(void delegate(int)) &lcd.display);
+        connect!("clicked")(quit, &QApplication.quit);
+        connect!("valueChanged")(slider, cast(void delegate(int)) &lcd.display);
 
         auto layout = new QVBoxLayout;
         layout.addWidget(quit);
--- a/examples/tutorials/tutorial/t6/main.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/tutorials/tutorial/t6/main.d	Fri Oct 16 02:43:59 2009 +0000
@@ -58,7 +58,7 @@
 		auto slider = new QSlider(Qt.Horizontal);
 		slider.setRange(0, 99);
 		slider.setValue(0);
-        slider.valueChanged.connect(cast(void delegate(int)) &lcd.display);
+        connect!("valueChanged")(slider, cast(void delegate(int)) &lcd.display);
 
 		auto layout = new QVBoxLayout;
 		layout.addWidget(lcd);
@@ -76,7 +76,7 @@
 		
 		auto quit = new QPushButton("Quit");
 		quit.setFont(new QFont("Times", 18, QFont.Bold));
-        quit.clicked.connect(&QApplication.quit);
+        connect!("clicked")(quit, &QApplication.quit);
 
 		auto grid = new QGridLayout;
 		for (int row = 0; row < 3; ++row) {
--- a/examples/widgets/analogclock/AnalogClock.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/widgets/analogclock/AnalogClock.d	Fri Oct 16 02:43:59 2009 +0000
@@ -55,7 +55,7 @@
     {
         super(parent);
         auto timer = new QTimer(this);
-        timer.timeout.connect(&this.update);
+        connect!("timeout")(timer, &this.update);
         timer.start(1000);
         setWindowTitle("Analog Clock");
         resize(200, 200);
--- a/examples/widgets/calculator/calculator.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/widgets/calculator/calculator.d	Fri Oct 16 02:43:59 2009 +0000
@@ -346,7 +346,7 @@
         Button createButton(string text, void delegate() member)
         {
                 Button button = new Button(text);
-                button.clicked.connect(member);
+                connect!("clicked")(button, member);
                 return button;
         }
 
--- a/examples/widgets/calculator/calculator_d1.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/examples/widgets/calculator/calculator_d1.d	Fri Oct 16 02:43:59 2009 +0000
@@ -348,7 +348,7 @@
         Button createButton(string text, void delegate() member)
         {
                 Button button = new Button(text);
-                button.clicked.connect(member);
+                connect!("clicked")(button, member);
                 return button;
         }
 
--- a/qt/d1/qt/Signal.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/qt/d1/qt/Signal.d	Fri Oct 16 02:43:59 2009 +0000
@@ -858,25 +858,6 @@
     }
 }
 
-template CheckSlot(Slot, A...)
-{
-    static assert(ParameterTupleOf!(Slot).length <= A.length, "Slot " ~ ParameterTypeTuple!(Slot).stringof ~
-        " has more prameters than signal " ~ A.stringof);
-    alias CheckSlotImpl!(Slot, 0, A) check;
-}
-
-template CheckSlotImpl(Slot, int i, A...)
-{
-    alias ParameterTupleOf!(Slot) SlotArgs;
-    static if (i < SlotArgs.length)
-    {
-        static assert (is(SlotArgs[i] : A[i]), "Argument " ~ __toString(i) ~
-            ":" ~ A[i].stringof ~ " of signal " ~ A.stringof ~ " is not implicitly convertible to parameter "
-            ~ SlotArgs[i].stringof ~ " of slot " ~ SlotArgs.stringof);
-        alias CheckSlotImpl!(Slot, i + 1, A) next;
-    }
-}
-
 public template SignalHandlerOps()
 {
     static assert (is(typeof(this.signalHandler)),
@@ -910,56 +891,83 @@
         signalHandler.unblockSignals();
     }
     
-    void connect(string signalName, T, R, B...)(T sender, R function(B) dg, ConnectionFlags flags = ConnectionFlags.None)
+    template connect(string signalName, A...)
     {
-        alias findSymbol!(SignalQualifier, T, signalName) sig;
-        alias CheckSlot!(typeof(fn), sig[2].at) check;
-        auto sh = sender.signalHandler();
-        auto invoker = Dg(&sh.invokeSlot!(typeof(fn), Fn, sig[2].at));
-        sh.connect(sig[1], Fn(fn), invoker, flags);
+        static void connect(T, Func)(T sender, Func func, ConnectionFlags flags = ConnectionFlags.None)
+        {
+            static if (isFnOrDg!(Func)) // D1 has no constraints
+        {
+            alias findSignal!(T, signalName, Func, A).result sig;
+            auto sh = sender.signalHandler();
+            static if (isFn!(Func))
+                alias Fn Callable;
+            else
+                alias Dg Callable;
+            auto invoker = Dg(&sh.invokeSlot!(typeof(func), Callable, sig[2..$]));
+            sh.connect(sig[1], Callable(func), invoker, flags);
+        }
+        else
+        {
+            static assert(false, "The slot must be a function or delegate type.");
+        }
+        }
     }
 
-    void connect(string signalName, T, R, B...)(T sender, R delegate(B) dg, ConnectionFlags flags = ConnectionFlags.None)
+    template disconnect(string signalName, A...)
     {
-        alias findSymbol!(SignalQualifier, T, signalName) sig;
-        alias CheckSlot!(typeof(dg), sig[2].at) check;
-        auto sh = sender.signalHandler();
-        auto invoker = Dg(&sh.invokeSlot!(typeof(dg), Dg, sig[2].at));
-        sh.connect(sig[1], Dg(dg), invoker, flags);
+        static void connect(T, Func)(T sender, Func func, ConnectionFlags flags = ConnectionFlags.None)
+        {
+            static if (isFnOrDg!(Func)) // D1 has no constraints
+        {
+            alias findSignal!(T, signalName, Func, A).result sig;
+            auto sh = sender.signalHandler();
+            static if (isFn!(Func))
+                alias Fn Callable;
+            else
+                alias Dg Callable;
+            sh.disconnect(sig[1], Callable(func));
+        }
+        else
+        {
+            static assert(false, "The slot must be a function or delegate type.");
+        }
+        }
     }
-
-    void disconnect(string signalName, T, R, B...)(T sender, R function(B) fn)
+/*
+    template slotCount(string signalName, A...)
     {
-        alias findSymbol!(SignalQualifier, T, signalName) sig;
-        auto sh = sender.signalHandler();
-        sh.disconnect(sig[1], Fn(fn));
+        debug static void slotCount(T)(T sender)
+        {
+            alias findSignal!(T, signalName, Func, A).result sig;
+            auto sh = sender.signalHandler();
+            return sh.slotCount(sig[1]);
+        }
     }
-
-    void disconnect(string signalName, T, R, B...)(T sender, R delegate(B) dg)
-    {
-        alias findSymbol!(SignalQualifier, T, signalName) sig;
-        auto sh = sender.signalHandler();
-        sh.disconnect(sig[1], Dg(dg));
-    }
-
-    debug size_t slotCount(string signalName, T)(T sender)
-    {
-        alias findSymbol!(SignalQualifier, T, signalName) sig;
-        auto sh = sender.signalHandler();
-        return sh.slotCount(sig[1]);
-    }
+    */
 }
 
 /**
     New implementation.
 */
 
-public bool startsWith(T)(T[] source, T[] pattern)
+const string signalPrefix = "__signal";
+
+template TupleWrapper(A...) { alias A at; }
+
+template isDg(Dg)
 {
-    return source.length >= pattern.length && source[0 .. pattern.length] == pattern[];
+    enum { isDg = is(Dg == delegate) }
 }
 
-template TupleWrapper(A...) { alias A at; }
+template isFn(Fn)
+{
+    enum { isFn = is(typeof(*Fn.init) == function) }
+}
+
+template isFnOrDg(Dg)
+{
+    enum { isFnOrDg = isFn!(Dg) || isDg!(Dg) }
+}
 
 string joinArgs(A...)()
 {
@@ -973,20 +981,72 @@
     return res;
 }
 
-struct SignalQualifier
+template SlotPred(T1, T2)
 {
-    const string staticSymbolPrefix = "__signal";
-    const string name = "signal";
-    
-    static bool matches(alias source, string sigName)()
+    enum { SlotPred = is(T1 : T2) }
+}
+
+template CheckSlot(alias Needle, alias Source)
+{
+    static if(Needle.at.length <= Source.at.length)
+        enum { CheckSlot = CheckArgs!(Needle, Source, SlotPred, 0).value }
+    else
+        enum { CheckSlot = false }
+}
+
+template SignalPred(T1, T2)
+{
+    enum { SignalPred = is(T1 == T2) }
+}
+
+template CheckSignal(alias Needle, alias Source)
+{
+    static if(Needle.at.length == Source.at.length)
+        enum { CheckSignal = CheckArgs!(Needle, Source, SignalPred, 0).value }
+    else
+        enum { CheckSignal = false }
+}
+
+template CheckArgs(alias Needle, alias Source, alias pred, int i)
+{
+    static if (i < Needle.at.length)
     {
-        return startsWith(source.at[0], sigName);
+        static if (pred!(Needle.at[i], Source.at[i]))
+            enum { value = CheckArgs!(Needle, Source, pred, i + 1).value }
+        else
+            enum { value = false }
+    }
+    else
+    {
+        enum { value = true }
     }
 }
 
-template staticSymbolName(Qualifier, int id)
+template SigByNamePred(string name, SlotArgs...)
 {
-    const string staticSymbolName = Qualifier.staticSymbolPrefix ~ ToString!(id);
+    template SigByNamePred(source...)
+    {
+        static if (source[0] == name) // only instantiate CheckSlot if names match
+            enum { SigByNamePred = CheckSlot!(TupleWrapper!(SlotArgs), TupleWrapper!(source[2 .. $])) }
+        else
+            enum { SigByNamePred = false }
+    }
+}
+
+template SigBySignPred(string name, SigArgs...)
+{
+    template SigBySignPred(source...)
+    {
+        static if (source[0] == name) // only instantiate CheckSignal if names match
+            enum { SigBySignPred = CheckSignal!(TupleWrapper!(SigArgs), TupleWrapper!(source[2 .. $])) }
+        else
+            enum { SigBySignPred = false }
+    }
+}
+
+template staticSymbolName(string prefix, int id)
+{
+    const string staticSymbolName = prefix ~ ToString!(id);
 }
 
 template signatureString(string name, A...)
@@ -994,26 +1054,45 @@
     const string signatureString = name ~ "(" ~ joinArgs!(A) ~ ")";
 }
 
-template findSymbolImpl(Qualifier, C, int id, string key)
+template findSymbolImpl(string prefix, C, int id, alias pred)
 {
-    static if ( is(typeof(mixin("C." ~ staticSymbolName!(Qualifier, id)))) )
+    static if ( is(typeof(mixin("C." ~ staticSymbolName!(prefix, id)))) )
     {
-        mixin ("alias C." ~ staticSymbolName!(Qualifier, id) ~ " current;");
-        static if ( Qualifier.matches!(TupleWrapper!(current), key)() ) {
+        mixin ("alias C." ~ staticSymbolName!(prefix, id) ~ " current;");
+        static if (pred!(current))
             alias current result;
-        }
         else
-            alias findSymbolImpl!(Qualifier, C, id + 1, key).result result;
+            alias findSymbolImpl!(prefix, C, id + 1, pred).result result;
     }
     else
     {
-        static assert(0, Qualifier.name ~ " " ~ key ~ " not found.");
+        alias void result;
     }
 }
 
-template findSymbol(Qualifier, C, string key)
+template findSymbol(string prefix, C, alias pred)
 {
-    alias findSymbolImpl!(Qualifier, C, 0, key).result findSymbol;
+    alias findSymbolImpl!(prefix, C, 0, pred).result findSymbol;
+}
+
+template findSignal(C, string name, Receiver, SigArgs...)
+{
+    alias TupleWrapper!(ParameterTupleOf!(Receiver)) SlotArgsWr;
+    static if (SigArgs.length > 0)
+    {
+        alias findSymbol!(signalPrefix, C, SigBySignPred!(name, SigArgs)) result;
+        static if (is(result == void))
+            static assert(0, "Signal " ~ name ~ "(" ~ joinArgs!(SigArgs)() ~ ") was not found.");
+        else
+            static if (!CheckSlot!(SlotArgsWr, TupleWrapper!(result[2 .. $])))
+                static assert(0, "Signature of slot is incompatible with signal " ~ name ~ ".");
+    }
+    else
+    {
+        alias findSymbol!(signalPrefix, C, SigByNamePred!(name, SlotArgsWr.at)) result;
+        static if (is(result == void))
+            static assert(0, "Signal " ~ name ~ " was not found.");
+    }
 }
 
 
@@ -1056,7 +1135,7 @@
 
 template SignalImpl(int index, string name, A...)
 {
-    static if (is(typeof(mixin(typeof(this).stringof ~ ".__sig" ~ ToString!(index)))))
+    static if (is(typeof(mixin(typeof(this).stringof ~ ".__signal" ~ ToString!(index)))))
         mixin SignalImpl!(index + 1, name, A);
     else
     {
@@ -1065,8 +1144,7 @@
         {
             mixin SignalHandlerOps;
         }
-        mixin("private static const int __sig" ~ ToString!(index) ~ " = " ~ ToString!(index) ~ ";");
-//        mixin("public alias Tuple!(\"" ~ signatureString!(name, A) ~ "\", index, TupleWrapper!(A)) __signal" ~ ToString!(index) ~ ";");
+        mixin("public alias Tuple!(\"" ~ name ~ "\", index, A) __signal" ~ ToString!(index) ~ ";");
         mixin("SignalOps!(" ~ ToString!(index) ~ ", A) " ~ name ~ "(){ return SignalOps!("
             ~ ToString!(index) ~ ", A)(signalHandler); }");
     }
--- a/qt/d2/qt/Signal.d	Sun Oct 11 05:23:41 2009 +0000
+++ b/qt/d2/qt/Signal.d	Fri Oct 16 02:43:59 2009 +0000
@@ -787,30 +787,6 @@
     private SignalHandler sh;
     enum { signalId = sigId }
 
-    void connect(R, B...)(R function(B) fn, ConnectionFlags flags = ConnectionFlags.None)
-    {
-        alias CheckSlot!(typeof(fn), A) check;
-        auto invoker = Dg(&sh.invokeSlot!(typeof(fn), Fn, A));
-        sh.connect(signalId, Fn(fn), invoker, flags);
-    }
-
-    void connect(R, B...)(R delegate(B) dg, ConnectionFlags flags = ConnectionFlags.None)
-    {
-        alias CheckSlot!(typeof(dg), A) check;
-        auto invoker = Dg(&sh.invokeSlot!(typeof(dg), Dg, A));
-        sh.connect(signalId, Dg(dg), invoker, flags);
-    }
-
-    void disconnect(R, B...)(R function(B) fn)
-    {
-        sh.disconnect(signalId, Fn(fn));
-    }
-
-    void disconnect(R, B...)(R delegate(B) dg)
-    {
-        sh.disconnect(signalId, Dg(dg));
-    }
-
     void emit(A args)
     {
         sh.emit(signalId, args);
@@ -822,25 +798,6 @@
     }
 }
 
-template CheckSlot(Slot, A...)
-{
-    static assert(ParameterTypeTuple!(Slot).length <= A.length, "Slot " ~ ParameterTypeTuple!(Slot).stringof ~
-        " has more prameters than signal " ~ A.stringof);
-    alias CheckSlotImpl!(Slot, 0, A) check;
-}
-
-template CheckSlotImpl(Slot, int i, A...)
-{
-    alias ParameterTypeTuple!(Slot) SlotArgs;
-    static if (i < SlotArgs.length)
-    {
-        static assert (is(SlotArgs[i] : A[i]), "Argument " ~ ToString!(i) ~
-            ":" ~ A[i].stringof ~ " of signal " ~ A.stringof ~ " is not implicitly convertible to parameter "
-            ~ SlotArgs[i].stringof ~ " of slot " ~ SlotArgs.stringof);
-        alias CheckSlotImpl!(Slot, i + 1, A) next;
-    }
-}
-
 public template SignalHandlerOps()
 {
     static assert (is(typeof(this.signalHandler)),
@@ -874,56 +831,71 @@
         signalHandler.unblockSignals();
     }
 
-    void connect(string signalName, this T, R, B...)(R function(B) dg, ConnectionFlags flags = ConnectionFlags.None)
+    template connect(string signalName, A...)
     {
-        alias findSymbol!(SignalQualifier, T, signalName) sig;
-        alias CheckSlot!(typeof(fn), sig[2].at) check;
-        auto sh = signalHandler();
-        auto invoker = Dg(&sh.invokeSlot!(typeof(fn), Fn, sig[2].at));
-        sh.connect(sig[1], Fn(fn), invoker, flags);
+        static void connect(T, Func)(T sender, Func func, ConnectionFlags flags = ConnectionFlags.None)
+            if (isFnOrDg!(Func))
+        {
+            alias findSignal!(T, signalName, Func, A).result sig;
+            auto sh = sender.signalHandler();
+            static if (isFn!(Func))
+                alias Fn Callable;
+            else
+                alias Dg Callable;
+            auto invoker = Dg(&sh.invokeSlot!(typeof(func), Callable, sig[2..$]));
+            sh.connect(sig[1], Callable(func), invoker, flags);
+        }
     }
 
-    void connect(string signalName, this T, R, B...)(R delegate(B) dg, ConnectionFlags flags = ConnectionFlags.None)
+    template disconnect(string signalName, A...)
     {
-        alias findSymbol!(SignalQualifier, T, signalName) sig;
-        alias CheckSlot!(typeof(dg), sig[2].at) check;
-        auto sh = signalHandler();
-        auto invoker = Dg(&sh.invokeSlot!(typeof(dg), Dg, sig[2].at));
-        sh.connect(sig[1], Dg(dg), invoker, flags);
+        static void connect(T, Func)(T sender, Func func, ConnectionFlags flags = ConnectionFlags.None)
+            if (isFnOrDg!(Func))
+        {
+            alias findSignal!(T, signalName, Func, A).result sig;
+            auto sh = sender.signalHandler();
+            static if (isFn!(Func))
+                alias Fn Callable;
+            else
+                alias Dg Callable;
+            sh.disconnect(sig[1], Callable(func));
+        }
     }
-
-    void disconnect(string signalName, this T, R, B...)(R function(B) fn)
+/*
+    template slotCount(string signalName, A...)
     {
-        alias findSymbol!(SignalQualifier, T, signalName) sig;
-        auto sh = signalHandler();
-        sh.disconnect(sig[1], Fn(fn));
+        debug static void slotCount(T)(T sender)
+        {
+            alias findSignal!(T, signalName, Func, A).result sig;
+            auto sh = sender.signalHandler();
+            return sh.slotCount(sig[1]);
+        }
     }
-
-    void disconnect(string signalName, this T, R, B...)(R delegate(B) dg)
-    {
-        alias findSymbol!(SignalQualifier, T, signalName) sig;
-        auto sh = signalHandler();
-        sh.disconnect(sig[1], Dg(dg));
-    }
-
-    debug size_t slotCount(string signalName, this T)()
-    {
-        alias findSymbol!(SignalQualifier, T, signalName) sig;
-        auto sh = signalHandler();
-        return sh.slotCount(sig[1]);
-    }
+    */
 }
 
 /**
     New implementation.
 */
 
-public bool startsWith(T)(T[] source, T[] pattern)
+const string signalPrefix = "__signal";
+
+template TupleWrapper(A...) { alias A at; }
+
+template isDg(Dg)
 {
-    return source.length >= pattern.length && source[0 .. pattern.length] == pattern[];
+    enum isDg = is(Dg == delegate);
 }
 
-template TupleWrapper(A...) { alias A at; }
+template isFn(Fn)
+{
+    enum isFn = is(typeof(*Fn.init) == function);
+}
+
+template isFnOrDg(Dg)
+{
+    enum isFnOrDg = isFn!(Dg) || isDg!(Dg);
+}
 
 string joinArgs(A...)()
 {
@@ -937,20 +909,72 @@
     return res;
 }
 
-struct SignalQualifier
+template SlotPred(T1, T2)
 {
-    const string staticSymbolPrefix = "__signal";
-    const string name = "signal";
-    
-    static bool matches(alias source, string sigName)()
+    enum SlotPred = is(T1 : T2);
+}
+
+template CheckSlot(alias Needle, alias Source)
+{
+    static if(Needle.at.length <= Source.at.length)
+        enum CheckSlot = CheckArgs!(Needle, Source, SlotPred, 0).value;
+    else
+        enum CheckSlot = false;
+}
+
+template SignalPred(T1, T2)
+{
+    enum SignalPred = is(T1 == T2);
+}
+
+template CheckSignal(alias Needle, alias Source)
+{
+    static if(Needle.at.length == Source.at.length)
+        enum CheckSignal = CheckArgs!(Needle, Source, SignalPred, 0).value;
+    else
+        enum CheckSignal = false;
+}
+
+template CheckArgs(alias Needle, alias Source, alias pred, int i)
+{
+    static if (i < Needle.at.length)
     {
-        return startsWith(source.at[0], sigName);
+        static if (pred!(Needle.at[i], Source.at[i]))
+            enum value = CheckArgs!(Needle, Source, pred, i + 1).value;
+        else
+            enum value = false;
+    }
+    else
+    {
+        enum value = true;
     }
 }
 
-template staticSymbolName(Qualifier, int id)
+template SigByNamePred(string name, SlotArgs...)
 {
-    const string staticSymbolName = Qualifier.staticSymbolPrefix ~ ToString!(id);
+    template SigByNamePred(source...)
+    {
+        static if (source[0] == name) // only instantiate CheckSlot if names match
+            enum SigByNamePred = CheckSlot!(TupleWrapper!(SlotArgs), TupleWrapper!(source[2 .. $]));
+        else
+            enum SigByNamePred = false;
+    }
+}
+
+template SigBySignPred(string name, SigArgs...)
+{
+    template SigBySignPred(source...)
+    {
+        static if (source[0] == name) // only instantiate CheckSignal if names match
+            enum SigBySignPred = CheckSignal!(TupleWrapper!(SigArgs), TupleWrapper!(source[2 .. $]));
+        else
+            enum SigBySignPred = false;
+    }
+}
+
+template staticSymbolName(string prefix, int id)
+{
+    const string staticSymbolName = prefix ~ ToString!(id);
 }
 
 template signatureString(string name, A...)
@@ -958,26 +982,45 @@
     const string signatureString = name ~ "(" ~ joinArgs!(A) ~ ")";
 }
 
-template findSymbolImpl(Qualifier, C, int id, string key)
+template findSymbolImpl(string prefix, C, int id, alias pred)
 {
-    static if ( is(typeof(mixin("C." ~ staticSymbolName!(Qualifier, id)))) )
+    static if ( is(typeof(mixin("C." ~ staticSymbolName!(prefix, id)))) )
     {
-        mixin ("alias C." ~ staticSymbolName!(Qualifier, id) ~ " current;");
-        static if ( Qualifier.matches!(TupleWrapper!(current), key)() ) {
+        mixin ("alias C." ~ staticSymbolName!(prefix, id) ~ " current;");
+        static if (pred!current)
             alias current result;
-        }
         else
-            alias findSymbolImpl!(Qualifier, C, id + 1, key).result result;
+            alias findSymbolImpl!(prefix, C, id + 1, pred).result result;
     }
     else
     {
-        static assert(0, Qualifier.name ~ " " ~ key ~ " not found.");
+        alias void result;
     }
 }
 
-template findSymbol(Qualifier, C, string key)
+template findSymbol(string prefix, C, alias pred)
 {
-    alias findSymbolImpl!(Qualifier, C, 0, key).result findSymbol;
+    alias findSymbolImpl!(prefix, C, 0, pred).result findSymbol;
+}
+
+template findSignal(C, string name, Receiver, SigArgs...)
+{
+    alias TupleWrapper!(ParameterTypeTuple!Receiver) SlotArgsWr;
+    static if (SigArgs.length > 0)
+    {
+        alias findSymbol!(signalPrefix, C, SigBySignPred!(name, SigArgs)) result;
+        static if (is(result == void))
+            static assert(0, "Signal " ~ name ~ "(" ~ joinArgs!SigArgs() ~ ") was not found.");
+        else
+            static if (!CheckSlot!(SlotArgsWr, TupleWrapper!(result[2 .. $])))
+                static assert(0, "Signature of slot is incompatible with signal " ~ name ~ ".");
+    }
+    else
+    {
+        alias findSymbol!(signalPrefix, C, SigByNamePred!(name, SlotArgsWr.at)) result;
+        static if (is(result == void))
+            static assert(0, "Signal " ~ name ~ " was not found.");
+    }
 }
 
 /** ---------------- */
@@ -1022,7 +1065,7 @@
 
 template SignalImpl(int index, string name, A...)
 {
-    static if (is(typeof(mixin(typeof(this).stringof ~ ".__sig" ~ ToString!(index)))))
+    static if (is(typeof(mixin(typeof(this).stringof ~ ".__signal" ~ ToString!(index)))))
         mixin SignalImpl!(index + 1, name, A);
     else
     {
@@ -1031,8 +1074,7 @@
         {
             mixin SignalHandlerOps;
         }
-        /* deprecated */ mixin("private static const int __sig" ~ ToString!(index) ~ " = " ~ ToString!(index) ~ ";");
- //       mixin("public alias TypeTuple!(\"" ~ signatureString!(name, A) ~ "\", index, TupleWrapper!(A)) __signal" ~ ToString!(index) ~ ";");
+        mixin("public alias TypeTuple!(\"" ~ name ~ "\", index, A) __signal" ~ ToString!(index) ~ ";");
         mixin("SignalOps!(" ~ ToString!(index) ~ ", A) " ~ name ~ "(){ return SignalOps!("
             ~ ToString!(index) ~ ", A)(signalHandler); }");
     }