tools/activeqt/testcon/mainwindow.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/activeqt/testcon/mainwindow.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,461 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "changeproperties.h"
+#include "invokemethod.h"
+#include "ambientproperties.h"
+#include "controlinfo.h"
+#include "docuwindow.h"
+
+#include <QtGui>
+#include <qt_windows.h>
+#include <ActiveQt/ActiveQt>
+
+QT_BEGIN_NAMESPACE
+
+QAxObject *ax_mainWindow = 0;
+
+static QTextEdit *debuglog = 0;
+
+static void redirectDebugOutput(QtMsgType type, const char*msg)
+{
+    Q_UNUSED(type);
+    debuglog->append(QLatin1String(msg));
+}
+
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+MainWindow::MainWindow(QWidget *parent)
+    : QMainWindow(parent)
+{
+    setupUi(this);
+    setObjectName(QLatin1String("MainWindow"));
+
+    QAxScriptManager::registerEngine(QLatin1String("PerlScript"), QLatin1String(".pl"));
+    QAxScriptManager::registerEngine(QLatin1String("Python"), QLatin1String(".py"));
+
+    dlgInvoke = 0;
+    dlgProperties = 0;
+    dlgAmbient = 0;
+    scripts = 0;
+    debuglog = logDebug;
+    oldDebugHandler = qInstallMsgHandler(redirectDebugOutput);
+    QHBoxLayout *layout = new QHBoxLayout(Workbase);
+    workspace = new QWorkspace(Workbase);
+    layout->addWidget(workspace);
+    layout->setMargin(0);
+
+    connect(workspace, SIGNAL(windowActivated(QWidget*)), this, SLOT(updateGUI()));
+    connect(actionFileExit, SIGNAL(triggered()), qApp, SLOT(quit()));
+}
+
+MainWindow::~MainWindow()
+{
+    qInstallMsgHandler(oldDebugHandler);
+    debuglog = 0;
+}
+
+
+void MainWindow::on_actionFileNew_triggered()
+{
+    QAxSelect select(this);
+    if (select.exec()) {
+        QAxWidget *container = new QAxWidget(workspace);
+        container->setAttribute(Qt::WA_DeleteOnClose);
+        container->setControl(select.clsid());
+	container->setObjectName(container->windowTitle());
+        workspace->addWindow(container);
+        container->show();
+    }
+    updateGUI();
+}
+
+void MainWindow::on_actionFileLoad_triggered()
+{
+    QString fname = QFileDialog::getOpenFileName(this, tr("Load"), QString(), QLatin1String("*.qax"));
+    if (fname.isEmpty())
+	return;
+
+    QFile file(fname);
+    if (!file.open(QIODevice::ReadOnly)) {
+	QMessageBox::information(this, tr("Error Loading File"), tr("The file could not be opened for reading.\n%1").arg(fname));
+	return;
+    }
+
+    QAxWidget *container = new QAxWidget(workspace);
+    workspace->addWindow(container);
+    
+    QDataStream d(&file);
+    d >> *container;
+
+    container->setObjectName(container->windowTitle());
+    container->show();
+
+    updateGUI();
+}
+
+void MainWindow::on_actionFileSave_triggered()
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+        return;
+
+    QString fname = QFileDialog::getSaveFileName(this, tr("Save"), QString(), QLatin1String("*.qax"));
+    if (fname.isEmpty())
+	return;
+
+    QFile file(fname);
+    if (!file.open(QIODevice::WriteOnly)) {
+	QMessageBox::information(this, tr("Error Saving File"), tr("The file could not be opened for writing.\n%1").arg(fname));
+	return;
+    }
+    QDataStream d(&file);
+    d << *container;
+}
+
+
+void MainWindow::on_actionContainerSet_triggered()
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+        return;
+
+    QAxSelect select(this);
+    if (select.exec())
+	container->setControl(select.clsid());
+    updateGUI();
+}
+
+void MainWindow::on_actionContainerClear_triggered()
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (container)
+	container->clear();
+    updateGUI();
+}
+
+void MainWindow::on_actionContainerProperties_triggered()
+{
+    if (!dlgAmbient) {
+	dlgAmbient = new AmbientProperties(this);
+	dlgAmbient->setControl(workspace);
+    }
+    dlgAmbient->show();
+}
+
+
+void MainWindow::on_actionControlInfo_triggered()
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+        return;
+
+    ControlInfo info(this);
+    info.setControl(container);
+    info.exec();
+}
+
+void MainWindow::on_actionControlProperties_triggered()
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+        return;
+
+    if (!dlgProperties) {
+	dlgProperties = new ChangeProperties(this);
+	connect(container, SIGNAL(propertyChanged(const QString&)), dlgProperties, SLOT(updateProperties()));
+    }
+    dlgProperties->setControl(container);
+    dlgProperties->show();
+}
+
+void MainWindow::on_actionControlMethods_triggered()
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+        return;
+
+    if (!dlgInvoke)
+	dlgInvoke = new InvokeMethod(this);
+    dlgInvoke->setControl(container);
+    dlgInvoke->show();
+}
+
+void MainWindow::on_VerbMenu_aboutToShow()
+{
+    VerbMenu->clear();
+
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+        return;
+
+    QStringList verbs = container->verbs();
+    for (int i = 0; i < verbs.count(); ++i) {
+        VerbMenu->addAction(verbs.at(i));
+    }
+
+    if (!verbs.count()) { // no verbs?
+        VerbMenu->addAction(tr("-- Object does not support any verbs --"))->setEnabled(false);
+    }
+}
+
+void MainWindow::on_VerbMenu_triggered(QAction *action)
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+        return;
+
+    container->doVerb(action->text());
+}
+
+void MainWindow::on_actionControlDocumentation_triggered()
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+        return;
+    
+    QString docu = container->generateDocumentation();
+    if (docu.isEmpty())
+	return;
+
+    DocuWindow *docwindow = new DocuWindow(docu, workspace, container);
+    workspace->addWindow(docwindow);
+    docwindow->show();
+}
+
+
+void MainWindow::on_actionControlPixmap_triggered()
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+	return;
+
+    QPixmap pm = QPixmap::grabWidget(container);
+
+    QLabel *label = new QLabel(workspace);
+    label->setAttribute(Qt::WA_DeleteOnClose);
+    label->setPixmap(pm);
+    label->setWindowTitle(tr("%1 - Pixmap").arg(container->windowTitle()));
+
+    workspace->addWindow(label);
+    label->show();
+}
+
+void MainWindow::on_actionScriptingRun_triggered()
+{
+#ifndef QT_NO_QAXSCRIPT
+    if (!scripts)
+	return;
+
+    // If we have only one script loaded we can use the cool dialog
+    QStringList scriptList = scripts->scriptNames();
+    if (scriptList.count() == 1) {
+	InvokeMethod scriptInvoke(this);
+	scriptInvoke.setWindowTitle(tr("Execute Script Function"));
+	scriptInvoke.setControl(scripts->script(scriptList[0])->scriptEngine());
+	scriptInvoke.exec();
+	return;
+    }
+
+    bool ok = false;
+    QStringList macroList = scripts->functions(QAxScript::FunctionNames);
+    QString macro = QInputDialog::getItem(this, tr("Select Macro"), tr("Macro:"), macroList, 0, true, &ok);
+
+    if (!ok)
+	return;
+
+    QVariant result = scripts->call(macro);
+    if (result.isValid())
+	logMacros->append(tr("Return value of %1: %2").arg(macro).arg(result.toString()));
+#endif
+}
+
+void MainWindow::on_actionScriptingLoad_triggered()
+{
+#ifndef QT_NO_QAXSCRIPT
+    QString file = QFileDialog::getOpenFileName(this, tr("Open Script"), QString(), QAxScriptManager::scriptFileFilter());
+
+    if (file.isEmpty())
+	return;
+
+    if (!scripts) {
+	scripts = new QAxScriptManager(this);
+	scripts->addObject(this);
+    }
+
+    QWidgetList widgets = workspace->windowList();
+    QWidgetList::Iterator it(widgets.begin());
+    while (it != widgets.end()) {
+	QAxBase *ax = (QAxBase*)(*it)->qt_metacast("QAxBase");
+	++it;
+	if (!ax)
+	    continue;
+	scripts->addObject(ax);
+    }
+
+    QAxScript *script = scripts->load(file, file);
+    if (script) {
+	connect(script, SIGNAL(error(int, const QString&, int, const QString&)),
+		this,   SLOT(logMacro(int,  const QString&, int, const QString&)));
+	actionScriptingRun->setEnabled(true);
+    }
+#else
+    QMessageBox::information(this, tr("Function not available"),
+	tr("QAxScript functionality is not available with this compiler."));
+#endif
+}
+
+void MainWindow::updateGUI()
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+
+    bool hasControl = container && !container->isNull();
+    actionFileNew->setEnabled(true);
+    actionFileLoad->setEnabled(true);
+    actionFileSave->setEnabled(hasControl);
+    actionContainerSet->setEnabled(container != 0);
+    actionContainerClear->setEnabled(hasControl);
+    actionControlProperties->setEnabled(hasControl);
+    actionControlMethods->setEnabled(hasControl);
+    actionControlInfo->setEnabled(hasControl);
+    actionControlDocumentation->setEnabled(hasControl);
+    actionControlPixmap->setEnabled(hasControl);
+    VerbMenu->setEnabled(hasControl);
+    if (dlgInvoke)
+	dlgInvoke->setControl(hasControl ? container : 0);
+    if (dlgProperties)
+	dlgProperties->setControl(hasControl ? container : 0);
+
+    QWidgetList list = workspace->windowList();
+    QWidgetList::Iterator it = list.begin();
+    while (it != list.end()) {
+	QWidget *container = *it;
+
+	QAxWidget *ax = qobject_cast<QAxWidget*>(container);
+	if (ax) {
+	    container->disconnect(SIGNAL(signal(const QString&, int, void*)));
+	    if (actionLogSignals->isChecked())
+		connect(container, SIGNAL(signal(const QString&, int, void*)), this, SLOT(logSignal(const QString&, int, void*)));
+
+	    container->disconnect(SIGNAL(exception(int,const QString&,const QString&,const QString&)));
+	    connect(container, SIGNAL(exception(int,const QString&,const QString&,const QString&)),
+		this, SLOT(logException(int,const QString&,const QString&,const QString&)));
+
+	    container->disconnect(SIGNAL(propertyChanged(const QString&)));
+	    if (actionLogProperties->isChecked()) 
+		connect(container, SIGNAL(propertyChanged(const QString&)), this, SLOT(logPropertyChanged(const QString&)));
+	    container->blockSignals(actionFreezeEvents->isChecked());
+	}
+
+	++it;
+    }
+}
+
+
+void MainWindow::logPropertyChanged(const QString &prop)
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+        return;
+
+    QVariant var = container->property(prop.toLatin1());
+    logProperties->append(tr("%1: Property Change: %2 - { %3 }").arg(container->windowTitle(), prop, var.toString()));
+}
+
+void MainWindow::logSignal(const QString &signal, int argc, void *argv)
+{
+    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
+    if (!container)
+        return;
+
+    QString paramlist;
+    VARIANT *params = (VARIANT*)argv;
+    for (int a = argc-1; a >= 0; --a) {
+	if (a == argc-1)
+	    paramlist = QLatin1String(" - {");
+	QVariant qvar = VARIANTToQVariant(params[a], 0);
+	paramlist += QLatin1String(" ") + qvar.toString();
+	if (a > 0)
+	    paramlist += QLatin1String(",");
+	else
+	    paramlist += QLatin1String(" ");
+    }
+    if (argc)
+	paramlist += QLatin1String("}");
+    logSignals->append(container->windowTitle() + QLatin1String(": ") + signal + paramlist);
+}
+
+void MainWindow::logException(int code, const QString&source, const QString&desc, const QString&help)
+{
+    Q_UNUSED(desc);
+    QAxWidget *container = qobject_cast<QAxWidget*>(sender());
+    if (!container)
+        return;
+
+    QString str = tr("%1: Exception code %2 thrown by %3").
+	arg(container->windowTitle()).arg(code).arg(source);
+    logDebug->append(str);
+    logDebug->append(tr("\tDescription: %1").arg(desc));
+
+    if (!help.isEmpty())
+	logDebug->append(tr("\tHelp available at %1").arg(help));
+    else
+	logDebug->append(tr("\tNo help available."));
+}
+
+void MainWindow::logMacro(int code, const QString &description, int sourcePosition, const QString &sourceText)
+{
+    /* FIXME This needs to be rewritten to not use string concatentation, such
+     * that it can be translated in a sane way. */
+    QString message = tr("Script: ");
+    if (code)
+	message += QString::number(code) + QLatin1String(" ");
+    message += QLatin1String("'") + description + QLatin1String("'");
+    if (sourcePosition)
+	message += tr(" at position ") + QString::number(sourcePosition);
+    if (!sourceText.isEmpty())
+	message += QLatin1String(" '") + sourceText + QLatin1String("'");
+
+    logMacros->append(message);
+}