Commit d34b384f authored by Jeff Baumes's avatar Jeff Baumes

ENH: Adding Qt classes and tests related to views and databases. These will...

ENH: Adding Qt classes and tests related to views and databases. These will only be compiled if VTK is configured with Qt 4.
parent 7b0e7a89
...@@ -9,6 +9,8 @@ IF(DESIRED_QT_VERSION MATCHES 0) ...@@ -9,6 +9,8 @@ IF(DESIRED_QT_VERSION MATCHES 0)
MESSAGE("Please set the DESIRED_QT_VERSION") MESSAGE("Please set the DESIRED_QT_VERSION")
ELSE(DESIRED_QT_VERSION MATCHES 0) ELSE(DESIRED_QT_VERSION MATCHES 0)
SET ( QT_USE_QTSQL 1 )
INCLUDE( ${CMAKE_ROOT}/Modules/FindQt${DESIRED_QT_VERSION}.cmake ) INCLUDE( ${CMAKE_ROOT}/Modules/FindQt${DESIRED_QT_VERSION}.cmake )
IF(NOT QT_FOUND) IF(NOT QT_FOUND)
...@@ -18,17 +20,42 @@ ELSE(NOT QT_FOUND) ...@@ -18,17 +20,42 @@ ELSE(NOT QT_FOUND)
# set up sources to build # set up sources to build
SET ( QVTKLibSrcs SET ( QVTKLibSrcs
vtkEventQtSlotConnect.cxx vtkEventQtSlotConnect.cxx
QVTKWidget.cxx ) QVTKWidget.cxx
vtkQtAbstractModelAdapter.cxx
vtkQtInitialization.cxx
vtkQtSQLDatabase.cxx
vtkQtSQLQuery.cxx
vtkQtTableModelAdapter.cxx
vtkQtTimePointUtility.cxx
vtkQtTreeModelAdapter.cxx
)
SET ( QVTKMocHeaders SET ( QVTKMocHeaders
QVTKWidget.h QVTKWidget.h
vtkEventQtSlotConnect.h) vtkEventQtSlotConnect.h
vtkQtAbstractModelAdapter.h
vtkQtTableModelAdapter.h
vtkQtTreeModelAdapter.h
)
INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_BINARY_DIR} ) INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_BINARY_DIR} )
IF(DESIRED_QT_VERSION MATCHES 4) IF(DESIRED_QT_VERSION MATCHES 4)
# add additional files depending on infovis and/or views
IF(VTK_USE_VIEWS)
SET( QVTKLibSrcs ${QVTKLibSrcs}
vtkQtItemView.cxx
vtkQtListView.cxx
vtkQtTableView.cxx
vtkQtTreeView.cxx
)
SET ( QVTKMocHeaders ${QVTKMocHeaders}
vtkQtItemView.h
)
ENDIF(VTK_USE_VIEWS)
# help CMake fine QtDesigner on Mac (binary install) # help CMake fine QtDesigner on Mac (binary install)
FIND_PATH(QT_QTDESIGNER_INCLUDE_DIR QDesignerComponents FIND_PATH(QT_QTDESIGNER_INCLUDE_DIR QDesignerComponents
PATHS ${QT_LIBRARY_DIR}/QtDesigner.framework/Headers PATHS ${QT_LIBRARY_DIR}/QtDesigner.framework/Headers
...@@ -85,6 +112,7 @@ ENDIF(DESIRED_QT_VERSION MATCHES 4) ...@@ -85,6 +112,7 @@ ENDIF(DESIRED_QT_VERSION MATCHES 4)
SET_SOURCE_FILES_PROPERTIES(vtkEventQtSlotConnect.cxx PROPERTIES SET_SOURCE_FILES_PROPERTIES(vtkEventQtSlotConnect.cxx PROPERTIES
OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/moc_vtkEventQtSlotConnect.cxx) OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/moc_vtkEventQtSlotConnect.cxx)
ADD_LIBRARY(QVTK ${QVTKLibSrcs} ${QVTKLibMocSrcs}) ADD_LIBRARY(QVTK ${QVTKLibSrcs} ${QVTKLibMocSrcs})
# Apply user-defined properties to the library target. # Apply user-defined properties to the library target.
...@@ -99,7 +127,12 @@ TARGET_LINK_LIBRARIES( QVTK ...@@ -99,7 +127,12 @@ TARGET_LINK_LIBRARIES( QVTK
vtkImaging vtkImaging
vtkCommon) vtkCommon)
# add extra dependencies if necessary
IF(DESIRED_QT_VERSION MATCHES 4)
IF(VTK_USE_VIEWS)
TARGET_LINK_LIBRARIES( QVTK vtkViews )
ENDIF(VTK_USE_VIEWS)
ENDIF(DESIRED_QT_VERSION MATCHES 4)
# build plugin # build plugin
SET(QT_PLUGIN_LIBS ${QT_LIBS}) SET(QT_PLUGIN_LIBS ${QT_LIBS})
...@@ -203,8 +236,14 @@ ENDIF(NOT VTK_INSTALL_NO_LIBRARIES) ...@@ -203,8 +236,14 @@ ENDIF(NOT VTK_INSTALL_NO_LIBRARIES)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.ctest.in" CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.ctest.in"
"${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.ctest" @ONLY IMMEDIATE) "${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.ctest" @ONLY IMMEDIATE)
# recurse into testing directory if testing is on
IF(DESIRED_QT_VERSION MATCHES 4)
IF(BUILD_TESTING)
SUBDIRS(Testing/Cxx)
ENDIF(BUILD_TESTING)
ENDIF(DESIRED_QT_VERSION MATCHES 4)
ENDIF(NOT QT_FOUND) ENDIF(NOT QT_FOUND)
ENDIF(DESIRED_QT_VERSION MATCHES 0) ENDIF(DESIRED_QT_VERSION MATCHES 0)
...@@ -45,15 +45,7 @@ class vtkImageData; ...@@ -45,15 +45,7 @@ class vtkImageData;
#include <Carbon/Carbon.h> // Event handling for dirty region #include <Carbon/Carbon.h> // Event handling for dirty region
#endif #endif
#if defined(WIN32) && defined(VTK_BUILD_SHARED_LIBS) #include "QVTKWin32Header.h"
#if defined(QVTK_EXPORTS) || defined(QVTKWidgetPlugin_EXPORTS)
#define QVTK_EXPORT __declspec( dllexport )
#else
#define QVTK_EXPORT __declspec( dllimport )
#endif
#else
#define QVTK_EXPORT
#endif
//! QVTKWidget displays a VTK window in a Qt window. //! QVTKWidget displays a VTK window in a Qt window.
class QVTK_EXPORT QVTKWidget : public QWidget class QVTK_EXPORT QVTKWidget : public QWidget
......
/*=========================================================================
Program: Visualization Toolkit
Module: QVTKWin32Header.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*----------------------------------------------------------------------------
Copyright (c) Sandia Corporation
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
#ifndef __QVTKWin32Header_h
#define __QVTKWin32Header_h
#include "vtkConfigure.h"
#if defined(WIN32) && defined(VTK_BUILD_SHARED_LIBS)
#if defined(QVTK_EXPORTS) || defined(QVTKWidgetPlugin_EXPORTS)
#define QVTK_EXPORT __declspec( dllexport )
#else
#define QVTK_EXPORT __declspec( dllimport )
#endif
#else
#define QVTK_EXPORT
#endif
#endif /*__QVTKWin32Header_h*/
# if we have rendering add the following tests
SET(KIT QVTK)
# add tests that do not require data
SET(MyTests
TestQtInitialization.cxx
TestQtSQLDatabase.cxx
TestQtTableModelAdapter.cxx
TestQtTreeModelAdapter.cxx
)
IF (VTK_DATA_ROOT)
# add tests that require data
SET(MyTests ${MyTests}
)
ENDIF (VTK_DATA_ROOT)
CREATE_TEST_SOURCELIST(Tests ${KIT}CxxTests.cxx ${MyTests}
EXTRA_INCLUDE vtkTestDriver.h)
ADD_EXECUTABLE(${KIT}CxxTests ${Tests})
TARGET_LINK_LIBRARIES(${KIT}CxxTests QVTK)
SET (TestsToRun ${Tests})
REMOVE (TestsToRun ${KIT}CxxTests.cxx)
#
# Add all the executables
FOREACH (test ${TestsToRun})
GET_FILENAME_COMPONENT(TName ${test} NAME_WE)
IF (VTK_DATA_ROOT)
ADD_TEST(QVTK-${TName} ${CXX_TEST_PATH}/${KIT}CxxTests ${TName}
-D ${VTK_DATA_ROOT}
-T ${VTK_BINARY_DIR}/Testing/Temporary
-V Baseline/${KIT}/${TName}.png)
ELSE (VTK_DATA_ROOT)
ADD_TEST(QVTK-${TName} ${CXX_TEST_PATH}/${KIT}CxxTests ${TName})
ENDIF (VTK_DATA_ROOT)
ENDFOREACH (test)
/*=========================================================================
Program: Visualization Toolkit
Module: TestQtInitialization.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*----------------------------------------------------------------------------
Copyright (c) Sandia Corporation
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
// Tests vtkQtInitialization.
// Thanks to Tim Shead from Sandia National Laboratories for writing this test.
#include "vtkQtInitialization.h"
#include "vtkSmartPointer.h"
#include "vtkTestUtilities.h"
#include <QCoreApplication>
int TestQtInitialization(int , char* [])
{
int error_count = 0;
// Because we share the same process with other tests, verify that
// an instance of QCoreApplication hasn't already been created. This
// ensures that we don't introduce false-positives in case some other test
// has an instance of QCoreApplication floating-around ...
if(QCoreApplication::instance())
{
cerr << "Internal test error ... QCoreApplication already exists" << endl;
++error_count;
}
vtkSmartPointer<vtkQtInitialization> initialization = vtkSmartPointer<vtkQtInitialization>::New();
if(!QCoreApplication::instance())
{
cerr << "QCoreApplication not initialized" << endl;
++error_count;
}
return error_count;
}
/*=========================================================================
Program: Visualization Toolkit
Module: TestQtSQLDatabase.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*----------------------------------------------------------------------------
Copyright (c) Sandia Corporation
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
// Tests vtkQtSQLDatabase.
#include "vtkQtSQLDatabase.h"
#include "vtkSQLQuery.h"
#include "vtkRowQueryToTable.h"
#include "vtkStdString.h"
#include "vtkTable.h"
#include "vtkQtTableModelAdapter.h"
#include "vtkVariant.h"
#include "vtkVariantArray.h"
#include <QApplication>
#include <QFile>
#include <QInputDialog>
#include <QStringList>
#include <QTableView>
int TestQtSQLDatabase(int argc, char* argv[])
{
QApplication app(argc, argv);
//QCoreApplication app(argc, argv);
//for (int i = 0; i < QCoreApplication::libraryPaths().count(); i++)
// {
// cerr << QCoreApplication::libraryPaths().at(i).toStdString() << endl;
// }
bool interactive = false;
// QMYSQL parameters:
//QString dbtype = "QMYSQL";
//QString database = "test";
//QString user = "root";
//bool askpass = true;
//QString host = "localhost";
//int port = 3306;
// QSQLITE parameters:
QString dbtype("QSQLITE");
QString database(":memory:");
QString user;
bool askpass = false;
QString host;
int port = -1;
QString queryText("SELECT name, age, weight FROM people WHERE age <= 20");
for (int i = 1; i < argc; i++)
{
if (!strcmp(argv[i], "-I"))
{
interactive = true;
continue;
}
if (!strcmp(argv[i], "-t"))
{
i++;
dbtype = argv[i];
continue;
}
if (!strcmp(argv[i], "-d"))
{
i++;
database = argv[i];
continue;
}
if (!strcmp(argv[i], "-u"))
{
i++;
user = argv[i];
continue;
}
if (!strcmp(argv[i], "-w"))
{
askpass = true;
continue;
}
if (!strcmp(argv[i], "-h"))
{
i++;
host = argv[i];
continue;
}
if (!strcmp(argv[i], "-p"))
{
i++;
port = atoi(argv[i]);
continue;
}
if (!strcmp(argv[i], "-q"))
{
i++;
queryText = argv[i];
continue;
}
cerr << argv[0] << " Options:\n"
<< " -I (interactive, shows Qt table with query result)\n"
<< " -t database type (QSQLITE, QMYSQL, etc.; default: QSQLITE)\n"
<< " -h host (default: :memory:)\n"
<< " -p port (default: empty)\n"
<< " -d database (default: test)\n"
<< " -u username (default: empty)\n"
<< " -w (password required; default: no password required)\n"
<< " -q (query; default: select * from people ...)\n";
return 0;
}
QString password;
if (askpass)
{
password = QInputDialog::getText(NULL, "Enter password", "Password", QLineEdit::Password);
}
vtkQtSQLDatabase* db = vtkQtSQLDatabase::New();
db->SetDatabaseType(dbtype.toStdString().c_str());
db->SetDatabaseName(database.toStdString().c_str());
db->SetUserName(user.toStdString().c_str());
db->SetPassword(password.toStdString().c_str());
db->SetPort(port);
if (!db->Open())
{
cerr << "Unable to open database" << endl;
return 1;
}
vtkSQLQuery* query = db->GetQueryInstance();
bool dataExists = false;
query->SetQuery("SHOW TABLES");
query->Execute();
if (query->NextRow())
{
dataExists = true; // there is a table
}
if (!dataExists)
{
QString createQuery("CREATE TABLE IF NOT EXISTS people (name TEXT, age INTEGER, weight FLOAT)");
cout << createQuery.toStdString() << endl;
query->SetQuery(createQuery.toStdString().c_str());
if (!query->Execute())
{
cerr << "Create query failed" << endl;
return 1;
}
for (int i = 0; i < 40; i++)
{
QString insertQuery = QString("INSERT INTO people VALUES('John Doe %1', %1, %2)").arg(i).arg(10*i);
cout << insertQuery.toStdString() << endl;
query->SetQuery(insertQuery.toStdString().c_str());
if (!query->Execute())
{
cerr << "Insert query failed" << endl;
return 1;
}
}
}
query->SetQuery(queryText.toStdString().c_str());
cerr << endl << "Running query: " << query->GetQuery() << endl;
cerr << endl << "Using vtkSQLQuery directly to execute query:" << endl;
if (!query->Execute())
{
cerr << "Query failed" << endl;
return 1;
}
for (int col = 0; col < query->GetNumberOfFields(); col++)
{
if (col > 0)
{
cerr << ", ";
}
cerr << query->GetFieldName(col);
}
cerr << endl;
while (query->NextRow())
{
for (int field = 0; field < query->GetNumberOfFields(); field++)
{
if (field > 0)
{
cerr << ", ";
}
cerr << query->DataValue(field).ToString().c_str();
}
cerr << endl;
}
cerr << endl << "Using vtkSQLQuery to execute query and retrieve by row:" << endl;
if (!query->Execute())
{
cerr << "Query failed" << endl;
return 1;
}
for (int col = 0; col < query->GetNumberOfFields(); col++)
{
if (col > 0)
{
cerr << ", ";
}
cerr << query->GetFieldName(col);
}
cerr << endl;
vtkVariantArray* va = vtkVariantArray::New();
while (query->NextRow(va))
{
for (int field = 0; field < va->GetNumberOfValues(); field++)
{
if (field > 0)
{
cerr << ", ";
}
cerr << va->GetValue(field).ToString().c_str();
}
cerr << endl;
}
va->Delete();
cerr << endl << "Using vtkRowQueryToTable to execute query:" << endl;
vtkRowQueryToTable* reader = vtkRowQueryToTable::New();
reader->SetQuery(query);
reader->Update();
vtkTable* table = reader->GetOutput();
for (vtkIdType col = 0; col < table->GetNumberOfColumns(); col++)
{
table->GetColumn(col)->Print(cerr);
}
cerr << endl;
for (vtkIdType row = 0; row < table->GetNumberOfRows(); row++)
{
for (vtkIdType col = 0; col < table->GetNumberOfColumns(); col++)
{
vtkVariant v = table->GetValue(row, col);
cerr << "row " << row << ", col " << col << " - "
<< v.ToString() << " (" << vtkImageScalarTypeNameMacro(v.GetType()) << ")" << endl;
}
}
// Put the table in a view ... just for fun
if (interactive)
{
vtkQtTableModelAdapter* model = new vtkQtTableModelAdapter(table);
QTableView* view = new QTableView();
view->setModel(model);
view->show();
app.exec();
delete view;
delete model;
}
reader->Delete();
query->Delete();
db->Delete();
return 0;
}
/*=========================================================================
Program: Visualization Toolkit
Module: TestQtTableModelAdapter.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*----------------------------------------------------------------------------
Copyright (c) Sandia Corporation
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
// Tests vtkQtTableModelAdapter.
#include "vtkDoubleArray.h"
#include "vtkIntArray.h"
#include "vtkQtTableModelAdapter.h"
#include "vtkSmartPointer.h"
#include "vtkTable.h"
#define VTK_CREATE(type, name) \
vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
int TestQtTableModelAdapter(int, char*[])
{
int numRows = 10;
int errors = 0;
VTK_CREATE(vtkTable, table);
VTK_CREATE(vtkIntArray, intArr);
intArr->SetName("int");
VTK_CREATE(vtkDoubleArray, doubleArr);
doubleArr->SetName("double");
for (int i = 0; i < numRows; ++i)
{
intArr->InsertNextValue(i);
doubleArr->InsertNextValue(-i);
}
table->AddColumn(intArr);
table->AddColumn(doubleArr);
vtkQtTableModelAdapter adapter(table);
if (adapter.rowCount(QModelIndex()) != numRows)
{
cerr << "ERROR: Wrong number of rows." << endl;
++errors;
}
if (adapter.columnCount(QModelIndex()) != 2)
{
cerr << "ERROR: Wrong number of columns." << endl;
++errors;
}
for (int i = 0; i < numRows; ++i)
{
QModelIndex ind = adapter.index(i, 0);
QModelIndex pind = adapter.PedigreeToQModelIndex(i);
if (ind != pind)
{
cerr << "ERROR: Pedigree lookup failed." << endl;
++errors;
}
if (adapter.rowCount(ind) != 0)
{
cerr << "ERROR: Row should have zero sub-rows." << endl;
++errors;
}
if (adapter.parent(ind) != QModelIndex())
{
cerr << "ERROR: Wrong parent." << endl;
++errors;
}
}
return errors;
}
/*=========================================================================
Program: Visualization Toolkit
Module: TestQtTreeModelAdapter.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*----------------------------------------------------------------------------
Copyright (c) Sandia Corporation
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
// Tests vtkQtTreeModelAdapter.
#include "vtkDataSetAttributes.h"
#include "vtkDoubleArray.h"
#include "vtkIntArray.h"
#include "vtkMutableDirectedGraph.h"
#include "vtkQtTreeModelAdapter.h"
#include "vtkSmartPointer.h"
#include "vtkTree.h"
#define VTK_CREATE(type, name) \
vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
int TestQtTreeModelAdapter(int, char*[])
{
int numVerts = 6;
int errors = 0;
VTK_CREATE(vtkMutableDirectedGraph, builder);
builder->AddVertex(); // 0
builder->AddChild(0); // 1
builder->AddChild(0); // 2
builder->AddChild(0); // 3
builder->AddChild(1); // 4
builder->AddChild(1); // 5
VTK_CREATE(vtkTree, tree);
tree->ShallowCopy(builder);
VTK_CREATE(vtkIntArray, intArr);
intArr->SetName("int");
VTK_CREATE(vtkDoubleArray, doubleArr);
doubleArr->SetName("double");
for (int i = 0; i < numVerts; ++i)
{
intArr->InsertNextValue(i);
doubleArr->InsertNextValue(-i);
}
tree->GetVertexData()->AddArray(intArr);
tree->GetVertexData()->AddArray(doubleArr);
vtkQtTreeModelAdapter adapter(0, tree);
if (adapter.rowCount(QModelIndex()) != 1)
{
cerr << "ERROR: Wrong number of rows." << endl;
++errors;
}
if (adapter.columnCount(QModelIndex()) != 2)
{
cerr << "ERROR: Wrong number of columns." << endl;
++errors;
}
QModelIndex ind0 = adapter.index(0, 0);
QModelIndex ind1 = adapter.index(0, 0, ind0);
for (int i = 0; i < numVerts; ++i)
{
QModelIndex ind;
QModelIndex parent;
int rows;
if (i == 0)
{
ind = ind0;
parent = QModelIndex();
rows = 3;
}
else if (i == 1)
{
ind = ind1;
parent = ind0;
rows = 2;
}
else if (i < 4)
{
ind = adapter.index(i-1, 0, ind0);
parent = ind0;
rows = 0;
}
else
{
ind = adapter.index(i-4, 0, ind1);
parent = ind1;
rows = 0;
}
QModelIndex pind = adapter.PedigreeToQModelIndex(i);
if (ind != pind)